@aotter/mantle 0.2.0-alpha.7 → 0.2.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +10 -5
  2. package/dist/auth/caller.js +2 -1
  3. package/dist/auth/identity.d.ts +2 -2
  4. package/dist/auth/oauth.d.ts +33 -1
  5. package/dist/auth/oauth.js +121 -28
  6. package/dist/auth/routes.js +3 -2
  7. package/dist/build/compiler.d.ts +44 -122
  8. package/dist/build/compiler.js +202 -277
  9. package/dist/build/spec/domain/model/ManifestGrammar.d.ts +6 -5
  10. package/dist/build/spec/domain/model/SqlIr.d.ts +2 -0
  11. package/dist/build/spec/domain/service/PlanFingerprint.d.ts +2 -0
  12. package/dist/build/spec/kernel/diagnostic.d.ts +1 -1
  13. package/dist/domain/describe/{chunk-ZIQVLA7X.js → chunk-ZVXBGP7Y.js} +69 -8
  14. package/dist/domain/describe/index.js +1 -1
  15. package/dist/domain/describe/target-hash.js +1 -1
  16. package/dist/domain/describe/targets.d.ts +1 -1
  17. package/dist/domain/generated-tools.js +2 -0
  18. package/dist/domain/paging.js +41 -15
  19. package/dist/infrastructure/bundle.js +105 -15
  20. package/dist/infrastructure/cli.js +11 -15
  21. package/dist/infrastructure/generate.d.ts +1 -3
  22. package/dist/infrastructure/generate.js +2 -2
  23. package/dist/infrastructure/generateAuth.js +6 -0
  24. package/dist/infrastructure/inputs.js +8 -3
  25. package/dist/infrastructure/wrangler.js +35 -12
  26. package/dist/kernel/drain.d.ts +5 -0
  27. package/dist/kernel/drain.js +35 -0
  28. package/dist/kernel/driver/postgres.js +3 -0
  29. package/dist/kernel/host-caller.d.ts +1 -0
  30. package/dist/kernel/host-caller.js +1 -0
  31. package/dist/kernel/mcp-apps.d.ts +29 -9
  32. package/dist/kernel/mcp-apps.js +2 -2
  33. package/dist/kernel/mcp-handler.js +100 -17
  34. package/dist/kernel/mcp.d.ts +7 -2
  35. package/dist/kernel/mcp.js +29 -5
  36. package/dist/kernel/rest-router.js +3 -2
  37. package/dist/kernel/site.d.ts +1 -3
  38. package/dist/kernel/site.js +2 -2
  39. package/dist/kernel/web.d.ts +3 -1
  40. package/dist/kernel/web.js +3 -0
  41. package/dist/usecase/adminBindings.js +2 -3
  42. package/dist/usecase/adminClient.js +87 -0
  43. package/dist/usecase/adminDescriptors.js +19 -65
  44. package/dist/usecase/generate.js +5 -4
  45. package/dist/usecase/mcp-media.js +2 -2
  46. package/dist/usecase/mcp.js +16 -12
  47. package/dist/usecase/paging.js +2 -3
  48. package/dist/usecase/publishing.js +2 -2
  49. package/dist/usecase/tool-version.js +9 -0
  50. package/dist/usecase/translations.js +1 -1
  51. package/dist/usecase/validation.js +120 -19
  52. package/dist/usecase/web.js +3 -2
  53. package/docs/examples/README.md +1 -1
  54. package/docs/examples/app-shell/README.md +39 -1
  55. package/docs/examples/app-shell/package.json +14 -6
  56. package/docs/examples/app-shell/smoke-kit.mjs +54 -0
  57. package/docs/examples/app-shell/src/auth.ts +4 -2
  58. package/docs/examples/app-shell/src/service.ts +2 -2
  59. package/docs/examples/app-shell/tsconfig.json +4 -1
  60. package/docs/examples/app-shell/worker-configuration.d.ts +2 -2
  61. package/docs/examples/app-shell/wrangler.jsonc +5 -4
  62. package/docs/examples/generated-web/README.md +6 -2
  63. package/docs/examples/generated-web/wrangler.jsonc +1 -0
  64. package/docs/examples/purchasing/README.md +1 -1
  65. package/docs/examples/purchasing/manifests/purchasing.yaml +1 -1
  66. package/docs/examples/purchasing/smoke.mjs +10 -4
  67. package/docs/examples/purchasing/src/admin.tsx +13 -0
  68. package/docs/examples/purchasing/wrangler.jsonc +5 -4
  69. package/docs/examples/recipes/wrangler.jsonc +5 -4
  70. package/docs/handbook/cloudflare/authentication.md +22 -2
  71. package/docs/handbook/cloudflare/deploy-and-operate.md +21 -0
  72. package/docs/handbook/cloudflare/service-entry.md +55 -28
  73. package/docs/handbook/concepts/authorization.md +1 -1
  74. package/docs/handbook/concepts/mcp-and-agents.md +19 -0
  75. package/docs/handbook/examples/hub.md +1 -1
  76. package/docs/handbook/guides/admin-ui.md +107 -1
  77. package/docs/handbook/guides/agent-setup.md +27 -9
  78. package/docs/handbook/guides/mcp-apps.md +445 -6
  79. package/docs/handbook/guides/native-admin.md +296 -51
  80. package/docs/handbook/guides/oauth.md +61 -5
  81. package/docs/handbook/guides/public-pages.md +2 -2
  82. package/docs/handbook/guides/size-and-startup.md +1 -1
  83. package/docs/handbook/navigation.json +0 -4
  84. package/docs/handbook/reference/admin-descriptors.md +0 -35
  85. package/docs/handbook/reference/procedure.md +5 -1
  86. package/docs/handbook/reference/schema.md +13 -3
  87. package/docs/handbook/reference/surface.md +123 -13
  88. package/docs/handbook/reference/trigger.md +34 -1
  89. package/docs/handbook/reference/view.md +1 -1
  90. package/docs/handbook/releases/index.md +74 -2
  91. package/docs/handbook/start/overview.md +1 -1
  92. package/docs/handbook/start/project-and-cli.md +8 -8
  93. package/docs/handbook/start/quickstart-worker.md +1 -1
  94. package/docs/skills/develop/SKILL.md +4 -3
  95. package/docs/skills/integrate/SKILL.md +1 -1
  96. package/docs/skills/media-gc/SKILL.md +7 -5
  97. package/docs/skills/provision/SKILL.md +4 -1
  98. package/docs/skills/update/SKILL.md +1 -1
  99. package/docs/upgrade-0.1-to-0.2.md +6 -6
  100. package/package.json +2 -1
  101. package/skills/README.md +11 -16
  102. package/skills/mantle/SKILL.md +4 -4
  103. package/skills/mantle/references/local-testing.md +4 -0
  104. package/skills/mantle/references/web.md +1 -1
  105. package/skills/mantle/references/website.md +24 -22
  106. package/docs/examples/app-shell/src/admin.ts +0 -10
  107. package/docs/examples/purchasing/src/admin.ts +0 -12
  108. package/docs/handbook/guides/admin-extensions.md +0 -20
