swallowkit 2.0.0-alpha.1 → 2.0.0-alpha.11

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 (224) hide show
  1. package/README.ja.md +14 -0
  2. package/README.md +14 -0
  3. package/dist/cli/commands/add-auth.js +37 -6
  4. package/dist/cli/commands/add-auth.js.map +1 -1
  5. package/dist/cli/commands/configure-mcp.d.ts +12 -0
  6. package/dist/cli/commands/configure-mcp.d.ts.map +1 -0
  7. package/dist/cli/commands/configure-mcp.js +42 -0
  8. package/dist/cli/commands/configure-mcp.js.map +1 -0
  9. package/dist/cli/commands/dev.d.ts +2 -2
  10. package/dist/cli/commands/dev.d.ts.map +1 -1
  11. package/dist/cli/commands/dev.js +39 -27
  12. package/dist/cli/commands/dev.js.map +1 -1
  13. package/dist/cli/commands/init.d.ts +8 -2
  14. package/dist/cli/commands/init.d.ts.map +1 -1
  15. package/dist/cli/commands/init.js +67 -132
  16. package/dist/cli/commands/init.js.map +1 -1
  17. package/dist/cli/commands/migrations.d.ts.map +1 -1
  18. package/dist/cli/commands/migrations.js +25 -0
  19. package/dist/cli/commands/migrations.js.map +1 -1
  20. package/dist/cli/commands/provision.d.ts +5 -0
  21. package/dist/cli/commands/provision.d.ts.map +1 -1
  22. package/dist/cli/commands/provision.js +278 -55
  23. package/dist/cli/commands/provision.js.map +1 -1
  24. package/dist/cli/commands/scaffold.d.ts +4 -0
  25. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  26. package/dist/cli/commands/scaffold.js +85 -3
  27. package/dist/cli/commands/scaffold.js.map +1 -1
  28. package/dist/cli/index.d.ts +2 -0
  29. package/dist/cli/index.d.ts.map +1 -1
  30. package/dist/cli/index.js +43 -5
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/core/operations/create-model.d.ts +2 -0
  33. package/dist/core/operations/create-model.d.ts.map +1 -1
  34. package/dist/core/operations/create-model.js +60 -8
  35. package/dist/core/operations/create-model.js.map +1 -1
  36. package/dist/core/operations/migration-generator.d.ts.map +1 -1
  37. package/dist/core/operations/migration-generator.js +12 -1
  38. package/dist/core/operations/migration-generator.js.map +1 -1
  39. package/dist/core/operations/model-migration.d.ts +22 -0
  40. package/dist/core/operations/model-migration.d.ts.map +1 -0
  41. package/dist/core/operations/model-migration.js +36 -0
  42. package/dist/core/operations/model-migration.js.map +1 -0
  43. package/dist/core/operations/provision-deployment.d.ts +52 -0
  44. package/dist/core/operations/provision-deployment.d.ts.map +1 -0
  45. package/dist/core/operations/provision-deployment.js +164 -0
  46. package/dist/core/operations/provision-deployment.js.map +1 -0
  47. package/dist/core/operations/provision-operations.d.ts +62 -6
  48. package/dist/core/operations/provision-operations.d.ts.map +1 -1
  49. package/dist/core/operations/provision-operations.js +653 -115
  50. package/dist/core/operations/provision-operations.js.map +1 -1
  51. package/dist/core/operations/scaffold-apply.d.ts +1 -0
  52. package/dist/core/operations/scaffold-apply.d.ts.map +1 -1
  53. package/dist/core/operations/scaffold-apply.js +1 -0
  54. package/dist/core/operations/scaffold-apply.js.map +1 -1
  55. package/dist/core/operations/scaffold-machine.d.ts +1 -0
  56. package/dist/core/operations/scaffold-machine.d.ts.map +1 -1
  57. package/dist/core/operations/scaffold-machine.js.map +1 -1
  58. package/dist/core/operations/scaffold-plan.d.ts +2 -0
  59. package/dist/core/operations/scaffold-plan.d.ts.map +1 -1
  60. package/dist/core/operations/scaffold-plan.js +3 -1
  61. package/dist/core/operations/scaffold-plan.js.map +1 -1
  62. package/dist/core/project/agent-instructions.d.ts.map +1 -1
  63. package/dist/core/project/agent-instructions.js +4 -1
  64. package/dist/core/project/agent-instructions.js.map +1 -1
  65. package/dist/core/project/boundaries.d.ts +5 -2
  66. package/dist/core/project/boundaries.d.ts.map +1 -1
  67. package/dist/core/project/boundaries.js +51 -20
  68. package/dist/core/project/boundaries.js.map +1 -1
  69. package/dist/core/project/capabilities.d.ts +10 -0
  70. package/dist/core/project/capabilities.d.ts.map +1 -1
  71. package/dist/core/project/capabilities.js +38 -6
  72. package/dist/core/project/capabilities.js.map +1 -1
  73. package/dist/core/project/home-page.d.ts +4 -0
  74. package/dist/core/project/home-page.d.ts.map +1 -0
  75. package/dist/core/project/home-page.js +113 -0
  76. package/dist/core/project/home-page.js.map +1 -0
  77. package/dist/core/project/mcp-config.d.ts +26 -0
  78. package/dist/core/project/mcp-config.d.ts.map +1 -0
  79. package/dist/core/project/mcp-config.js +117 -0
  80. package/dist/core/project/mcp-config.js.map +1 -0
  81. package/dist/core/project/react-project.d.ts +1 -1
  82. package/dist/core/project/react-project.d.ts.map +1 -1
  83. package/dist/core/project/react-project.js +46 -25
  84. package/dist/core/project/react-project.js.map +1 -1
  85. package/dist/core/project/state.d.ts +7 -0
  86. package/dist/core/project/state.d.ts.map +1 -1
  87. package/dist/core/project/state.js +86 -0
  88. package/dist/core/project/state.js.map +1 -1
  89. package/dist/core/project/workflows.d.ts.map +1 -1
  90. package/dist/core/project/workflows.js +72 -12
  91. package/dist/core/project/workflows.js.map +1 -1
  92. package/dist/core/scaffold/auth-generator.d.ts.map +1 -1
  93. package/dist/core/scaffold/auth-generator.js +26 -27
  94. package/dist/core/scaffold/auth-generator.js.map +1 -1
  95. package/dist/core/scaffold/model-parser.d.ts +23 -0
  96. package/dist/core/scaffold/model-parser.d.ts.map +1 -1
  97. package/dist/core/scaffold/model-parser.js +407 -137
  98. package/dist/core/scaffold/model-parser.js.map +1 -1
  99. package/dist/core/scaffold/native-schema-generator.d.ts +13 -0
  100. package/dist/core/scaffold/native-schema-generator.d.ts.map +1 -1
  101. package/dist/core/scaffold/native-schema-generator.js +294 -91
  102. package/dist/core/scaffold/native-schema-generator.js.map +1 -1
  103. package/dist/core/scaffold/openapi-generator.d.ts +5 -0
  104. package/dist/core/scaffold/openapi-generator.d.ts.map +1 -1
  105. package/dist/core/scaffold/openapi-generator.js +53 -3
  106. package/dist/core/scaffold/openapi-generator.js.map +1 -1
  107. package/dist/core/scaffold/ui-generator.d.ts +0 -3
  108. package/dist/core/scaffold/ui-generator.d.ts.map +1 -1
  109. package/dist/core/scaffold/ui-generator.js +68 -7
  110. package/dist/core/scaffold/ui-generator.js.map +1 -1
  111. package/dist/core/verify/index.d.ts +4 -3
  112. package/dist/core/verify/index.d.ts.map +1 -1
  113. package/dist/core/verify/index.js +122 -5
  114. package/dist/core/verify/index.js.map +1 -1
  115. package/dist/machine/contracts.d.ts +1 -0
  116. package/dist/machine/contracts.d.ts.map +1 -1
  117. package/dist/machine/errors.d.ts +3 -2
  118. package/dist/machine/errors.d.ts.map +1 -1
  119. package/dist/machine/errors.js +2 -1
  120. package/dist/machine/errors.js.map +1 -1
  121. package/dist/machine/index.d.ts.map +1 -1
  122. package/dist/machine/index.js +59 -28
  123. package/dist/machine/index.js.map +1 -1
  124. package/dist/mcp/index.d.ts +6 -4
  125. package/dist/mcp/index.d.ts.map +1 -1
  126. package/dist/mcp/index.js +210 -25
  127. package/dist/mcp/index.js.map +1 -1
  128. package/dist/mcp/version-selection.d.ts +55 -0
  129. package/dist/mcp/version-selection.d.ts.map +1 -0
  130. package/dist/mcp/version-selection.js +152 -0
  131. package/dist/mcp/version-selection.js.map +1 -0
  132. package/dist/utils/azure-cli.d.ts +56 -0
  133. package/dist/utils/azure-cli.d.ts.map +1 -0
  134. package/dist/utils/azure-cli.js +326 -0
  135. package/dist/utils/azure-cli.js.map +1 -0
  136. package/dist/utils/azure-diagnostics.d.ts +16 -0
  137. package/dist/utils/azure-diagnostics.d.ts.map +1 -0
  138. package/dist/utils/azure-diagnostics.js +68 -0
  139. package/dist/utils/azure-diagnostics.js.map +1 -0
  140. package/dist/utils/package-manager.js +2 -2
  141. package/dist/utils/package-manager.js.map +1 -1
  142. package/dist/utils/python-uv.d.ts +5 -7
  143. package/dist/utils/python-uv.d.ts.map +1 -1
  144. package/dist/utils/python-uv.js +50 -24
  145. package/dist/utils/python-uv.js.map +1 -1
  146. package/dist/utils/react-dev.d.ts +4 -0
  147. package/dist/utils/react-dev.d.ts.map +1 -0
  148. package/dist/utils/react-dev.js +35 -0
  149. package/dist/utils/react-dev.js.map +1 -0
  150. package/dist/utils/semver.d.ts +14 -0
  151. package/dist/utils/semver.d.ts.map +1 -0
  152. package/dist/utils/semver.js +61 -0
  153. package/dist/utils/semver.js.map +1 -0
  154. package/package.json +6 -3
  155. package/src/__tests__/__snapshots__/boundaries.test.ts.snap +154 -0
  156. package/src/__tests__/agent-instructions.test.ts +93 -0
  157. package/src/__tests__/agent-loop-phase34.test.ts +143 -8
  158. package/src/__tests__/auth.test.ts +9 -0
  159. package/src/__tests__/azure-cli.test.ts +202 -0
  160. package/src/__tests__/boundaries.test.ts +42 -0
  161. package/src/__tests__/csharp-schema.test.ts +261 -0
  162. package/src/__tests__/dev.test.ts +13 -6
  163. package/src/__tests__/fixtures/az wrapper.cmd +2 -0
  164. package/src/__tests__/fixtures/azure-cli.cjs +153 -0
  165. package/src/__tests__/fixtures/provision-runner.cjs +28 -0
  166. package/src/__tests__/generated-project-matrix.test.ts +789 -0
  167. package/src/__tests__/home-page.test.ts +50 -0
  168. package/src/__tests__/init.test.ts +116 -0
  169. package/src/__tests__/mcp-version.test.ts +262 -0
  170. package/src/__tests__/mcp.test.ts +120 -3
  171. package/src/__tests__/multi-auth.test.ts +115 -4
  172. package/src/__tests__/package-manager.test.ts +17 -2
  173. package/src/__tests__/plan-apply.test.ts +179 -0
  174. package/src/__tests__/provision-runtime.test.ts +722 -0
  175. package/src/__tests__/python-uv.test.ts +50 -14
  176. package/src/__tests__/python-venv.test.ts +48 -0
  177. package/src/__tests__/react-dev.test.ts +72 -0
  178. package/src/__tests__/react.test.ts +19 -0
  179. package/src/__tests__/schema-analysis.test.ts +329 -0
  180. package/src/cli/commands/add-auth.ts +36 -6
  181. package/src/cli/commands/configure-mcp.ts +54 -0
  182. package/src/cli/commands/dev.ts +40 -31
  183. package/src/cli/commands/init.ts +73 -138
  184. package/src/cli/commands/migrations.ts +22 -0
  185. package/src/cli/commands/provision.ts +294 -56
  186. package/src/cli/commands/scaffold.ts +105 -3
  187. package/src/cli/index.ts +40 -7
  188. package/src/core/operations/create-model.ts +51 -13
  189. package/src/core/operations/migration-generator.ts +14 -1
  190. package/src/core/operations/model-migration.ts +52 -0
  191. package/src/core/operations/provision-deployment.ts +183 -0
  192. package/src/core/operations/provision-operations.ts +662 -154
  193. package/src/core/operations/scaffold-apply.ts +2 -0
  194. package/src/core/operations/scaffold-machine.ts +1 -0
  195. package/src/core/operations/scaffold-plan.ts +5 -1
  196. package/src/core/project/agent-instructions.ts +4 -1
  197. package/src/core/project/agent-templates/AGENTS.md +126 -6
  198. package/src/core/project/agent-templates/CLAUDE.md +14 -1
  199. package/src/core/project/agent-templates/copilot-instructions.md +15 -1
  200. package/src/core/project/agent-templates/shared-models.instructions.md +23 -3
  201. package/src/core/project/boundaries.ts +62 -20
  202. package/src/core/project/capabilities.ts +49 -6
  203. package/src/core/project/home-page.ts +114 -0
  204. package/src/core/project/mcp-config.ts +84 -0
  205. package/src/core/project/react-project.ts +50 -28
  206. package/src/core/project/state.ts +70 -0
  207. package/src/core/project/workflows.ts +72 -12
  208. package/src/core/scaffold/auth-generator.ts +26 -27
  209. package/src/core/scaffold/model-parser.ts +413 -129
  210. package/src/core/scaffold/native-schema-generator.ts +319 -103
  211. package/src/core/scaffold/openapi-generator.ts +63 -5
  212. package/src/core/scaffold/ui-generator.ts +70 -8
  213. package/src/core/verify/index.ts +118 -6
  214. package/src/machine/contracts.ts +1 -0
  215. package/src/machine/errors.ts +4 -2
  216. package/src/machine/index.ts +65 -34
  217. package/src/mcp/index.ts +221 -31
  218. package/src/mcp/version-selection.ts +163 -0
  219. package/src/utils/azure-cli.ts +315 -0
  220. package/src/utils/azure-diagnostics.ts +75 -0
  221. package/src/utils/package-manager.ts +2 -2
  222. package/src/utils/python-uv.ts +53 -33
  223. package/src/utils/react-dev.ts +31 -0
  224. package/src/utils/semver.ts +59 -0
