swallowkit 2.0.0-alpha.1 → 2.0.0-alpha.10

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 +53 -7
  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 +5 -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 +89 -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 +11 -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 +53 -7
  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,18 @@ SwallowKit should generate framework-owned CRUD artifacts.
263
274
 
264
275
  Do not manually recreate boilerplate that SwallowKit owns.
265
276
 
277
+ When the task must not change Bicep or other infrastructure, still scaffold the
278
+ model: pass `--skip-infra` to `plan scaffold` / `apply scaffold` (MCP
279
+ `skipInfra: true`, or `swallowkit scaffold --skip-infra`). Nothing under
280
+ `infra/` changes, the plan reports `infra-skipped`, and `verify project` still
281
+ passes. Generate only the pending container migration later with
282
+ `{{runCmd}} swallowkit migrations add-model <model>`.
283
+
284
+ Treat plan `warnings` as decisions to make, not noise. In particular,
285
+ `user-scoped-data-without-auth` means the model looks per-user (for example a
286
+ `/userId` partition key) while authentication is not configured, so generated
287
+ CRUD would let any caller read and write every document.
288
+
266
289
  ## Authentication
267
290
 
268
291
  Authentication is a **plan/apply operation**, not a free-form config edit.
@@ -300,6 +323,20 @@ custom endpoints that derive the scoping key (e.g. `learnerId`) from the
300
323
  verified principal — never from the request body — and restrict the generated
301
324
  write endpoints to admin roles.
302
325
 
326
+ Configure authentication with `plan auth` / `apply auth` **before** declaring
327
+ `authPolicy`. Without authentication, an explicit policy
328
+ blocks plan/apply/scaffold with `auth-policy-without-auth` before file writes;
329
+ follow `nextActions`, then re-plan. Do not remove a required policy just to pass
330
+ generation.
331
+ An empty `authPolicy = {}` means no explicit policy; it does not enable authentication.
332
+
333
+ With named `auth.schemes`, define `auth.authorization.policies` selecting the
334
+ required schemes and roles, then use `authPolicy = { policy: 'adminOnly' }` (or
335
+ read/write policy names). Role-only declarations do not select a named scheme
336
+ and block with `auth-policy-requires-named-policy`. Conversely, single-provider
337
+ `auth.provider` supports role lists only; a named policy (including a named
338
+ `defaultPolicy`) blocks with `auth-named-policy-requires-named-scheme`.
339
+
303
340
  ## Verification Is a Completion Gate
304
341
 
305
342
  Before treating an agent-driven implementation as complete, run SwallowKit
@@ -311,8 +348,17 @@ verification:
311
348
 
312
349
  or the equivalent MCP operation.
313
350
 
314
- Verification covers SwallowKit structural correctness, drift, type correctness,
315
- and configured project checks.
351
+ Default checks are `structure`, `drift`, `typecheck`, `backend-build`, plus
352
+ configured project checks. `backend-build` checks standalone `functions/`:
353
+ C# uses `dotnet build`, TypeScript uses the project's `tsc --noEmit`, and Python
354
+ uses Python 3 `compileall` (syntax only, not imports or type checking), preferring
355
+ `functions/.venv` over PATH. Missing toolchains are `skip` with an explanation;
356
+ a skipped backend check is **not** evidence that the backend works. Restore the
357
+ toolchain and re-run it before claiming backend validation.
358
+
359
+ Root `build` scripts do not replace standalone backend verification. To include
360
+ frontend production builds, use `--checks "structure,drift,typecheck,backend-build,build"`.
361
+ Quote comma-separated values in PowerShell.
316
362
 
317
363
  When verification fails, use the structured failure explanation:
318
364
 
@@ -359,6 +405,24 @@ Use the `swallowkit-provision` Agent Skill or runbook and never bypass its
359
405
  approval gate. A broad request to deploy does not itself grant the explicit
360
406
  approval required by that workflow.
361
407
 
408
+ Provision applies Bicep once and tracks the original Azure deployment with a
409
+ bounded wait. A local timeout/error, output truncation, or Ctrl+C is not proof
410
+ that Azure failed. `in-progress` means Azure is Running/Accepted; `unknown`
411
+ means its result could not be read; `partial` means Azure succeeded but
412
+ tag/ledger completion is pending. Never re-submit Bicep, reconcile, adopt,
413
+ cancel, or delete just to repair waiting or migration bookkeeping.
414
+
415
+ Retain `.swallowkit/state/provision/` execution checkpoints. Use
416
+ `{{runCmd}} swallowkit machine inspect provision --plan <runId> --wait-seconds 300`
417
+ for read-only status/wait, and after explicit human approval use
418
+ `{{runCmd}} swallowkit machine apply provision --plan <runId> --approve`
419
+ to resume. `runId` equals the original `planId`; fingerprints, subscription,
420
+ deployment identity and migration checks remain in force. Only
421
+ `status: "complete"` / `outcome: "succeeded"` means Azure Succeeded plus verified
422
+ tags and local ledger. Do not print deployment output secrets or raw `az --debug`.
423
+ For older untracked baselines use `plan provision --resume-deployment <name>`
424
+ with original target/regions; it blocks unless ARM/parameter evidence matches.
425
+
362
426
  ## SwallowKit Agent Skills and Runbooks