package/skills/README.md CHANGED
@@ -21,25 +21,20 @@ distributions (ADR-0032 decision 13):
21
21
 
22
22
  ## Install
23
23
 
24
- ```bash
25
- # Claude Code: two separate prompts
26
- /plugin marketplace add aotter/mantle
27
- /plugin install mantle@mantle
24
+ Use the [agent setup guide](../docs/handbook/guides/agent-setup.md) for Codex,
25
+ Claude Code, Cursor and GitHub Copilot. Pin the plugin checkout to the same
26
+ release tag as the application's SDK; alpha releases on `develop` can be newer
27
+ than the default `main` branch. For a skill-only installation:
28
28
 
29
- # Codex
30
- codex plugin marketplace add aotter/mantle
31
- codex plugin add mantle@mantle
29
+ ```sh
30
+ npx skills add https://github.com/aotter/mantle/tree/v0.2.0-alpha.8 --skill mantle
32
31
  ```
33
32
 
34
- Cursor and GitHub Copilot read the manifests from the repository
35
- (`.cursor-plugin/plugin.json`, `.copilot-plugin/plugin.json`). Without a
36
- plugin host, `npx skills add aotter/mantle` installs the `mantle` skill and its
37
- references. The manifests are generated by
38
- `scripts/sync-plugin-manifests.mjs` and checked with `--check`.
39
-
40
- Claude Code updates an installed plugin only when its manifest version
41
- changes, and that version is Core's, so a skill or script update reaches
42
- Claude Code users with the next Core release.
33
+ The explicit skill name excludes repository maintainer skills. The manifests
34
+ are generated by `scripts/sync-plugin-manifests.mjs` and checked with `--check`.
35
+ When upgrading, update the marketplace ref or local tagged checkout and refresh
36
+ the plugin. Verify the loaded manifest version; Claude Code's plugin version
37
+ is Core's, so packaged skill changes reach users through the next Core release.
43
38
 
44
39
  ## Disclosure audit
45
40
 
@@ -21,7 +21,7 @@ checkout, or any online copy.
21
21
 
22
22
  Work in the user's application, outside the SDK checkout. Read package.json, the lockfile, installed SDK README and node_modules/@aotter/mantle/docs/. Those files define the exact version's contract. Preserve existing identity, handles, routes and resources.
23
23
 
24
- For a new project, install an exact published SDK version with matching selected Admin/UI packages. Node must be 22.22 or newer. Add TypeScript and target types; Workers also need Wrangler. Optional auth/MCP peers use the installed SDK's package.json versions. Read the installed handbook's start/project-and-cli.md before choosing a target.
24
+ For a new project, install an exact published SDK version with matching selected Admin/UI packages. Node must be 22.22 or newer. Add TypeScript and target types; Workers also need Wrangler. `node_modules/@aotter/mantle/docs/examples/app-shell/package.json` lists the Wrangler, TypeScript and type-package versions this release is tested with. Optional auth/MCP peers use the installed SDK's package.json versions. Read the installed handbook's start/project-and-cli.md before choosing a target.
25
25
 
26
26
  For a new Cloudflare app, copy `node_modules/@aotter/mantle/docs/examples/app-shell/` first, then the closest example from `docs/examples/README.md` on top of it, and edit from there: manifests, `src/handlers.ts`, `src/routes.ts`, `src/schedule.ts`, `smoke.mjs`. Search for `AGENT:` to find what the app must fill in; the example pages are unstyled on purpose, so styling them is part of that work. Before reporting done, resolve each `AGENT:` or name the ones you left. Keep the two roles `admin` and `user` unless the user asks for more.
27
27
 
@@ -89,7 +89,7 @@ Procedure fragments and generated checks. Ref operations retain typed `ctx.store
89
89
  at request time. Verify member/frontend and admin/Admin OTP, tenant/privacy/TTL,