@@ -19,6 +19,7 @@ export interface ApplyScaffoldOptions {
19
19
  functionsDir?: string;
20
20
  apiDir?: string;
21
21
  apiOnly?: boolean;
22
+ skipInfra?: boolean;
22
23
  }
23
24
 
24
25
  export interface ApplyScaffoldResult extends MachineScaffoldOperationResult {
@@ -70,6 +71,7 @@ export async function applyScaffoldOperation(options: ApplyScaffoldOptions): Pro
70
71
  functionsDir: options.functionsDir ?? basePlan?.options.functionsDir,
71
72
  apiDir: options.apiDir ?? basePlan?.options.apiDir,
72
73
  apiOnly: options.apiOnly ?? basePlan?.options.apiOnly,
74
+ skipInfra: options.skipInfra ?? basePlan?.options.skipInfra,
73
75
  };
74
76
 
75
77
  // 常に最新状態で collect し、競合を検出する(plan 指定時も現況を再確認)
@@ -13,6 +13,7 @@ export interface MachineScaffoldOperationOptions {
13
13
  functionsDir?: string;
14
14
  apiDir?: string;
15
15
  apiOnly?: boolean;
16
+ skipInfra?: boolean;
16
17
  expectedSchemaAnalysis?: SchemaAnalysisSnapshot;
17
18
  }
