@aotter/mantle 0.2.0 → 0.2.1-alpha.2

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 (89) hide show
  1. package/README.md +6 -2
  2. package/dist/build/compiler.d.ts +6 -6
  3. package/dist/build/compiler.js +6 -3
  4. package/dist/build/spec/domain/model/ManifestGrammar.d.ts +39 -1
  5. package/dist/build/spec/domain/model/RuntimePlan.d.ts +16 -3
  6. package/dist/build/spec/domain/model/SqlIr.d.ts +30 -0
  7. package/dist/build/spec/kernel/diagnostic.d.ts +1 -1
  8. package/dist/domain/describe/chunk-CW7X5Q5T.js +1 -0
  9. package/dist/domain/describe/index.d.ts +1 -0
  10. package/dist/domain/describe/index.js +1 -1
  11. package/dist/domain/describe/match.d.ts +19 -0
  12. package/dist/domain/describe/public.d.ts +3 -0
  13. package/dist/domain/describe/public.js +1 -0
  14. package/dist/infrastructure/adminEntries.js +19 -3
  15. package/dist/infrastructure/bundle.js +43 -8
  16. package/dist/infrastructure/cli.js +1 -1
  17. package/dist/infrastructure/generate.js +17 -3
  18. package/dist/kernel/binds.d.ts +18 -3
  19. package/dist/kernel/binds.js +1 -1
  20. package/dist/kernel/contracts.d.ts +7 -0
  21. package/dist/kernel/contracts.js +9 -0
  22. package/dist/kernel/driver/bun-sqlite.js +3 -3
  23. package/dist/kernel/driver/d1.d.ts +1 -1
  24. package/dist/kernel/driver/d1.js +6 -3
  25. package/dist/kernel/driver/postgres.d.ts +2 -1
  26. package/dist/kernel/driver/postgres.js +11 -6
  27. package/dist/kernel/mcp-apps.d.ts +3 -2
  28. package/dist/kernel/mcp-apps.js +7 -2
  29. package/dist/kernel/mcp-handler.js +22 -9
  30. package/dist/kernel/mcp.d.ts +18 -0
  31. package/dist/kernel/mcp.js +1 -0
  32. package/dist/kernel/rest-router.js +3 -5
  33. package/dist/kernel/rest.d.ts +2 -1
  34. package/dist/kernel/rest.js +1 -0
  35. package/dist/kernel/route-pattern.d.ts +26 -0
  36. package/dist/kernel/route-pattern.js +34 -0
  37. package/dist/kernel/store.d.ts +15 -1
  38. package/dist/kernel/store.js +51 -18
  39. package/dist/usecase/adminBindings.js +2 -2
  40. package/dist/usecase/adminClient.js +4 -1
  41. package/dist/usecase/generate.js +7 -5
  42. package/dist/usecase/handlers.js +1 -1
  43. package/dist/usecase/publishing.js +20 -7
  44. package/dist/usecase/rest.js +5 -5
  45. package/dist/usecase/stores.js +8 -3
  46. package/docs/examples/README.md +1 -1
  47. package/docs/examples/app-shell/README.md +58 -10
  48. package/docs/examples/app-shell/package.json +6 -6
  49. package/docs/examples/club-events/manifests/club-events.yaml +2 -0
  50. package/docs/examples/generated-web/seed.sql +5 -4
  51. package/docs/examples/purchasing/manifests/purchasing.yaml +3 -0
  52. package/docs/handbook/cloudflare/media-r2.md +6 -3
  53. package/docs/handbook/cloudflare/service-entry.md +2 -0
  54. package/docs/handbook/concepts/lifecycle-and-locales.md +21 -1
  55. package/docs/handbook/examples/hub.md +1 -1
  56. package/docs/handbook/guides/admin-ui.md +1 -1
  57. package/docs/handbook/guides/agent-setup.md +13 -8
  58. package/docs/handbook/guides/agent-workflow-acceptance.md +129 -19
  59. package/docs/handbook/guides/local-testing.md +50 -5
  60. package/docs/handbook/guides/mcp-apps.md +40 -0
  61. package/docs/handbook/guides/native-admin.md +218 -11
  62. package/docs/handbook/guides/native-execution.md +5 -4
  63. package/docs/handbook/guides/revisions.md +584 -0
  64. package/docs/handbook/guides/size-and-startup.md +140 -0
  65. package/docs/handbook/guides/sql-patterns.md +47 -1
  66. package/docs/handbook/guides/typed-queries.md +8 -3
  67. package/docs/handbook/navigation.json +4 -0
  68. package/docs/handbook/reference/authorization.md +2 -0
  69. package/docs/handbook/reference/describe.md +56 -4
  70. package/docs/handbook/reference/diagnostics.md +12 -3
  71. package/docs/handbook/reference/procedure.md +4 -4
  72. package/docs/handbook/reference/schema.md +71 -7
  73. package/docs/handbook/reference/sql.md +2 -1
  74. package/docs/handbook/reference/surface.md +13 -2
  75. package/docs/handbook/reference/trigger.md +12 -0
  76. package/docs/handbook/releases/index.md +75 -1
  77. package/docs/handbook/start/agents.md +6 -2
  78. package/docs/handbook/start/project-and-cli.md +4 -0
  79. package/docs/handbook/start/quickstart-worker.md +1 -1
  80. package/docs/skills/develop/SKILL.md +15 -3
  81. package/docs/skills/integrate/SKILL.md +3 -1
  82. package/docs/skills/performance/SKILL.md +169 -0
  83. package/docs/skills/update/SKILL.md +9 -5
  84. package/docs/upgrade-0.1-to-0.2.md +151 -39
  85. package/package.json +10 -11
  86. package/skills/README.md +6 -2
  87. package/skills/mantle/SKILL.md +19 -5
  88. package/dist/domain/describe/chunk-SGMRVDGE.js +0 -1
  89. package/dist/domain/describe/target-hash.js +0 -1
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Every Mantle release line — what 0.2.0 changes, and what each stable 0.1.x release contained.
2
+ description: Every Mantle release line — what 0.2.x changes, and what each stable 0.1.x release contained.
3
3
  ---