90
90
  publishing, paging, statistics, exact OCC, ref effects and the actual console;
91
91
  never retry unknown 503 writes automatically. Read the installed Admin README
92
- for extensions, raw-body limits, CSP/assets, 22 languages and the developer workspace.
92
+ for raw-body limits, CSP/assets, 22 languages and the developer workspace.
93
93
  Use only versions actually published, or the explicitly linked workspace packages.
94
94
 
95
95
  For generated native applications, optional site settings/media are selected
@@ -107,7 +107,7 @@ without asking the user to enumerate OTP, media, Admin or SEO. Defaults are
107
107
  acceptance requirements, not evidence that a missing renderer is implemented.
108
108
  Do not report a complete website with blocked required checks.
109
109
 
110
- Run the [local HTTP acceptance](references/local-testing.md) for handlers and websites; compilation does not execute their behavior.
110
+ Run the [local HTTP acceptance](references/local-testing.md) for handlers and selected interfaces; compilation does not execute their behavior. Account for every declared interface as verified, intentionally not exposed, or deferred/unverified with a reason in the existing application handoff. An early preview may defer remote MCP; preserve that pending work. WebMCP, cookie-session discovery and OAuth Bearer/client integration are separate checks.
111
111
 
112
112
  ## Self-hosted deployment
113
113
 
@@ -120,7 +120,7 @@ workflow. Local project creation alone is not deployment authorization.
120
120
  Preserve the user's manifests, `src/` files, identity, package versions and
121
121
  provider resources. The app writes its entry (`src/worker.ts` by default;
122
122
  `--entry` selects another). Workers generation creates or updates Wrangler's