18
19
 
@@ -29,6 +29,7 @@ export interface PlanScaffoldOptions {
29
29
  functionsDir?: string;
30
30
  apiDir?: string;
31
31
  apiOnly?: boolean;
32
+ skipInfra?: boolean;
32
33
  }
33
34
 
34
35
  export type ScaffoldPlanAction = "create" | "update" | "overwrite" | "append" | "delete" | "skip";
@@ -59,6 +60,7 @@ export interface ScaffoldPlanData {
59
60
  functionsDir?: string;
60
61
  apiDir?: string;
61
62
  apiOnly?: boolean;
63
+ skipInfra?: boolean;
62
64
  };
63
65
  createdAt: string;
64
66
  swallowkitVersion: string;
@@ -93,6 +95,7 @@ async function collectScaffoldOperations(options: PlanScaffoldOptions): Promise<
93
95
  functionsDir: options.functionsDir,
94
96
  apiDir: options.apiDir,
95
97
  apiOnly: options.apiOnly,
98
+ skipInfra: options.skipInfra,
96
99
  });
97
100
  });
98
101
  });
@@ -193,7 +196,7 @@ export async function planScaffoldOperation(options: PlanScaffoldOptions): Promi
193
196
  .update(
194
197
  JSON.stringify({
195
198
  model: options.model,
196
- options: { functionsDir: options.functionsDir, apiDir: options.apiDir, apiOnly: options.apiOnly },
199
+ options: { functionsDir: options.functionsDir, apiDir: options.apiDir, apiOnly: options.apiOnly, skipInfra: options.skipInfra },
197
200
  operations: operations.map((op) => ({ path: op.path, action: op.action })),
198
201
  fingerprints,
199
202
  schemaAnalysis,
@@ -210,6 +213,7 @@ export async function planScaffoldOperation(options: PlanScaffoldOptions): Promi
210
213
  ...(options.functionsDir ? { functionsDir: options.functionsDir } : {}),
211
214
  ...(options.apiDir ? { apiDir: options.apiDir } : {}),
212
215
  ...(options.apiOnly !== undefined ? { apiOnly: options.apiOnly } : {}),
216
+ ...(options.skipInfra ? { skipInfra: true } : {}),
213
217
  },
214
218
  createdAt: new Date().toISOString(),
215
219
  swallowkitVersion: getSwallowKitVersion(),
@@ -71,6 +71,9 @@ function getBackendRules(backendLanguage: BackendLanguage): string {
71
71
  "- All backend business logic and data access live in `functions/`.",
72
72
  `- SwallowKit derives OpenAPI and native ${BACKEND_LANGUAGE_LABELS[backendLanguage]} schema assets from the Zod source of truth.`,
73
73
  "- Keep custom business logic in ai-authored locations identified by the current boundary contract.",
74
+ backendLanguage === "python"
75
+ ? "- Use uv with the user's interpreter/version settings. Local Python is not pinned to the Azure deployment runtime. Preserve functions/.venv and functions/.codegen-venv; do not clear them or weaken OS application-control policy to fix interpreter errors."
76
+ : "- Start the isolated Functions backend with dotnet run, not func start from the source directory, so the SDK loads extensions from the build output.",
74
77
  ].join("\n");
75
78
  }
76
79
 
@@ -91,7 +94,7 @@ function interpolateTemplate(template: string, context: AgentInstructionContext)
91
94
  ? "├── src/ # React SPA (Vite + React Router)\n│ └── pages/ # generated/custom UI and route registrations\n├── bff/ # SWA managed HTTP-only Functions\n│ ├── src/ # BFF handlers and request-local helpers\n│ └── {function}/ # function.json registrations"
92
95
  : "├── app/ # Next.js App Router\n│ ├── api/ # BFF routes\n│ └── {model}/ # generated/custom UI",
93
96
  devGuidance: react
94
- ? "Use http://localhost:4280 for the app. `swallowkit dev` runs Vite (3000), the managed BFF (7073), standalone Functions (7071), and SWA CLI (4280). SWA forwards /api only to the managed BFF, never directly to standalone Functions. `--no-functions` leaves the BFF running; `--no-swa` removes same-origin routing/auth emulation. BFF local settings belong in bff/local.settings.json. Build bundles BFF dependencies and copies staticwebapp.config.json into dist/. Deploy dist/ + bff/ together, and functions/ separately."
97
+ ? "Use http://localhost:4280 for the app. `swallowkit dev` runs Vite (3000), the managed BFF (7073), standalone Functions (7071), and SWA CLI (4280). SWA forwards /api only to the managed BFF, never directly to standalone Functions. `--no-functions` leaves the BFF running; `--no-swa` removes same-origin routing/auth emulation. BFF local settings belong in bff/local.settings.json. Build bundles BFF dependencies and copies staticwebapp.config.json into dist/. Deploy dist/ + bff/ together, and functions/ separately. Generated home, CRUD, and login pages share the Next.js presentation templates. Preserve their Tailwind styles and the light/dark defaults in src/style.css when editing them."
95
98
  : "Use http://localhost:3000 for the app, or the SWA emulator port (4280) when testing SWA authentication. `swallowkit dev` runs Next.js and standalone Functions (7071). The BFF remains Next.js API routes.",
96
99
  pm: context.packageManager,
97
100
  runCmd,
@@ -41,7 +41,14 @@ When a SwallowKit capability, project structure, or ownership boundary affects
41
41
  a design decision, inspect the current project and the currently available
42
42
  SwallowKit interfaces before deciding.
43
43
 
44
- Prefer the `swallowkit_*` MCP tools when available.
44
+ Prefer the `swallowkit_*` MCP tools when available, with one exception: every
45
+ MCP response reports the SwallowKit version that answered in
46
+ `metadata.swallowkitVersion` and `metadata.mcp`. If that version is older than
47
+ the project's installed SwallowKit (`{{runCmd}} swallowkit --version`), or
48
+ `metadata.warnings` contains `mcp-older-than-project`, its capabilities,
49
+ boundaries, and plan/apply contracts may be outdated for this project. Use
50
+ `{{runCmd}} swallowkit machine ...` instead and follow the response's
51
+ `nextActions` (for example `{{runCmd}} swallowkit configure-mcp`).
45
52
 
46
53
  If MCP is unavailable, use the machine interface:
47
54
 
@@ -217,6 +224,10 @@ required.
217
224
 
218
225
  Never invent or implicitly grant human approval.
219
226
 
227
+ Humans normally invoke `swallowkit provision` directly. Its invocation requests
228
+ execution without an additional confirmation. Agents must still use the
229
+ machine/MCP approval flow and must not switch to normal CLI to bypass it.
230
+
220
231
  ## Model Changes
221
232
 
222
233
  For an existing model change, the normal pattern is:
@@ -263,6 +274,55 @@ SwallowKit should generate framework-owned CRUD artifacts.
263
274
 
264
275
  Do not manually recreate boilerplate that SwallowKit owns.
265
276
 
277
+ ### Persistent models require infrastructure, even with custom APIs
278
+
279
+ Whenever adding a persistent model, execute the installed SwallowKit model
280
+ creation and infrastructure generation workflow, whether or not it has custom
281
+ APIs. A hand-written model alone is not complete.
282
+
283
+ 1. Create the source-of-truth schema with
284
+ `{{runCmd}} swallowkit machine generate model <model> --overwrite never`
285
+ (the machine equivalent of `{{runCmd}} swallowkit create-model <model>`),
286
+ then author its domain fields in `shared/models/` and check its export from
287
+ `shared/index.ts`. Preserve an existing hand-written schema; do not overwrite
288
+ it just to run the template command. Model creation alone does **not**
289
+ generate a Cosmos DB container.
290
+ 2. If generated CRUD is needed, use `machine plan scaffold <model>` →
291
+ `machine apply scaffold --plan <planId>` to derive Functions, BFF, UI,
292
+ OpenAPI/native schema assets as applicable, and the container migration.
293
+ `--api-only` skips UI only; it still generates CRUD Functions and BFF routes.
294
+ If custom APIs replace CRUD, do **not** scaffold unnecessary CRUD. Instead run
295
+ `{{runCmd}} swallowkit migrations add-model <model> --dry-run`, review the
296
+ changes, then `{{runCmd}} swallowkit migrations add-model <model>` to generate
297
+ only the Cosmos DB container migration and its generation records.
298
+ 3. Inspect `machine inspect entities`, `machine inspect infra`,
299
+ `machine inspect artifacts`, and `machine inspect drift`, then run
300
+ `{{runCmd}} swallowkit machine verify project`. Check that the model's
301
+ container name and partition key match the generated Bicep under
302
+ `infra/migrations/`, its `sourceModel` entry in
303
+ `infra/migrations/manifest.json`, and `.swallowkit/artifacts.json`.
304
+ An existing baseline-owned container may need no new migration; verify its
305
+ tracked definition and wiring in `infra/main.bicep` instead. External
306
+ `connectorConfig` models use the configured connector rather than Cosmos DB;
307
+ verify that mapping instead of inventing a Cosmos container.
308
+
309
+ Do not hand-edit the checksum-locked baseline or an existing migration to add
310
+ a container; use the current migration workflow. Generation is local, not Azure
311
+ provisioning. Deployment still follows the provisioning approval gates below.
312
+
313
+ If infrastructure generation must be deferred, state the reason and the pending
314
+ container/migration work explicitly. For CRUD, pass `--skip-infra` to
315
+ `plan scaffold` / `apply scaffold` (MCP `skipInfra: true`). Nothing under `infra/`
316
+ changes and the plan reports `infra-skipped`. Generate the pending migration
317
+ later with `{{runCmd}} swallowkit migrations add-model <model>`. Even if
318
+ `verify project` passes, do not mark the persistent model complete or describe
319
+ the project as deployment-ready while required infrastructure is missing.
320
+
321
+ Treat plan `warnings` as decisions to make, not noise. In particular,
322
+ `user-scoped-data-without-auth` means the model looks per-user (for example a
323
+ `/userId` partition key) while authentication is not configured, so generated
324
+ CRUD would let any caller read and write every document.
325
+
266
326
  ## Authentication
267
327
 
268
328
  Authentication is a **plan/apply operation**, not a free-form config edit.
@@ -300,6 +360,20 @@ custom endpoints that derive the scoping key (e.g. `learnerId`) from the
300
360
  verified principal — never from the request body — and restrict the generated
301
361
  write endpoints to admin roles.
302
362
 
363
+ Configure authentication with `plan auth` / `apply auth` **before** declaring
364
+ `authPolicy`. Without authentication, an explicit policy
365
+ blocks plan/apply/scaffold with `auth-policy-without-auth` before file writes;
366
+ follow `nextActions`, then re-plan. Do not remove a required policy just to pass
367
+ generation.
368
+ An empty `authPolicy = {}` means no explicit policy; it does not enable authentication.
369
+
370
+ With named `auth.schemes`, define `auth.authorization.policies` selecting the
371
+ required schemes and roles, then use `authPolicy = { policy: 'adminOnly' }` (or
372
+ read/write policy names). Role-only declarations do not select a named scheme
373
+ and block with `auth-policy-requires-named-policy`. Conversely, single-provider
374
+ `auth.provider` supports role lists only; a named policy (including a named
375
+ `defaultPolicy`) blocks with `auth-named-policy-requires-named-scheme`.
376
+
303
377
  ## Verification Is a Completion Gate
304
378
 
305
379
  Before treating an agent-driven implementation as complete, run SwallowKit
@@ -311,8 +385,17 @@ verification:
311
385
 
312
386
  or the equivalent MCP operation.
313
387
 
314
- Verification covers SwallowKit structural correctness, drift, type correctness,
315
- and configured project checks.
388
+ Default checks are `structure`, `drift`, `typecheck`, `backend-build`, plus
389
+ configured project checks. `backend-build` checks standalone `functions/`:
390
+ C# uses `dotnet build`, TypeScript uses the project's `tsc --noEmit`, and Python
391
+ uses Python 3 `compileall` (syntax only, not imports or type checking), preferring
392
+ `functions/.venv` over PATH. Missing toolchains are `skip` with an explanation;
393
+ a skipped backend check is **not** evidence that the backend works. Restore the
394
+ toolchain and re-run it before claiming backend validation.
395
+
396
+ Root `build` scripts do not replace standalone backend verification. To include
397
+ frontend production builds, use `--checks "structure,drift,typecheck,backend-build,build"`.
398
+ Quote comma-separated values in PowerShell.
316
399
 
317
400
  When verification fails, use the structured failure explanation:
318
401
 
@@ -359,6 +442,24 @@ Use the `swallowkit-provision` Agent Skill or runbook and never bypass its
359
442
  approval gate. A broad request to deploy does not itself grant the explicit
360
443
  approval required by that workflow.
361
444
 
445
+ Provision applies Bicep once and tracks the original Azure deployment with a
446
+ bounded wait. A local timeout/error, output truncation, or Ctrl+C is not proof
447
+ that Azure failed. `in-progress` means Azure is Running/Accepted; `unknown`
448
+ means its result could not be read; `partial` means Azure succeeded but
449
+ tag/ledger completion is pending. Never re-submit Bicep, reconcile, adopt,
450
+ cancel, or delete just to repair waiting or migration bookkeeping.
451
+
452
+ Retain `.swallowkit/state/provision/` execution checkpoints. Use
453
+ `{{runCmd}} swallowkit machine inspect provision --plan <runId> --wait-seconds 300`
454
+ for read-only status/wait, and after explicit human approval use
455
+ `{{runCmd}} swallowkit machine apply provision --plan <runId> --approve`
456
+ to resume. `runId` equals the original `planId`; fingerprints, subscription,
457
+ deployment identity and migration checks remain in force. Only
458
+ `status: "complete"` / `outcome: "succeeded"` means Azure Succeeded plus verified
459
+ tags and local ledger. Do not print deployment output secrets or raw `az --debug`.
460
+ For older untracked baselines use `plan provision --resume-deployment <name>`
461
+ with original target/regions; it blocks unless ARM/parameter evidence matches.
462
+
362
463
  ## SwallowKit Agent Skills and Runbooks
363
464
 
364
465
  SwallowKit installs task-specific Agent Skills under:
@@ -455,12 +556,24 @@ same generated structure.
455
556
  - Model schema files use `shared/models/{kebab-case}.ts`.
456
557
  - The Zod schema constant and inferred TypeScript type use the same PascalCase
457
558
  name: `export const Todo = z.object(...); export type Todo = z.infer<typeof Todo>`.
458
- - Re-export models from `shared/index.ts`.
559
+ - Re-export models from `shared/index.ts`. create-model and plan/apply scaffold
560
+ append missing exports, including manually authored models. Manual exports
561
+ are allowed; this file has no managed markers and existing content is preserved.
459
562
  - `id` is a required `z.string()`; only `createdAt` / `updatedAt` are optional
460
563
  backend-managed fields.
461
- - Models may declare `partitionKey`, `authPolicy`, `displayName`, and
462
- `connectorConfig` as exported constants. Exact formats:
564
+ - Models may declare `partitionKey`, `authPolicy`, `displayName`,
565
+ `references`, and `connectorConfig` as exported constants. Exact formats:
463
566
  `{{runCmd}} swallowkit machine inspect capabilities` (modelDeclarations).
567
+ - A string field named `<model>Id` is treated as a foreign key only when that
568
+ model exists in `shared/models`. Declare other references explicitly with
569
+ `export const references = { authorId: 'User' };` (map a field to `false`
570
+ to opt out).
571
+ - Native C#/Python schema types come from Zod, not field names: use
572
+ `z.iso.datetime()` / `z.iso.date()` for date values (`createdAt` stays a
573
+ string), `z.number().int()` for integers, and inline `z.object` for nested
574
+ classes. Length/range/regex/item constraints are enforced natively; formats
575
+ such as email remain Zod (BFF) validation. See `inspect capabilities`
576
+ (sharedModels.nativeSchemaMapping).
464
577
  - Cosmos DB containers use PascalCase plural names and default to `/id` as the
465
578
  partition key unless the model declares another key, e.g.
466
579
  `export const partitionKey = '/learnerId';` (the field must exist in the
@@ -517,3 +630,10 @@ Do:
517
630
  - verify before final semantic review
518
631
 
519
632
  Use `{{pm}}`, the package manager selected for this project. Do not introduce another package manager or lockfile. Use `{{runCmd}} swallowkit` for the project-local CLI. The MCP launcher intentionally resolves `latest` independently.
633
+ Exception for prerelease projects: when the project's SwallowKit is newer than
634
+ the published `latest` (for example `2.0.0-alpha.3` while `latest` is `1.1.2`),
635
+ `.mcp.json` may pin `SWALLOWKIT_MCP_VERSION` to the project version, and a
636
+ `latest` launcher that supports it hands the session to the project-installed
637
+ MCP. Run `{{runCmd}} swallowkit configure-mcp` to re-select the version (it
638
+ returns to `latest` once `latest` is at least the project version). Until MCP
639
+ reports the project version, prefer `{{runCmd}} swallowkit machine ...`.
@@ -14,7 +14,9 @@ Always-on rules:
14
14
  - Inspect the current project and SwallowKit capabilities before making
15
15
  SwallowKit-dependent assumptions or asking questions the repository can answer.
16
16
  - Prefer `swallowkit_*` MCP tools.
17
- - Fall back to `{{runCmd}} swallowkit machine ...` when MCP is unavailable.
17
+ - Fall back to `{{runCmd}} swallowkit machine ...` when MCP is unavailable, or
18
+ when an MCP response's `metadata.swallowkitVersion` is older than the project's
19
+ SwallowKit (`metadata.warnings` contains `mcp-older-than-project`).
18
20
  - Inspect responsibility boundaries before editing framework-related files.
19
21
  - Never hand-edit deterministic SwallowKit-managed artifacts.
20
22
  - Add auth schemes only via plan/apply auth; never hand-write `auth.schemes`
@@ -22,7 +24,18 @@ Always-on rules:
22
24
  after apply).
23
25
  - Use plan/apply for deterministic generation.
24
26
  - Respect all `requires-human` states and provisioning approval gates.
27
+ - Normal `swallowkit provision` is for humans. Agents must not use it to bypass
28
+ the machine/MCP approval flow.
29
+ - Provision timeouts/Ctrl+C do not prove Azure failed. Inspect the original
30
+ execution checkpoint with `machine inspect provision --plan <runId>`; resume
31
+ `machine apply provision --plan <runId> --approve` only after explicit human
32
+ approval. Preserve checkpoints; never re-submit Bicep/reconcile/cancel/delete
33
+ to repair waiting or tag/ledger failures. Do not print deployment output secrets.
25
34
  - Run SwallowKit verification before considering implementation complete.
35
+ - Default verification includes `backend-build` for standalone Functions.
36
+ Skipped toolchains are not validation; Python compilation checks syntax only.
37
+ - Configure auth via plan/apply auth before adding `authPolicy`; otherwise
38
+ scaffold blocks before file writes. Scaffold appends missing shared model exports.
26
39
 
27
40
  Task-specific SwallowKit Agent Skills are available under `.github/skills/`.
28
41
  Equivalent agent-agnostic runbooks are available under
@@ -13,7 +13,9 @@ Key rules:
13
13
  - Inspect current SwallowKit capabilities instead of assuming them.
14
14
  - Answer repository- and SwallowKit-inspectable questions before asking the human.
15
15
  - Prefer `swallowkit_*` MCP tools when available.
16
- - Otherwise use `{{runCmd}} swallowkit machine ...`.
16
+ - Otherwise use `{{runCmd}} swallowkit machine ...`. Also use it when an MCP
17
+ response's `metadata.swallowkitVersion` is older than the project's SwallowKit
18
+ or `metadata.warnings` contains `mcp-older-than-project`.
17
19
  - Inspect responsibility boundaries before editing framework-related files.
18
20
  - Never hand-edit deterministic SwallowKit-managed artifacts.
19
21
  - Add auth schemes only via plan/apply auth; never hand-write `auth.schemes`
@@ -21,7 +23,19 @@ Key rules:
21
23
  after apply).