4
4
  # Releases
5
5
 
@@ -15,6 +15,80 @@ From 0.2.0-alpha.7, Mantle publishes three packages together at one version:
15
15
  and `@aotter/mantle-admin` (optional Admin server, SPA and MCP App).
16
16
  Pin every package you use to the same exact version and upgrade them together.
17
17
 
18
+ ## 0.2.1 — in preparation
19
+
20
+ 0.2.1 adds Schema locks: a manifest rule that refuses a row's update or delete
21
+ for every caller path (REST, MCP, Admin and Procedures), with Admin showing the
22
+ lock before an edit. `spec.publishing.liveEdits` lets an application edit a
23
+ published row in place, and the [revisions guide](../guides/revisions.md) now
24
+ freezes the live revision with a lock and switches it atomically. It also brings
25
+ Admin form and refresh fixes, the media picker for custom inputs and pages
26
+ (`@aotter/mantle-admin/media`), `matchTarget` in `@aotter/mantle/describe`, and
27
+ dependency updates for current advisories.
28
+
29
+ Procedures gain `handler.steps`: a program written one statement per step, where
30
+ `onNoRows: conflict` makes a set-op write that writes nothing a `CONFLICT` and
31
+ rolls the whole program back ("create only if the parent exists"). Ref handlers
32
+ and interactive transactions can use `store.batch` for atomic multi-writes, and
33
+ `mantle bundle` under `wrangler dev` reports stale generated output in one line
34
+ instead of a failed build.
35
+
36
+ ### Upgrading to 0.2.1-alpha.2
37
+
38
+ Pin the selected packages to `0.2.1-alpha.2` and regenerate. Breaking change:
39
+
40
+ - **`@aotter/mantle/describe`** keeps only `matchTarget` and the
41
+ `AppDescription`, `DescribeTarget` and `TargetRequest` types. `describeApp`,
42
+ `diffApp` and the `@aotter/mantle/target-hash` subpath are removed.
43
+ **`mantle describe` output is the supported way to get a description outside
44
+ the CLI:** run `mantle describe <target> manifests/*.yaml > describe.json` in
45
+ Node.js or Bun (for example in a deploy step) and give the JSON to
46
+ `matchTarget`. Do not import compiler files from `dist`; a Worker cannot
47
+ compile manifests that contain SQL ([describe](../reference/describe.md)).
48
+ Use `mantle describe --diff` instead of `diffApp`, and `_meta.targetHash`
49
+ instead of `targetHash()`.
50
+
51
+ Hand-built MCP tools gain three opt-in capabilities; without them the output
52
+ is unchanged ([MCP Apps](../guides/mcp-apps.md), [surface](../reference/surface.md)):
53
+
54
+ - `Tool.meta` merges into the tool's listed `_meta`. `ui.visibility: ["app"]`
55
+ can now hide a Procedure from clients without MCP Apps; it is a listing hint,
56
+ and calls are authorized as before.
57
+ - `withResultMeta(data, meta)` returns `meta` only in the result `_meta`, so a
58
+ value such as a signed upload URL stays out of `content`. `callTool` returns
59
+ `{ data, _meta }`; drop `_meta` before forwarding a result to a model.
60
+ - `toolsPageSize` pages `tools/list` with an opaque `nextCursor`.
61
+
62
+ Also: generation reports a SQL parser that cannot load in the current runtime
63
+ as such, instead of `SQL_SYNTAX`, and the handbook renders under Vue-based
64
+ site generators (bare `<placeholder>` text is now quoted, and `pnpm check`
65
+ fails on any that return).
66
+
67
+ ### Upgrading to 0.2.1-alpha.1
68
+
69
+ Pin `@aotter/mantle`, and any selected `@aotter/mantle-ui` and
70
+ `@aotter/mantle-admin`, to `0.2.1-alpha.1`, refresh the lockfile, regenerate and
71
+ review owned output. No DDL changes are required. Breaking changes:
72
+
73
+ - **PostgreSQL `version`:** Store results return `version` as a number, as on
74
+ SQLite and D1. Procedure results stay driver-native.
75
+ - **Admin record form:** clearing an optional field sends `null`; generated
76
+ form types for optional fields are `T | null`.
77
+ - **REST route precedence** is fixed and most-specific-first. Only overlapping
78
+ same-method http Triggers with the same parameter count can change winner.
79
+ `TRIGGER_PATH_INVALID` and `TRIGGER_PATH_COLLISION` refuse ambiguous paths
80
+ at generation; see [route precedence](../reference/trigger.md#route-precedence).
81
+ - **Tooling:** the templates move to Wrangler 4.153.0 and
82
+ `@cloudflare/workers-types` 5.20261027.1.
83
+ - **PostgreSQL serialization failures:** SQLSTATE `40001` and `40P01` from a
84
+ definitive server refusal are now `CONFLICT` with `kind: "serialization"`
85
+ (409), instead of an unclassified driver error. Nothing is retried
86
+ automatically; read again before deciding to retry.
87
+ - **Revisions recipe:** an application that copied the guide's
88
+ `switch-revision` handler should adopt the new version. It requires
89
+ `expectedRevisionVersion` from the preview and seals and switches in one
90
+ `ctx.store.batch`.
91
+
18
92
  ## 0.2.0 (2026-10-19)
19
93
 
20
94
  The first stable native 0.2 release compiles closed v2 manifests to SQL and
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: The entry point `mantle help` prints first: choose a complete app or generation only, use examples as references, accept before done.
2
+ description: "The entry point `mantle help` prints first: choose a complete app or generation only, use examples as references, accept before done."
3
3
  ---
4
4
  # Build with an agent
5
5
 
@@ -38,7 +38,11 @@ the app entry (`--entry`) never imports, it warns and names the topic that shows
38
38
  4. `pnpm generate`, implement every handler it lists, `pnpm check`, then `pnpm smoke`.
39
39
  5. Before reporting the app or a feature done, run [role-only acceptance](../guides/agent-workflow-acceptance.md)
40
40
  (`mantle help agent-workflow-acceptance`). Scripted smoke is not acceptance. `pnpm accept` starts the app and hands
41
- each role to a fresh evaluator as a URL that carries that role's session.
41
+ each role to a fresh evaluator as a URL that carries that role's session. After a repair, the guide's
42
+ [re-verification rule](../guides/agent-workflow-acceptance.md#re-verify-what-a-repair-touches) decides which roles
43
+ and surfaces run again.
44
+ 6. Once acceptance converges, follow the [performance skill](../../skills/performance/SKILL.md): it decides which of
45
+ front end (Lighthouse), cold start and backend load apply, and holds each to a target before you report done.
42
46
 
43
47
  The first verified sign-in with `ADMIN_EMAIL` becomes the admin. Further administrators are added in Admin:
44
48
  **More → Administrators** invites by email, and **More → Members** grants Admin to an existing member.
@@ -59,6 +59,10 @@ Other handles may adapt to the same [structural driver contracts](../guides/adap
59
59
  `--auth` and `--site` modules). `mantle bundle`, which Wrangler runs for `wrangler dev` and every
60
60
  deploy, refuses to build when an input changed since, so stale generated code cannot run; regenerate and rebuild.
61
61
  Commit it with the other generated files.
62
+ Under `wrangler dev` (Wrangler sets `WRANGLER_COMMAND=dev`) the refusal is one line per change instead of a failed
63
+ build: `mantle bundle` removes `<outdir>/worker` and exits 0, so Wrangler reports the entry missing and holds requests.
64
+ Writing `generated/` rebuilds. Other commands, other errors and a build by hand still fail with a nonzero exit.
65
+ To see that form while `wrangler dev` runs, run `pnpm build` (or `mantle bundle` by hand).
62
66
  The bundle also prints notes, never errors, for SQL in the app's own code against Better Auth's tables (read users
63
67
  through `userOf(caller)` or `readIdentity(auth)` instead) and for Better Auth roles beyond `admin` and `user`.
64
68
 
@@ -3,7 +3,7 @@ description: Generate a small native D1 service and mount an application-owned W
3
3
  ---
4
4
  # Quickstart: a service on Workers
5
5
 
6
- Create an application outside the SDK checkout. Install stable `@aotter/mantle@0.2.0` exactly, TypeScript, Wrangler and Cloudflare Worker types; `node_modules/@aotter/mantle/docs/examples/app-shell/package.json` lists the versions this release is tested with. Read that installed version's handbook; this page describes the native 0.2.0 contract.
6
+ Create an application outside the SDK checkout. Install `@aotter/mantle@0.2.1-alpha.2` exactly (a prerelease; stable 0.2.0 has its own tagged handbook), TypeScript, Wrangler and Cloudflare Worker types; `node_modules/@aotter/mantle/docs/examples/app-shell/package.json` lists the versions this release is tested with. Read that installed version's handbook; this page describes the native 0.2 contract.
7
7
 
8
8
  Save `manifests/tickets.yaml`:
9
9
 
@@ -25,14 +25,23 @@ visibility, OCC and restart persistence, not just a 200 response.
25
25
  Before reporting any new app or feature as done, follow the [independent
26
26
  acceptance guide](../../handbook/guides/agent-workflow-acceptance.md): write a
27
27
  private rubric, then give one fresh agent per role (`admin`, `user`) only its
28
- role and entry points, across every surface it uses. This is not limited to
28
+ role and entry points, across every surface it uses. After a repair, re-run
29
+ the scope its [re-verification
30
+ rule](../../handbook/guides/agent-workflow-acceptance.md#re-verify-what-a-repair-touches)
31
+ names and state which evidence you reused. This is not limited to
29
32
  MCP; if it was not run, say so explicitly and report the work as UNVERIFIED
30
- rather than done. For MCP workflows, also run the guide's design audit before implementing
31
- tools.
33
+ rather than done. Hand off with the guide's [layered
34
+ report](../../handbook/guides/agent-workflow-acceptance.md#report-done-ness-in-layers):
35
+ an environment block is BLOCKED on its layer, never a product failure. For MCP workflows, also run the guide's design audit before implementing
36
+ tools. Once acceptance converges, follow the [performance skill](../performance/SKILL.md) before reporting done.
32
37
 
33
38
  For native Admin, read the [current guide](../../handbook/guides/native-admin.md):
34
39
  the app builds Admin with `mantle bundle`. To customise pages, slots, hooks or
35
40
  MCP-host-safe components, follow [Customising Admin](../../handbook/guides/native-admin.md#customising-admin).
41
+ Custom structured inputs and browser pages can use the optional
42
+ `@aotter/mantle-admin/media` controlled `MediaPicker`: pass `readOnly` and an exact
43
+ `uploadPurpose` (omit for selection only), apply `onSelect` to the local draft,
44
+ and keep its import out of the MCP App entry. See the native Admin media example.
36
45
  Keep matching SDK, Admin and UI versions. Ref handlers retain caller-bound
37
46
  `ctx.store`; generic Admin reads use shared generated View templates and writes
38
47
  use native Procedure fragments.
@@ -80,6 +89,9 @@ Destructive changes and type changes need explicit data migration. Mantle drops
80
89
 
81
90
  Writes use Store `insert` / `update` / `delete`, `batch`, `transaction`, or declared Procedures. Never use raw SQL writes: they bypass scope, TTL, publishing and system-column rules. For reads beyond an id lookup or simple AND filter (joins, aggregates, OR, reuse), declare an internal View so the SQL is reviewable and typed. Store `findById`, `find` and `first` remain suitable for handler lookups and embedding in an existing app. Ref handlers receive `ctx.store` bound to the same Caller and transaction.
82
91
 
92
+ For published-content replacement with preview and rollback, follow `mantle help revisions`: Core supplies OCC, Schema locks and atomic `store.batch`; the recipe binds the previewed revision ID/version and atomically seals it while switching the parent. Applications own retention and review policy; Core does not mandate a preparation step. Keep the previewed version on submit and require another preview after a revision conflict.
93
+ Use its custom Native Admin preview/switch page: freeze the reviewed content and both row versions, then submit them through the authorized operation. Do not make editors copy version numbers or silently replace the reviewed snapshot after a refresh; conflicts require another explicit preview.
94
+
83
95
  For simple creates/partial updates, prefer Store-backed ref Procedures; keep
84
96
  Procedure `requires`/generated input checks, use only allowed patch fields and
85
97
  return safe business fields with the actual returned ID/version. Preserve
@@ -22,7 +22,9 @@ data-preserving schema/auth/role migrations on a copy and retain rollback artifa
22
22
  Initial schema.sql is for an empty database, not an in-place upgrade. Requests run
23
23
  no DDL or storage checks; the only request-time write outside app operations is
24
24
  the configured OAuth resource row (see [OAuth](../../handbook/guides/oauth.md)).
25
- Verify cutover with actual app tests.
25
+ Verify cutover with actual app tests. Before reporting user-facing work done, run
26
+ [independent acceptance](../../handbook/guides/agent-workflow-acceptance.md), then the
27
+ [performance skill](../performance/SKILL.md).
26
28
 
27
29
  Preserve the app router, verified identity and native resources. For selected
28
30
  Admin, follow the [native guide](../../handbook/guides/native-admin.md) for its
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: performance
3
+ description: Make an accepted Mantle 0.2 application fast — Lighthouse for app-authored pages, Worker cold start and first-load budgets, and backend reads and writes under realistic data volume with indexes and internal Views. Use right after independent acceptance converges, or when a user reports a slow page, first request or query.
4
+ metadata:
5
+ source: "@aotter/mantle"
6
+ sourcePath: docs/skills/performance/SKILL.md
7
+ applies_to: mantle 0.2
8
+ projection: package
9
+ ---
10
+
11
+ # Mantle Performance
12
+
13
+ This skill sets direction: when to run, what to aim for, in what order and when
14
+ to stop. It names no tools or commands. Choose the measurement and repair
15
+ methods that fit the application, its host and the tools available to you; the
16
+ targets and rules below are what stay fixed.
17
+
18
+ ## When to run
19
+
20
+ - **After acceptance.** Once [independent acceptance](../../handbook/guides/agent-workflow-acceptance.md)
21
+ reports CONVERGED for a new application or a feature, continue here before
22
+ reporting done. Never optimize behavior that has not been accepted: after
23
+ BLOCKED or UNVERIFIED, report that and stop.
24
+ - **On request.** When a user reports a slow page, slow first request or slow
25
+ query, run only the part that covers it, then check the others it could affect.
26
+
27
+ ## Choose what to run
28
+
29
+ Decide from the manifests, the service entry and the changed files, not from
30
+ guesses about future use. Run every part whose condition holds; record each
31
+ skipped part with its reason.
32
+
33
+ | Run | When the application or change has | Skip when |
34
+ |---|---|---|
35
+ | Front end | Pages a browser opens directly that the application authors: public pages, member pages, a custom frontend, Admin customisations | The only browser UI is SDK-built Admin, unchanged; MCP and REST alone have no page to measure |
36
+ | Cold start | A deployed Worker or service entry: always for a new application; for a change, any added or moved import in the entry, its startup graph, a page's or an MCP App entry's first-load code | The change touched no import, entry, page or MCP App bundle |
37
+ | Backend reads | Views, or Store reads in handlers, whose rows grow with data: lists, search, paging, joins, aggregates, totals, reports | Only id lookups and small, bounded configuration tables |
38
+ | Backend writes | Procedures or Store writes that run often or concurrently: stock, counters, approvals, checkout, imports | Rare single-row administrative writes |
39
+
40
+ A change in one part can move another: an added index slows writes, a shared
41
+ stylesheet or entry import affects every page. Re-measure what a repair can reach.
42
+
43
+ ## Front end
44
+
45
+ **Target:** the highest Lighthouse performance score the page allows, with a
46
+ floor of 90 on mobile and 95 on desktop for every distinct page template, and
47
+ no regression in accessibility, SEO or best practices.
48
+
49
+ - Measure a production build, several runs on mobile and desktop, and report the
50
+ range. Separate what is real from what only the local environment causes
51
+ (no compression or HTTP/2, a cold cache) and say which is which.
52
+ - Measure pages behind sign-in (member pages, Admin) through the role's session
53
+ URL that `pnpm accept` prints
54
+ ([hand each role](../../handbook/guides/agent-workflow-acceptance.md#hand-each-role-to-its-evaluator)),
55
+ never by weakening sign-in.
56
+ - Find the actual bottleneck before changing anything; a trace beats a guess.
57
+ - Repair in this order: what blocks the first paint (render-blocking styles and
58
+ font stylesheets, request chains, unused bytes), then main-thread work (heavy
59
+ scripts, animations, layout of off-screen content), then repeat visits
60
+ (content-hashed assets cached long, HTML revalidated).
61
+ - When a bottleneck appears only because the measuring environment lacks
62
+ something (a GPU, a fast CPU), fix it only in a way that also helps real users
63
+ without it. Never detect the measuring tool to serve it a different page.
64
+ - After every change, prove nothing else moved: the page looks the same, links,
65
+ forms and in-page anchors still work, and the
66
+ [public-page checks](../../handbook/guides/public-pages.md#check-before-you-report-done)
67
+ still pass without JavaScript.
68
+
69
+ ## Cold start
70
+
71
+ **Target:** budgets that force code to load when it is needed, not before.
72
+
73
+ - **Worker:** its startup graph imports only what every request needs; auth, MCP,
74
+ Admin and rarely used routes load on the request that uses them
75
+ ([size and startup](../../handbook/guides/size-and-startup.md)). On Workers the
76
+ startup graph is the entry chunk `mantle bundle` writes under `<outdir>/worker`
77
+ plus the chunks it imports statically ([outputs](../../handbook/start/project-and-cli.md#outputs));
78
+ anything behind a dynamic import is outside it. Report its size locally as the
79
+ *Worker entry static graph*; measure the host's startup time only on
80
+ a deployment the user has authorized, and keep it well under the host's limit
81
+ (aim below 50 ms on Cloudflare).
82
+ - **Pages:** each page's *first-load JavaScript* is at most 100 KB, and only
83
+ what the first paint and first interaction need. Move the rest behind dynamic
84
+ imports, on use or when the browser is idle. An MCP App the application
85
+ authors holds its first-load JavaScript, the inline script text of its one
86
+ HTML file, to the same budget; it renders inside a host, so Lighthouse does
87
+ not measure it. Report the whole *MCP App HTML document* as its own number: it
88
+ also holds CSS and markup, so never compare it with this budget.
89
+ - Use the one definition of each metric in
90
+ [size metrics](../../handbook/guides/size-and-startup.md#size-metrics), with
91
+ its measurement. Where the SDK's own checks measure differently, that page says how.
92
+ - An overrun is a finding to repair by splitting, not a budget to raise. Raise a
93
+ budget only with the user's agreement and record why.
94
+
95
+ ## Backend
96
+
97
+ **Target:** every read and write the application's surfaces actually make stays
98
+ fast at a realistic volume, and no hot path scans a table that grows.
99
+
100
+ - **Data:** seed an isolated local database, never a shared or production one,
101
+ with data shaped like real use: several owners and roles, every state, long
102
+ text where fields allow it, and more than one page of results everywhere. Size
103
+ the largest tables at 100,000 rows or 10 times the expected first-year volume,
104
+ whichever is larger. Seed with SQL straight into that database, setting the
105
+ native columns as [reserved entry columns](../../handbook/reference/schema.md#reserved-entry-columns)
106
+ describes: it is test data, not an application write.
107
+ - **Load:** call every View and Procedure through the same callers and surfaces
108
+ the application uses, as each role. The app's local test harness already
109
+ starts it on a fresh database, signs each role in and calls routes and MCP
110
+ tools as that role ([local HTTP checks](../../handbook/guides/local-testing.md#what-smoke-covers)).
111
+ Record typical and slow-tail latency and
112
+ rows read, then run concurrent writers wherever contention matters. A business
113
+ rule that breaks under concurrency (oversell, double approval, lost update) is
114
+ a correctness defect, not a performance finding: fix it first.
115
+ - **Aim:** hot reads stay in the tens of milliseconds locally at seeded volume,
116
+ and their cost does not grow with table size.
117
+ - **Repair in this order:**
118
+ 1. Read the native query plan of each hot path, using the SQL in its generated
119
+ query module under `generated/` against the seeded database; a full scan of a
120
+ growing table is a finding.
121
+ 2. Add the index that serves it in the Schema's `indexes`
122
+ ([indexes](../../handbook/reference/schema.md#indexes-checks-and-search))
123
+ together with a native migration ([database changes](../develop/SKILL.md#database-changes)).
124
+ Index only what a measured query uses; every index costs writes. Paged Views
125
+ and [Schema locks](../../handbook/reference/schema.md#locks) are index-proven
126
+ already: generation refuses one no index serves.
127
+ 3. Move complex reads (joins, aggregates, OR, reuse) into an
128
+ [internal View](../../handbook/guides/typed-queries.md#declare-an-internal-view),
129
+ page with keysets ([results and paging](../../handbook/reference/view.md#results-and-paging)),
130
+ and replace exact totals on hot paths ([search and totals](../../handbook/reference/view.md#search-and-totals)).
131
+ 4. Re-measure reads and writes after each repair.
132
+
133
+ ## Rules
134
+
135
+ - Speed never buys a lower standard: scope, authorization, OCC, atomicity,
136
+ accessibility, the public-page requirements and every explicit user
137
+ requirement stay intact. The application's writes still go through Store and
138
+ Procedures; only seed data for the isolated test database is inserted directly.
139
+ - Do not lower a target, shrink the seeded data or drop a slow case to pass.
140
+ Report what is left instead.
141
+ - Work locally. Deploying or measuring a deployment follows the
142
+ [provision skill](../provision/SKILL.md) and needs the user's authorization.
143
+ - After any repair, rerun the [local HTTP checks](../../handbook/guides/local-testing.md).
144
+ A repair that changes what a user sees or can do is no longer only a
145
+ performance change: re-run acceptance for the scope the
146
+ [re-verification rule](../../handbook/guides/agent-workflow-acceptance.md#re-verify-what-a-repair-touches)
147
+ names. A changed View or Procedure widens it to every surface that reads or
148
+ writes that data, and so does a `uniqueIndexes` entry. A non-unique
149
+ `indexes` entry and its migration keep the business rules: run `pnpm check`,
150
+ the local HTTP checks and your focused regressions, not acceptance.
151
+ - Report app-added cost and SDK-existing cost separately. Built-in Admin has a
152
+ recorded [baseline](../../handbook/guides/size-and-startup.md#native-admin-baselines)
153
+ per SDK version; while the installed version and Admin entry are unchanged,
154
+ reuse it instead of repeating that experiment each round. Built-in Admin's
155
+ page and MCP App both miss the first-load budget; that is SDK-existing cost,
156
+ not the application's. A target the SDK's cost misses is still PARTIAL, with
157
+ its owner named. Never relabel it PASS.
158
+ - Do not patch vendor or SDK code, remove native Admin features or build a
159
+ general benchmark framework to meet a target.
160
+ - Stop when every target is met, after three rounds, or when two rounds in a row
161
+ bring no measurable gain.
162
+
163
+ ## Report
164
+
165
+ For each part: run or skipped (with the reason), the environment, before and
166
+ after numbers as ranges, what changed and what is left. Close with one verdict
167
+ beside the acceptance verdict: **PASS** (every target that applies is met),
168
+ **PARTIAL** (improved, with the targets still missed and why) or **SKIPPED**
169
+ (nothing applied).
@@ -15,12 +15,16 @@ metadata:
15
15
  Read the installed SDK README, then follow the version-matched [project and CLI
16
16
  workflow](../../handbook/start/project-and-cli.md) before editing.
17
17
 
18
- For 0.1.x, follow [Upgrade 0.1 to 0.2](../../upgrade-0.1-to-0.2.md): give the
19
- 0.2 service a new database and move data by export and import; never boot 0.2
20
- against a 0.1.x database. Between 0.2 versions, apply reviewed migrations
21
- rehearsed on a copy.
18
+ For 0.1.x, follow [Upgrade 0.1 to 0.2](../../upgrade-0.1-to-0.2.md). Mantle
19
+ ships no migration tool: plan the data move from
20
+ [Moving data from 0.1.x](../../upgrade-0.1-to-0.2.md#moving-data-from-01x),
21
+ verify each fact against the generated `schema.sql` and the 0.1.4 export, and
22
+ have the plan reviewed. Give the 0.2 service a new database, rehearse the load
23
+ on a copy, never boot 0.2 against a 0.1.x database, and keep exports out of the
24
+ repository. The guide's appendix is historical; do not follow it. Between 0.2
25
+ versions, apply reviewed migrations rehearsed on a copy.
22
26
 
23
- For the stable 0.2 line, pin every selected Mantle package to `0.2.0`; do not upgrade an existing application by following a moving dist-tag.
27
+ For the stable 0.2 line, pin every selected Mantle package to `0.2.0`; to try the 0.2.1 prerelease, pin all of them to `0.2.1-alpha.2` and read its release notes. Do not upgrade an existing application by following a moving dist-tag.
24
28
 
25
29
  Pin exact target SDK/peer versions and read its release notes and Admin build
26
30
  instructions. Core-to-native replaces app imports/wiring; it is not