123
- split-build settings. Run the same generation command (target, output directory,
123
+ split-build settings and public-fetch compatibility flags. Run the same generation command (target, output directory,
124
124
  manifests and options) with `--check`, and the project's own tests,
125
125
  before and after a change.
126
126
 
@@ -7,5 +7,9 @@ Better Auth limits each email-OTP path to 3 requests/minute per IP; `authHardeni
7
7
 
8
8
  - Exercise actual HTTP Triggers for every custom Procedure handler: valid input/output, invalid input, anonymous refusal on protected operations, authorized synthetic caller and expected stored result. A status below 500 alone is not success; assert the expected status and JSON envelope/body. Use only the generated contract's routes, inputs and permissions.
9
9
  - For an app-owned `fetch`, exercise its real public routes, not just dist files. Assert HTML content type, visible content and metadata/canonical/JSON-LD with no JavaScript execution, sitemap, robots and an unknown URL returning 404. Create a local synthetic draft and assert it is hidden anonymously; publish, edit and delete it through authorized operations and check the page and sitemap after each change. Reuse the application's existing smoke-test pattern and clean up test rows/server in `finally`.
10
+ - If the app serves Admin, run `npm run build` and then `node --test generated/admin-mcp-app.check.mjs` (the examples name it `npm test`): the generated `generated/admin-mcp-app.check.mjs` loads the Admin MCP App in an MCP host and fails on a network request, console error or exception. It needs `playwright-core` (a devDependency) and Chrome (`npx playwright-core install chromium` or `MANTLE_TEST_CHROMIUM`); with no browser it fails, so report it as blocked rather than skipped. See `docs/handbook/guides/mcp-apps.md`.
10
11
  - Keep caller authority explicit: use supplied `resolveCaller` and caller-scoped Store/Procedure APIs from the installed service-entry docs. Use the actual local host capabilities; local tests do not prove remote identity/provider wiring.
12
+ - Account for each declared interface separately: verified with the command/identity/result, intentionally not exposed, or deferred/unverified with a reason. Generation proves declaration and artifacts, not route mounting. An early Admin preview or a WebMCP-only application may defer remote MCP; preserve that pending item in the application's existing README, handoff or test report, without a new status/configuration format.
13
+ - For selected remote MCP, use the installed `docs/examples/app-shell/smoke-kit.mjs` `assertMcpDiscovery(endpoint, { tools, headers })` in the application's smoke scenario. Derive `tools` from the generated `mcp.ts` exports, or the pure static `developerConsole.interfaces.callable` in generated `admin-descriptors.ts`; filter to the selected surface and explicitly select the expected permitted subset when application authorization narrows it. Include app-composed tools when present. Do not count `describe.targets` or reconstruct authorization rules in the harness. Assert initialized discovery and all `tools/list` pages; a 404, HTML 200, protocol error or missing expected tools must fail. Keep anonymous/member denial assertions separate. Discovery never needs a business-write `tools/call`.
14
+ - Supply test credentials from the application's normal authorized sign-in/test setup (the smoke kit's console OTP sign-in is valid). The discovery assertion only receives credentials: it must not acquire credentials itself, scrape other sessions or manufacture authority. Report local cookie-session discovery, OAuth Bearer/client integration and browser WebMCP as separate evidence. Cookie or WebMCP success does not prove remote OAuth/ChatGPT wiring; missing credentials leave that case unverified, not passed. Do not enable remote routes or OAuth merely to make acceptance pass.
11
15
  - Record commands and passed/failed/blocked cases for the exact commit. Fix failures before source admission; rerun relevant checks after changing source. Packing does not run these checks and an agent's checklist is not server build attestation.
@@ -3,7 +3,7 @@
3
3
  Use this flow only when the installed package README documents concrete native
4
4
  queries and generated `web.ts`.
5
5
  Earlier Core versions use their own installed handbook. Read the installed
6
- `docs/handbook/reference/surface.md` and `docs/examples/generated-web/README.md` before writing
6
+ `docs/handbook/reference/surface.md` and `docs/examples/generated-web/README.md` under `node_modules/@aotter/mantle/` before writing
7
7
  routes; the installed version is authoritative.
8
8
 
9
9
  Mount `web()` when the application serves public HTML and needs `llms.txt`, a
@@ -7,19 +7,21 @@ selected host's frontend kit before choosing APIs. Native applications use
7
7
  their installed `docs/handbook/guides/native-admin.md` and the
8
8
  [web contract](web.md).
9
9
 
10
- - Link to host-provided Mantle Admin UI and configured tenant OTP; do not emit frontend assets under host-owned /admin routes. Add visitor sign-in only where
11
- needed. Do not build a second identity store or configure another mail provider
12
- when the host already supplies one. Backend permissions enforce roles and data
13
- access; Host membership is not application admin access.
10
+ - For self-hosted applications, mount the selected Admin API and serve the
11
+ separate Admin package's assets with its shell/CSP contract. The application
12
+ owns auth, OTP delivery and verified Caller wiring; use a console/test sender
13
+ locally and configure production email for deployment. If a host already
14
+ supplies identity/Admin, reuse its explicit contract and reserved routes.
15
+ Add visitor sign-in where needed. Backend permissions enforce roles and data
16
+ access; host membership alone is not application admin authority.
14
17
  - Integrate image selection/upload into content editing through the existing
15
- Admin media library and host storage. Follow the pinned Core upload/PUT/commit
16
- contract and `x-mantle-ref: media_assets` plus `x-mcp-hint: media-image`; store committed asset IDs, resolve permanent variants in the frontend, never use an ID as an image URL. Tenant `/mcp/admin` supplies `get_media_upload_policy` → `create_media_upload` → direct HTTP PUT → `commit_media_upload` when its shared media adapter is wired. Follow the pinned media docs for tenant admin authentication (historical Core
17
- uses admin); host project credentials are not application credentials. Upload capability URLs are temporary,
18
+ Admin media library and the application's selected storage. Follow the pinned Core upload/PUT/commit
19
+ contract and `x-mantle-ref: media_assets` plus `x-mcp-hint: media-image`; store committed asset IDs, resolve permanent variants in the frontend, never use an ID as an image URL. The application's `/mcp/admin` supplies `get_media_upload_policy` → `create_media_upload` → direct HTTP PUT → `commit_media_upload` when its shared media adapter is wired. Follow the installed media authentication contract; host project credentials are not application credentials. Upload capability URLs are temporary,
18
20
  not committed public images; anonymous visitors must not gain admin media access.
19
21
  - Generate an accessible, responsive public frontend by reading the installed
20
- `@aotter/mantle/web` REST contract; browser code on static hosts uses
22
+ generated `web.ts` and REST contracts; browser code on static hosts uses
21
23
  same-origin fetch, not a server surface imported into the browser. Do not install the historical standalone
22
- `@aotter/mantle-web` or claim Core supplies an HTML renderer. Application-owned `service.fetch` may render HTML; follow the selected host's static/template and pairing restrictions.
24
+ `@aotter/mantle-web` or claim Core supplies an HTML renderer. The application-owned Fetch entry renders HTML; follow the selected host's static/template restrictions.
23
25
  - Public content follows the installed `docs/handbook/guides/public-pages.md`
24
26
  (the one list of head tags, JSON-LD, languages, Markdown, sitemap, robots and
25
27
  `llms.txt`). For public content on static hosts disable SPA fallback and check unknown URLs
@@ -32,16 +34,16 @@ uses admin); host project credentials are not application credentials. Upload ca
32
34
  dependency; a dynamic blog is blocked until that path exists. Do not silently
33
35
  substitute build-time sample content for live tenant content.
34
36
 
35
- Before upload, follow the [local HTTP acceptance](local-testing.md): native HTTP HTML responses need no browser or deployment. Before reporting completion, inspect HTML without executing JavaScript, check
36
- metadata/sitemap and anonymous draft/permission refusal, and exercise OTP,
37
- content editing and media upload/commit with authorized synthetic accounts.
38
- Read the host's preview capability limits: disabled mail/media checks stay
39
- pending, not passed. Use candidate preview first, then an existing explicitly authorized live test
40
- tenant with authorized admin accounts for disabled services. Do not create or
41
- publish a test tenant without authorization. Live tests require
42
- explicit authorization for synthetic writes and cleanup. Without a published
43
- test tenant or that authorization, report them pending.
44
- Do not weaken preview isolation, fake success or grant admin privileges outside the authorized test scope to make
45
- checks pass. Provenance/pairing review does not certify website quality; report
46
- passed, failed and blocked checks separately. Pending required checks also
47
- block completion.
37
+ Follow the [local HTTP acceptance](local-testing.md) before reporting local
38
+ readiness: inspect HTML without JavaScript, check metadata/sitemap and anonymous
39
+ draft/permission refusal, and exercise OTP and editing with isolated synthetic
40
+ accounts. Local readiness does not require publication, a hosted tenant or a
41
+ candidate preview. Report production email, public origin and real object-store
42
+ upload/commit checks separately when local capabilities cannot exercise them.
43
+
44
+ For an explicitly requested deployment, use the selected host's native workflow
45
+ and any preview it provides. Verify disabled preview capabilities on an already
46
+ authorized live target; synthetic writes and cleanup stay within that scope.
47
+ Pending production checks block a production-readiness claim, not an otherwise
48
+ passing local-development handoff. Preserve preview isolation and permissions;
49
+ report passed, failed and blocked checks for each environment separately.
@@ -1,10 +0,0 @@
1
- import type { AdminExtension, AdminNavGroup } from "@aotter/mantle-admin/server/extensions";
2
-
3
- /**
4
- * Admin presentation, read by `mantle generate --admin-extensions src/admin.ts` (no runtime code).
5
- * AGENT: to group the sidebar for how staff work, declare groups here and place Schemas and admin Views in them with
6
- * `uiSchema.nav: { group, order, hidden }` (docs/handbook/guides/native-admin.md, "Sidebar"). Built-in groups need no
7
- * declaration: content, operations, reports, more. Admin extensions also go here.
8
- */
9
- export const navGroups: AdminNavGroup[] = [];
10
- export const adminExtensions: AdminExtension[] = [];
@@ -1,12 +0,0 @@
1
- import type { AdminExtension, AdminNavGroup } from "@aotter/mantle-admin/server/extensions";
2
-
3
- /**
4
- * Admin presentation, read by `mantle generate --admin-extensions src/admin.ts` (no runtime code).
5
- * The approver's daily work gets its own sidebar group above Admin's built-in ones (content 10, operations 20,
6
- * reports 30; More stays last); manifests place `pending-requests` and `requests` in it with `uiSchema.nav`.
7
- * AGENT: add groups for how the staff work; titles take one string or a { locale: text } map.
8
- */
9
- export const navGroups: AdminNavGroup[] = [
10
- { id: "approvals", title: { en: "Approvals", "zh-TW": "簽核" }, order: 5 },
11
- ];
12
- export const adminExtensions: AdminExtension[] = [];
@@ -1,20 +0,0 @@
1
- # Extend Admin
2
-
3
- Native Admin accepts app-owned extension declarations, executable server handlers and optional same-origin client modules. Import client `defineAdminExtension` from `@aotter/mantle-admin/extension` and UI primitives from `@aotter/mantle-ui/kit`. Server types live in `@aotter/mantle-admin/server`.
4
-
5
- | Contribution | Placement |
6
- | --- | --- |
7
- | pages/settings | Extension page; settings forms are generated from the supported form subset |
8
- | actions | record, list selection or list toolbar |
9
- | panels | record sidebar or home |
10
- | fields | field input or cell |
11
-
12
- Admin contributions sit behind the admin-layer gate; optional field roles default to `admin`. Server authorization is checked on every route. Handlers own finer business permissions.
13
-
14
- Pass full declarations to `mantle generate … --admin --admin-extensions <module>` (named/default `adminExtensions` array). Generation checks contributions, manifest uiSchema references and settings schemas, then emits `extensionMetadata` and compiled `extensionBindings` in `admin-extensions.ts`. Bind the same runtime definitions with `extensionBindings(adminExtensions)` and merge its extensions/routes into `admin()` options. Drift is refused before execution.
15
-
16
- Serve each `module` at a same-origin absolute path and install its integrity in the host shell's import map. Native Admin does not serve `source` modules or inject integrity; generation rejects source. Share React and the UI kit via the built import map, rather than bundling a second React. Canonical Admin refuses framing; use its separate same-origin preview contract.
17
-
18
- Raw API handlers receive the original Request. Declared `bodyLimit` checks Content-Length before DB access, but the app must bound unknown-length streams. Built-in JSON routes use the shared bounded reader after caller/origin checks. Do not lose exact OCC or uncertain-outcome handling in custom actions.
19
-
20
- See [native Admin](native-admin.md) for mounting and acceptance and [generated descriptors](../reference/admin-descriptors.md) for build-time metadata.