22
24
  - Use plan/apply for deterministic generation.
23
25
  - Respect `requires-human` states and other human approval gates.
26
+ - Normal `swallowkit provision` is a human-facing deployment command. Agents must
27
+ use the machine/MCP approval flow, not normal CLI as an approval bypass.
28
+ - Provision timeouts/Ctrl+C do not prove Azure failed. Read `status`, `outcome`,
29
+ and `nextActions`; inspect the original run with `machine inspect provision
30
+ --plan <runId>`, then resume `machine apply provision --plan <runId> --approve`
31
+ only after explicit human approval. Preserve execution checkpoints; never
32
+ re-submit Bicep or use reconcile/cancel/delete to repair waiting or tag/ledger
33
+ failures. Do not print deployment output secrets.
24
34
  - Run SwallowKit verification before completion.
35
+ - Default verification includes `backend-build` for standalone Functions.
36
+ Skipped toolchains are not validation; Python compilation checks syntax only.
37
+ - Configure auth via plan/apply auth before adding `authPolicy`; otherwise
38
+ scaffold blocks before file writes. Scaffold appends missing shared model exports.
25
39
 
26
40
  Task-specific SwallowKit Agent Skills live under `.github/skills/`.
27
41
  Agent-agnostic equivalents live under `.swallowkit/workflows/`.