363
427
 
364
428
  SwallowKit installs task-specific Agent Skills under:
@@ -455,12 +519,24 @@ same generated structure.
455
519
  - Model schema files use `shared/models/{kebab-case}.ts`.
456
520
  - The Zod schema constant and inferred TypeScript type use the same PascalCase
457
521
  name: `export const Todo = z.object(...); export type Todo = z.infer<typeof Todo>`.
458
- - Re-export models from `shared/index.ts`.
522
+ - Re-export models from `shared/index.ts`. create-model and plan/apply scaffold
523
+ append missing exports, including manually authored models. Manual exports
524
+ are allowed; this file has no managed markers and existing content is preserved.
459
525
  - `id` is a required `z.string()`; only `createdAt` / `updatedAt` are optional
460
526
  backend-managed fields.
461
- - Models may declare `partitionKey`, `authPolicy`, `displayName`, and
462
- `connectorConfig` as exported constants. Exact formats:
527
+ - Models may declare `partitionKey`, `authPolicy`, `displayName`,
528
+ `references`, and `connectorConfig` as exported constants. Exact formats:
463
529
  `{{runCmd}} swallowkit machine inspect capabilities` (modelDeclarations).
530
+ - A string field named `<model>Id` is treated as a foreign key only when that
531
+ model exists in `shared/models`. Declare other references explicitly with
532
+ `export const references = { authorId: 'User' };` (map a field to `false`
533
+ to opt out).
534
+ - Native C#/Python schema types come from Zod, not field names: use
535
+ `z.iso.datetime()` / `z.iso.date()` for date values (`createdAt` stays a
536
+ string), `z.number().int()` for integers, and inline `z.object` for nested
537
+ classes. Length/range/regex/item constraints are enforced natively; formats
538
+ such as email remain Zod (BFF) validation. See `inspect capabilities`
539
+ (sharedModels.nativeSchemaMapping).
464
540
  - Cosmos DB containers use PascalCase plural names and default to `/id` as the
465
541
  partition key unless the model declares another key, e.g.
466
542
  `export const partitionKey = '/learnerId';` (the field must exist in the
@@ -517,3 +593,10 @@ Do:
517
593
  - verify before final semantic review
518
594
 
519
595
  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.
596
+ Exception for prerelease projects: when the project's SwallowKit is newer than
597
+ the published `latest` (for example `2.0.0-alpha.3` while `latest` is `1.1.2`),
598
+ `.mcp.json` may pin `SWALLOWKIT_MCP_VERSION` to the project version, and a
599
+ `latest` launcher that supports it hands the session to the project-installed
600
+ MCP. Run `{{runCmd}} swallowkit configure-mcp` to re-select the version (it
601
+ returns to `latest` once `latest` is at least the project version). Until MCP
602
+ 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,8 +18,9 @@ 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.
24
25
 
25
26
  ## Optional model declarations (exact formats)
@@ -30,7 +31,7 @@ These are the only declarations SwallowKit parses from a model file:
30
31
  // Cosmos DB partition key (default '/id'). Must reference a schema field.
31
32
  export const partitionKey = '/learnerId';
32
33
 
33
- // Role-based access control on generated CRUD.
34
+ // Role-based access control on generated CRUD (requires plan/apply auth first).
34
35
  export const authPolicy = { roles: ['admin'] };
35
36
  // or: { read: ['user'], write: ['admin'] } or: { policy: 'adminOnly' }
36
37
 
@@ -48,6 +49,13 @@ export const connectorConfig = {
48
49
  The full machine-readable contract:
49
50
  `{{runCmd}} swallowkit machine inspect capabilities`
50
51
 
52
+ An explicit `authPolicy` without authentication blocks plan/apply/scaffold with
53
+ `auth-policy-without-auth` before writing files. Follow `nextActions` to configure
54
+ auth, then re-plan. Do not drop a required guard to bypass the prerequisite.
55
+ For named `auth.schemes`, use named authorization policies selecting schemes
56
+ and roles, referenced by `policy` or read/write names. Role-only declarations
57
+ block with `auth-policy-requires-named-policy` rather than emitting missing helpers.
58
+
51
59
  After changing a model, do not manually patch generated artifacts.
52
60
 
53
61
  ## 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
  }