@@ -18,9 +18,22 @@ source-of-truth models, subject to the current result of
18
18
  - `createdAt` and `updatedAt` are **optional** string fields
19
19
  (`z.string().optional()`). The backend manages their values.
20
20
  - Export a `displayName` string for UI display.
21
- - Re-export every model from `shared/index.ts`, outside managed markers where
22
- applicable.
21
+ - create-model and plan/apply scaffold append missing model exports to
22
+ `shared/index.ts`, including manually authored models. Manual exports are
23
+ allowed; there are no managed markers and existing content is preserved.
23
24
  - For relationships, use nested schemas rather than duplicating model shapes.
25
+ - For every new persistent model, follow the root `AGENTS.md` persistent-model
26
+ workflow even with custom APIs. Use `{{runCmd}} swallowkit machine generate model <model> --overwrite never`
27
+ (the `create-model` equivalent), preserve existing schemas, and generate the
28
+ required infrastructure. Model creation alone does not create a container.
29
+ Use plan/apply scaffold when CRUD is needed; for custom APIs replacing CRUD,
30
+ review `{{runCmd}} swallowkit migrations add-model <model> --dry-run`, then run
31
+ `{{runCmd}} swallowkit migrations add-model <model>` without unnecessary CRUD.
32
+ Check the model, container Bicep, migration manifest, and artifact ledger
33
+ correspondence, then inspect drift and verify project. For connector models,
34
+ verify the external connector mapping instead of generating a Cosmos container.
35
+ If generation is deferred, state why and what remains; do not claim completion
36
+ or deployment readiness while required infrastructure is missing.
24
37
 
25
38
  ## Optional model declarations (exact formats)
26
39
 
@@ -30,7 +43,7 @@ These are the only declarations SwallowKit parses from a model file:
30
43
  // Cosmos DB partition key (default '/id'). Must reference a schema field.
31
44
  export const partitionKey = '/learnerId';
32
45
 
33
- // Role-based access control on generated CRUD.
46
+ // Role-based access control on generated CRUD (requires plan/apply auth first).
34
47
  export const authPolicy = { roles: ['admin'] };
35
48
  // or: { read: ['user'], write: ['admin'] } or: { policy: 'adminOnly' }
36
49
 
@@ -48,6 +61,13 @@ export const connectorConfig = {
48
61
  The full machine-readable contract:
49
62
  `{{runCmd}} swallowkit machine inspect capabilities`
50
63
 
64
+ An explicit `authPolicy` without authentication blocks plan/apply/scaffold with
65
+ `auth-policy-without-auth` before writing files. Follow `nextActions` to configure
66
+ auth, then re-plan. Do not drop a required guard to bypass the prerequisite.
67
+ For named `auth.schemes`, use named authorization policies selecting schemes
68
+ and roles, referenced by `policy` or read/write names. Role-only declarations
69
+ block with `auth-policy-requires-named-policy` rather than emitting missing helpers.
70
+
51
71
  After changing a model, do not manually patch generated artifacts.
52
72
 
53
73
  ## After changing a model
@@ -10,7 +10,9 @@
10
10
  * - shared: マーカー区切りの共有領域。マーカー内は SwallowKit、外は自由。
11
11
  */
12
12
 
13
+ import { getBackendLanguage } from "../config";
13
14
  import { ArtifactOwnership } from "../operations/file-session";
15
+ import { BackendLanguage } from "../../types";
14
16
  import { inspectArtifacts } from "./artifacts";
15
17
 
16
18
  export type BoundaryZone = "deterministic" | "ai-authored" | "shared";
@@ -48,6 +50,8 @@ export interface BoundaryArtifact {
48
50
  export interface BoundariesContract {
49
51
  contractVersion: number;
50
52
  summary: string;
53
+ /** backend.language the convention rules were resolved for */
54
+ backendLanguage: BackendLanguage;
51
55
  ownershipPolicies: OwnershipPolicy[];
52
56
  /** 台帳に載っていないパスの既定規約 */
53
57
  conventionRules: BoundaryPathRule[];
@@ -82,7 +86,7 @@ export const OWNERSHIP_POLICIES: OwnershipPolicy[] = [
82
86
  zone: "shared",
83
87
  editPolicy: "edit-outside-markers",
84
88
  howToChange:
85
- "SwallowKit appends only inside marked sections (e.g. `# SwallowKit scaffold registrations`). Edit anywhere outside the markers freely; do not remove the markers.",
89
+ "SwallowKit appends at the file-specific extension point: marked sections (e.g. `# SwallowKit scaffold registrations`) or append-only files such as shared/index.ts. Follow the path rule; preserve existing generated entries and any markers.",
86
90
  },
87
91
  {
88
92
  ownership: "metadata",
@@ -92,7 +96,7 @@ export const OWNERSHIP_POLICIES: OwnershipPolicy[] = [
92
96
  },
93
97
  ];
94
98
 
95
- export const CONVENTION_RULES: BoundaryPathRule[] = [
99
+ const COMMON_LEADING_RULES: BoundaryPathRule[] = [
96
100
  {
97
101
  pattern: ".swallowkit/",
98
102
  zone: "deterministic",
@@ -107,32 +111,66 @@ export const CONVENTION_RULES: BoundaryPathRule[] = [
107
111
  "Zod model schemas — the single source of truth. AI/developers author these freely; deterministic generation derives everything else from them.",
108
112
  },
109
113
  {
110
- pattern: "infra/main.bicep",
111
- zone: "shared",
112
- editPolicy: "edit-outside-markers",
113
- description: "SwallowKit inserts container modules; other infrastructure edits are free.",
114
+ pattern: "infra/migrations/manifest.json",
115
+ zone: "deterministic",
116
+ editPolicy: "never-hand-edit",
117
+ description:
118
+ "Infrastructure migration ledger with baseline checksums. Updated by scaffold, `swallowkit migrations add-model`, and `swallowkit create-migration`.",
114
119
  },
115
120
  {
116
- pattern: "functions/function_app.py",
117
- zone: "shared",
118
- editPolicy: "edit-outside-markers",
119
- description: "SwallowKit appends blueprint registrations under its marker; other edits are free.",
121
+ pattern: "infra/migrations/",
122
+ zone: "ai-authored",
123
+ editPolicy: "free-edit",
124
+ description:
125
+ "Versioned Bicep migrations. Edit a migration only before it is provisioned; never change an applied migration — add a new one with `swallowkit create-migration <slug>`.",
120
126
  },
121
127
  {
122
- pattern: "shared/index.ts",
123
- zone: "shared",
124
- editPolicy: "edit-outside-markers",
125
- description: "SwallowKit appends model exports; other exports may be added freely.",
128
+ pattern: "infra/",
129
+ zone: "deterministic",
130
+ editPolicy: "never-hand-edit",
131
+ description:
132
+ "Baseline infrastructure (main.bicep and modules) whose checksums are recorded in infra/migrations/manifest.json. Hand edits block scaffold with baseline-drift; add resources through a new migration instead.",
126
133
  },
127
134
  {
128
- pattern: "*",
129
- zone: "ai-authored",
135
+ pattern: "shared/index.ts",
136
+ zone: "shared",
130
137
  editPolicy: "free-edit",
131
- description:
132
- "Any path not recorded in the artifact ledger is AI/developer-authored. Business logic, custom pages, custom Functions, and tests belong here.",
138
+ description: "create-model and scaffold append missing model exports while preserving existing content. No managed markers; manual exports are allowed. Keep exports needed by generated code.",
133
139
  },
134
140
  ];
135
141
 
142
+ /** Backend files that SwallowKit appends to; C# and TypeScript discover functions without a registration file. */
143
+ const BACKEND_EXTENSION_RULES: Record<BackendLanguage, BoundaryPathRule[]> = {
144
+ python: [
145
+ {
146
+ pattern: "functions/function_app.py",
147
+ zone: "shared",
148
+ editPolicy: "edit-outside-markers",
149
+ description: "SwallowKit appends blueprint registrations under its marker; other edits are free.",
150
+ },
151
+ {
152
+ pattern: "functions/requirements.txt",
153
+ zone: "shared",
154
+ editPolicy: "free-edit",
155
+ description: "SwallowKit appends connector driver requirements when connector models are scaffolded; keep those lines and edit other requirements freely.",
156
+ },
157
+ ],
158
+ csharp: [],
159
+ typescript: [],
160
+ };
161
+
162
+ const FALLBACK_RULE: BoundaryPathRule = {
163
+ pattern: "*",
164
+ zone: "ai-authored",
165
+ editPolicy: "free-edit",
166
+ description:
167
+ "Any path not recorded in the artifact ledger is AI/developer-authored. Business logic, custom pages, custom Functions, and tests belong here.",
168
+ };
169
+
170
+ export function buildConventionRules(backendLanguage: BackendLanguage): BoundaryPathRule[] {
171
+ return [...COMMON_LEADING_RULES, ...BACKEND_EXTENSION_RULES[backendLanguage], FALLBACK_RULE];
172
+ }
173
+
136
174
  const POLICY_BY_OWNERSHIP = new Map(OWNERSHIP_POLICIES.map((policy) => [policy.ownership, policy] as const));
137
175
 
138
176
  export const BOUNDARY_GUIDANCE: string[] = [
@@ -143,7 +181,10 @@ export const BOUNDARY_GUIDANCE: string[] = [
143
181
  "Run `swallowkit machine verify project` after applying changes; use `explain failure` to get repair evidence.",
144
182
  ];
145
183
 
146
- export function inspectBoundaries(projectRoot: string = process.cwd()): BoundariesContract {
184
+ export function inspectBoundaries(
185
+ projectRoot: string = process.cwd(),
186
+ backendLanguage: BackendLanguage = getBackendLanguage()
187
+ ): BoundariesContract {
147
188
  const inspected = inspectArtifacts(projectRoot);
148
189
 
149
190
  const artifacts: BoundaryArtifact[] = inspected.artifacts.map((artifact) => {
@@ -162,8 +203,9 @@ export function inspectBoundaries(projectRoot: string = process.cwd()): Boundari
162
203
  contractVersion: 1,
163
204
  summary:
164
205
  "SwallowKit separates deterministic generation (models → CRUD/BFF/UI/infra via plan/apply) from AI free-form authoring (models, business logic, custom code). This contract tells agents which files belong to which side.",
206
+ backendLanguage,
165
207
  ownershipPolicies: OWNERSHIP_POLICIES,
166
- conventionRules: CONVENTION_RULES,
208
+ conventionRules: buildConventionRules(backendLanguage),
167
209
  artifacts,
168
210
  guidance: BOUNDARY_GUIDANCE,
169
211
  };
@@ -53,6 +53,7 @@ export interface CapabilitiesContract {
53
53
  sharedModels: {
54
54
  idFieldRule: string;
55
55
  buildNote: string;
56
+ nativeSchemaMapping: string[];
56
57
  };
57
58
  seeding: {
58
59
  createTemplates: string;
@@ -60,10 +61,19 @@ export interface CapabilitiesContract {
60
61
  notes: string[];
61
62
  };
62
63
  machineCommands: string[];
64
+ provisioning: {
65
+ execution: string;
66
+ completion: string;
67
+ tracking: string;
68
+ recovery: string;
69
+ diagnostics: string;
70
+ approval: string;
71
+ };
63
72
  verifyChecks: {
64
73
  defaultChecks: string[];
65
74
  optInChecks: string[];
66
75
  customChecks: string;
76
+ backendBuild: string;
67
77
  };
68
78
  }
69
79
 
@@ -108,6 +118,19 @@ export function inspectCapabilities(): CapabilitiesContract {
108
118
  "Role-based access control metadata applied to the generated CRUD Functions. `roles` guards all operations; `read`/`write` guard per-operation; `policy` references a named authorization policy from swallowkit.config auth.authorization.policies.",
109
119
  format:
110
120
  "export const authPolicy = { roles: ['admin'] };\n// or per-operation:\nexport const authPolicy = { read: ['user'], write: ['admin'] };\n// or a named policy:\nexport const authPolicy = { policy: 'adminOnly' };",
121
+ notes: [
122
+ "An explicit authPolicy without configured authentication blocks plan/apply/generate scaffold with auth-policy-without-auth before any artifacts are written. Run plan auth, apply auth, then re-plan scaffold. An empty {} declaration keeps the existing behavior: no explicit policy.",
123
+ "With named auth.schemes, define auth.authorization.policies selecting schemes and roles, then reference them via policy or read/write names. A role-only declaration cannot select a named scheme and blocks with auth-policy-requires-named-policy; it is supported by legacy single-provider authentication.",
124
+ "Conversely, single-provider authentication (auth.provider) supports role lists only. Referencing a named policy (authPolicy.policy, read/write names, or a named auth.authorization.defaultPolicy) blocks with auth-named-policy-requires-named-scheme; add a named scheme first.",
125
+ ],
126
+ },
127
+ {
128
+ name: "references",
129
+ required: false,
130
+ description:
131
+ "Explicit foreign keys used by generated UI lookups. Without it, a string field named <model>Id is treated as a foreign key only when shared/models contains that model (userId -> User only if user.ts exists). Map a field to false to disable inference. References to missing models are ignored with a reference-model-not-found warning.",
132
+ format: "export const references = { authorId: 'User', legacyId: false };",
133
+ notes: ["Only single string id fields can reference a model.", "No lookup UI, fetch, or OpenAPI reference is generated for fields that do not reference an existing model."],
111
134
  },
112
135
  {
113
136
  name: "connectorConfig",
@@ -174,15 +197,24 @@ export function inspectCapabilities(): CapabilitiesContract {
174
197
  ],
175
198
  notGuaranteed: [
176
199
  "Owner scoping: generated CRUD does NOT restrict rows to the authenticated principal. Any authenticated caller passing the policy can read/write any document.",
200
+ "Without authentication, plan scaffold reports user-scoped-data-without-auth when the partition key or an owner-like field (userId, learnerId, ownerId, ...) suggests per-user data.",
177
201
  ],
178
202
  guidance: [
179
- "For multi-user data where users may only touch their own records, add ai-authored custom endpoints that derive the scoping key (e.g. learnerId) from the verified principal — never from the request body — and restrict generated write endpoints to admin roles or disable them.",
203
+ "Configure authentication via plan/apply auth before declaring authPolicy. For multi-user data where users may only touch their own records, add ai-authored custom endpoints that derive the scoping key (e.g. learnerId) from the verified principal — never from the request body — and restrict generated write endpoints to admin roles or disable them.",
180
204
  ],
181
205
  },
182
206
  sharedModels: {
183
207
  idFieldRule: "id: z.string() (required). createdAt/updatedAt: z.string().optional(). The backend owns their values.",
208
+ nativeSchemaMapping: [
209
+ "C#/Python schema assets derive types from Zod, never from field names: z.string() -> string/str (including createdAt/updatedAt).",
210
+ "Date types only when declared: z.iso.datetime() -> DateTime/datetime, z.iso.date() -> DateOnly/date, z.date() -> DateTime/datetime.",
211
+ "z.number() -> double / float|int; z.number().int() or z.int() -> long / int.",
212
+ "Inline z.object({...}) fields become named classes <Model><Field> (e.g. ProbeItemNested); imported model schemas keep their own class.",
213
+ "min/max/length/nonempty/regex/int/gt/gte/lt/lte/positive/nonnegative and array min/max are enforced by C# IValidatableObject.Validate and Python Field bounds/validators. Regexes use search semantics like Zod.",
214
+ "String formats (email/uuid/url), refinements, and transforms are not re-implemented natively; the BFF Zod schemas remain the authoritative validation.",
215
+ ],
184
216
  buildNote:
185
- "verify typecheck resolves the shared package from its built dist/. SwallowKit rebuilds shared automatically during verify; when typechecking manually, build the shared package first (errors like \"no exported member\" usually mean a stale dist).",
217
+ "create-model and plan/apply scaffold append missing model exports to shared/index.ts, including manually authored models. Manual exports are allowed (no markers); existing content is preserved. verify typecheck resolves the shared package from its built dist/. SwallowKit rebuilds shared automatically during verify; when typechecking manually, build shared first.",
186
218
  },
187
219
  seeding: {
188
220
  createTemplates: "swallowkit create-dev-seeds <environment> — writes dev-seeds/<environment>/<model>.json templates.",
@@ -190,18 +222,29 @@ export function inspectCapabilities(): CapabilitiesContract {
190
222
  notes: ["Editing dev-seeds/*.json alone does nothing; seeds are only applied via dev --seed-env."],
191
223
  },
192
224
  machineCommands: [
193
- "inspect project | entities | routes | artifacts | boundaries | infra | drift | capabilities",
225
+ "inspect project | entities | routes | artifacts | boundaries | infra | drift | capabilities; inspect provision --plan <runId> [--wait-seconds <0-3600>]",
194
226
  "validate project",
195
227
  "generate model <names...> | generate scaffold <model>",
196
- "plan scaffold <models...> | plan auth --provider <p> [--scheme <name>] [--allowed-providers <csv>] | plan provision -g <rg> --location <loc> --swa-location <loc> [--adopt-existing --baseline 0 --what-if] [--reconcile --what-if]",
197
- "apply scaffold [models...] --plan <id> [--approve] | apply auth --plan <id> [--approve] | apply provision --plan <id> --approve",
228
+ "plan scaffold <models...> [--api-only] [--skip-infra] | plan auth --provider <p> [--scheme <name>] [--allowed-providers <csv>] | plan provision -g <rg> --location <loc> --swa-location <loc> [--adopt-existing --baseline 0 --what-if] [--reconcile --what-if] [--resume-deployment <name>]",
229
+ "apply scaffold [models...] --plan <id> [--approve] [--skip-infra] | apply auth --plan <id> [--approve] | apply provision --plan <id> --approve [--wait-seconds <0-3600>] (also resumes the same execution checkpoint)",
198
230
  "verify project [--checks <ids>] [--compact]",
199
231
  "explain failure [--check <id>]",
232
+ "(regular CLI) migrations add-model <model> [--dry-run] — generate only the container migration after scaffold --skip-infra",
233
+ "(regular CLI) configure-mcp [--version auto|latest|<semver>] — re-select the MCP launcher version in .mcp.json",
200
234
  ],
235
+ provisioning: {
236
+ execution: "Submit Bicep once with az deployment group create --no-wait, then bounded state polling (default 300 seconds, configurable 0-3600) for machine/MCP; the human `swallowkit provision` command waits until Azure reaches a terminal state. Azure CLI invocations are bounded separately. Warning-only stderr with exit 0 is not a failure; output capture limits do not terminate az.",
237
+ completion: "status complete/outcome succeeded requires Azure Succeeded plus verified migration tags and local ledger completion. Running/Accepted -> in-progress; unreadable/not-found state -> blocked/outcome unknown; bookkeeping interruption after Azure Succeeded -> blocked/outcome partial; Failed/Canceled -> failed with Azure causes.",
238
+ tracking: "Approved runs persist before Azure writes under .swallowkit/state/provision/. runId equals the original planId and preserves the subscription, RG, deployment ID/correlation, fingerprints and migration state. inspect provision is read-only; apply provision --plan resumes without re-submitting attempted deployments. Ctrl+C/termination may leave Azure running; never cancel/delete without explicit consent.",
239
+ recovery: "For an older untracked baseline, plan provision --resume-deployment <name> compares the existing ARM template and non-secure parameters to the local Bicep/parameters. It observes that deployment and only tags/records it after Succeeded. Mismatches, unreadable evidence, secure parameters or non-baseline migrations block; do not use reconcile just to repair bookkeeping.",
240
+ diagnostics: "Machine/MCP results include bounded/redacted stdout/stderr, omitted-output flags, exit code, signal, failure kind, elapsed time and deployment identity, but no deployment outputs. Normal CLI shows named resource information and CI/CD setup guidance after success. Never print --debug output, keys, tokens or connection strings.",
241
+ approval: "Machine/MCP initial apply and every resume require explicit human approval. A human invoking normal provision or provision --resume explicitly requests execution without another confirmation prompt. Agents must not switch to normal CLI to bypass approval. A passing local command or an ok envelope is not proof of completed Azure provisioning; inspect status, outcome and nextActions.",
242
+ },
201
243
  verifyChecks: {
202
- defaultChecks: ["structure", "drift", "typecheck"],
244
+ defaultChecks: ["structure", "drift", "typecheck", "backend-build"],
203
245
  optInChecks: ["build", "lint", "test"],
204
246
  customChecks: "swallowkit.config verify.checks: [{ id, command, title?, timeoutMs? }]",
247
+ backendBuild: "Runs dotnet build in functions/ (C#), the project tsc --noEmit (TypeScript), or Python 3 compileall (syntax only, using functions/.venv before PATH). Missing toolchains are skip with a reason, not proof of validation. Root build scripts do not replace backend-build; use --checks \"structure,drift,typecheck,backend-build,build\" for both.",
205
248
  },
206
249
  };
207
250
  }