@intentius/chant-lexicon-docker 0.124.21 → 0.124.23

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 (119) hide show
  1. package/dist/codegen/docs.d.ts.map +1 -1
  2. package/dist/codegen/generate.d.ts.map +1 -1
  3. package/dist/dockerfile-order.d.ts +13 -0
  4. package/dist/dockerfile-order.d.ts.map +1 -0
  5. package/dist/generated/index.d.ts +703 -6
  6. package/dist/generated/index.d.ts.map +1 -1
  7. package/dist/import/adapter.d.ts.map +1 -1
  8. package/dist/import/parser.d.ts +23 -0
  9. package/dist/import/parser.d.ts.map +1 -1
  10. package/dist/integrity.json +17 -8
  11. package/dist/lint/audit-catalog.d.ts.map +1 -1
  12. package/dist/lint/audit-lineage.d.ts.map +1 -1
  13. package/dist/lint/post-synth/add-url-checksum.d.ts +9 -0
  14. package/dist/lint/post-synth/add-url-checksum.d.ts.map +1 -0
  15. package/dist/lint/post-synth/apt-update-alone.d.ts +10 -0
  16. package/dist/lint/post-synth/apt-update-alone.d.ts.map +1 -0
  17. package/dist/lint/post-synth/cache-busting-copy.d.ts +11 -0
  18. package/dist/lint/post-synth/cache-busting-copy.d.ts.map +1 -0
  19. package/dist/lint/post-synth/copy-from-stage.d.ts +10 -0
  20. package/dist/lint/post-synth/copy-from-stage.d.ts.map +1 -0
  21. package/dist/lint/post-synth/docker-helpers.d.ts +35 -0
  22. package/dist/lint/post-synth/docker-helpers.d.ts.map +1 -1
  23. package/dist/lint/post-synth/index.d.ts.map +1 -1
  24. package/dist/lint/post-synth/no-root-user.d.ts +3 -2
  25. package/dist/lint/post-synth/no-root-user.d.ts.map +1 -1
  26. package/dist/lint/post-synth/relative-workdir.d.ts +10 -0
  27. package/dist/lint/post-synth/relative-workdir.d.ts.map +1 -0
  28. package/dist/lint/post-synth/repeated-cmd.d.ts +9 -0
  29. package/dist/lint/post-synth/repeated-cmd.d.ts.map +1 -0
  30. package/dist/lint/post-synth/root-after-user.d.ts +10 -0
  31. package/dist/lint/post-synth/root-after-user.d.ts.map +1 -0
  32. package/dist/lint/post-synth/unused-global-arg.d.ts +10 -0
  33. package/dist/lint/post-synth/unused-global-arg.d.ts.map +1 -0
  34. package/dist/lint/rules/index.d.ts +1 -0
  35. package/dist/lint/rules/index.d.ts.map +1 -1
  36. package/dist/lint/rules/per-kind-order.d.ts +15 -0
  37. package/dist/lint/rules/per-kind-order.d.ts.map +1 -0
  38. package/dist/manifest.json +1 -1
  39. package/dist/meta.json +444 -86
  40. package/dist/okf/index.md +10 -1
  41. package/dist/okf/rules/DKRD012.md +2 -2
  42. package/dist/okf/rules/DKRD013.md +11 -0
  43. package/dist/okf/rules/DKRD014.md +11 -0
  44. package/dist/okf/rules/DKRD015.md +11 -0
  45. package/dist/okf/rules/DKRD016.md +11 -0
  46. package/dist/okf/rules/DKRD017.md +11 -0
  47. package/dist/okf/rules/DKRD018.md +11 -0
  48. package/dist/okf/rules/DKRD019.md +11 -0
  49. package/dist/okf/rules/DKRD020.md +11 -0
  50. package/dist/okf/rules/DKRS002.md +15 -0
  51. package/dist/okf/types/DockerConfig.md +7 -5
  52. package/dist/okf/types/DockerSecret.md +8 -4
  53. package/dist/okf/types/Dockerfile.md +4 -1
  54. package/dist/okf/types/Network.md +10 -6
  55. package/dist/okf/types/Service.md +93 -15
  56. package/dist/okf/types/Volume.md +5 -5
  57. package/dist/plugin.d.ts.map +1 -1
  58. package/dist/rules/add-url-checksum.ts +38 -0
  59. package/dist/rules/apt-update-alone.ts +39 -0
  60. package/dist/rules/cache-busting-copy.ts +65 -0
  61. package/dist/rules/copy-from-stage.ts +54 -0
  62. package/dist/rules/docker-helpers.ts +80 -0
  63. package/dist/rules/no-root-user.ts +19 -17
  64. package/dist/rules/per-kind-order.ts +130 -0
  65. package/dist/rules/relative-workdir.ts +38 -0
  66. package/dist/rules/repeated-cmd.ts +35 -0
  67. package/dist/rules/root-after-user.ts +44 -0
  68. package/dist/rules/unused-global-arg.ts +38 -0
  69. package/dist/serializer.d.ts.map +1 -1
  70. package/dist/skills/chant-docker-patterns.md +93 -24
  71. package/dist/skills/chant-docker.md +43 -16
  72. package/dist/spec/parse-compose.d.ts +29 -2
  73. package/dist/spec/parse-compose.d.ts.map +1 -1
  74. package/dist/spec/parse-engine.d.ts +9 -0
  75. package/dist/spec/parse-engine.d.ts.map +1 -1
  76. package/dist/types/index.d.ts +344 -41
  77. package/package.json +3 -3
  78. package/src/codegen/__snapshots__/okf.test.ts.snap +278 -39
  79. package/src/codegen/docs.ts +14 -0
  80. package/src/codegen/generate.ts +128 -31
  81. package/src/codegen/okf.test.ts +1 -1
  82. package/src/dockerfile-order.ts +20 -0
  83. package/src/docs-examples.test.ts +141 -0
  84. package/src/generated/index.d.ts +344 -41
  85. package/src/generated/index.ts +396 -6
  86. package/src/generated/lexicon-docker.json +444 -86
  87. package/src/import/adapter.ts +8 -2
  88. package/src/import/generator.test.ts +4 -4
  89. package/src/import/generator.ts +53 -37
  90. package/src/import/parser.ts +82 -13
  91. package/src/import/roundtrip.test.ts +167 -2
  92. package/src/import/testdata/configs-secrets.yaml +15 -0
  93. package/src/lint/audit-catalog.ts +9 -1
  94. package/src/lint/audit-lineage.ts +14 -0
  95. package/src/lint/post-synth/add-url-checksum.ts +38 -0
  96. package/src/lint/post-synth/apt-update-alone.ts +39 -0
  97. package/src/lint/post-synth/cache-busting-copy.ts +65 -0
  98. package/src/lint/post-synth/copy-from-stage.ts +54 -0
  99. package/src/lint/post-synth/docker-helpers.ts +80 -0
  100. package/src/lint/post-synth/index.ts +16 -0
  101. package/src/lint/post-synth/no-root-user.ts +19 -17
  102. package/src/lint/post-synth/post-synth.test.ts +149 -0
  103. package/src/lint/post-synth/relative-workdir.ts +38 -0
  104. package/src/lint/post-synth/repeated-cmd.ts +35 -0
  105. package/src/lint/post-synth/root-after-user.ts +44 -0
  106. package/src/lint/post-synth/unused-global-arg.ts +38 -0
  107. package/src/lint/rules/index.ts +1 -0
  108. package/src/lint/rules/per-kind-order.ts +130 -0
  109. package/src/lint/rules/rules.test.ts +88 -0
  110. package/src/plugin.test.ts +4 -0
  111. package/src/plugin.ts +2 -1
  112. package/src/serializer.test.ts +112 -0
  113. package/src/serializer.ts +58 -11
  114. package/src/skills/chant-docker-patterns.md +93 -24
  115. package/src/skills/chant-docker.md +43 -16
  116. package/src/spec/parse-compose.ts +167 -95
  117. package/src/spec/parse-engine.ts +17 -5
  118. package/src/typecheck.e2e.test.ts +107 -0
  119. package/src/typed-props.test.ts +60 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-docker",
3
- "version": "0.124.21",
3
+ "version": "0.124.23",
4
4
  "description": "Docker lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -63,13 +63,13 @@
63
63
  "build": "../../scripts/tsc7.sh -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
64
64
  },
65
65
  "dependencies": {
66
- "@intentius/chant-lexicon-otel": "^0.124.21"
66
+ "@intentius/chant-lexicon-otel": "^0.124.23"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@intentius/chant": "*",
70
70
  "typescript": "^5.9.3"
71
71
  },
72
72
  "peerDependencies": {
73
- "@intentius/chant": "^0.124.21"
73
+ "@intentius/chant": "^0.124.23"
74
74
  }
75
75
  }
@@ -23,8 +23,17 @@ okf_version: '0.2'
23
23
  * [DKRD003](/rules/DKRD003.md) - Service exposes SSH port (22) externally — this is a security risk
24
24
  * [DKRD010](/rules/DKRD010.md) - apt-get install without --no-install-recommends adds unnecessary packages
25
25
  * [DKRD011](/rules/DKRD011.md) - Prefer COPY over ADD when not fetching URLs or extracting archives
26
- * [DKRD012](/rules/DKRD012.md) - Dockerfile has no USER instruction — container runs as root
26
+ * [DKRD012](/rules/DKRD012.md) - Dockerfile's final stage has no USER instruction, or ends on USER root — container runs as root
27
+ * [DKRD013](/rules/DKRD013.md) - Whole build context copied before a dependency install — every source change re-runs the install
28
+ * [DKRD014](/rules/DKRD014.md) - RUN needs root but comes after USER switched to a non-root user
29
+ * [DKRD015](/rules/DKRD015.md) - More than one CMD or ENTRYPOINT in a stage — only the last one takes effect
30
+ * [DKRD016](/rules/DKRD016.md) - COPY --from names a stage that is not defined before it
31
+ * [DKRD017](/rules/DKRD017.md) - ARG before the first FROM is not used by any FROM or stage
32
+ * [DKRD018](/rules/DKRD018.md) - Relative WORKDIR before any absolute WORKDIR in the stage
33
+ * [DKRD019](/rules/DKRD019.md) - ADD fetches a remote URL without --checksum
34
+ * [DKRD020](/rules/DKRD020.md) - apt-get update in a different RUN from apt-get install — the install can use a stale package index
27
35
  * [DKRS001](/rules/DKRS001.md) - No Latest Tag
36
+ * [DKRS002](/rules/DKRS002.md) - Per-kind Dockerfile fields written in a different order
28
37
  ",
29
38
  "path": "index.md",
30
39
  },
@@ -119,14 +128,14 @@ Prefer COPY over ADD when not fetching URLs or extracting archives
119
128
  "content": "---
120
129
  type: post-synth-check
121
130
  title: DKRD012
122
- description: Dockerfile has no USER instruction — container runs as root
131
+ description: Dockerfile's final stage has no USER instruction, or ends on USER root — container runs as root
123
132
  id: DKRD012
124
133
  severity: error
125
134
  category: post-synth
126
135
  lexicon: docker
127
136
  docs: https://intentius.io/chant/lexicons/docker/rules/
128
137
  ---
129
- Dockerfile has no USER instruction — container runs as root
138
+ Dockerfile's final stage has no USER instruction, or ends on USER root — container runs as root
130
139
 
131
140
  ## Applies to
132
141
 
@@ -136,6 +145,126 @@ Dockerfile has no USER instruction — container runs as root
136
145
  },
137
146
  {
138
147
  "content": "---
148
+ type: post-synth-check
149
+ title: DKRD013
150
+ description: Whole build context copied before a dependency install — every source change re-runs the install
151
+ id: DKRD013
152
+ severity: error
153
+ category: post-synth
154
+ lexicon: docker
155
+ docs: https://intentius.io/chant/lexicons/docker/rules/
156
+ ---
157
+ Whole build context copied before a dependency install — every source change re-runs the install
158
+ ",
159
+ "path": "rules/DKRD013.md",
160
+ },
161
+ {
162
+ "content": "---
163
+ type: post-synth-check
164
+ title: DKRD014
165
+ description: RUN needs root but comes after USER switched to a non-root user
166
+ id: DKRD014
167
+ severity: error
168
+ category: post-synth
169
+ lexicon: docker
170
+ docs: https://intentius.io/chant/lexicons/docker/rules/
171
+ ---
172
+ RUN needs root but comes after USER switched to a non-root user
173
+ ",
174
+ "path": "rules/DKRD014.md",
175
+ },
176
+ {
177
+ "content": "---
178
+ type: post-synth-check
179
+ title: DKRD015
180
+ description: More than one CMD or ENTRYPOINT in a stage — only the last one takes effect
181
+ id: DKRD015
182
+ severity: error
183
+ category: post-synth
184
+ lexicon: docker
185
+ docs: https://intentius.io/chant/lexicons/docker/rules/
186
+ ---
187
+ More than one CMD or ENTRYPOINT in a stage — only the last one takes effect
188
+ ",
189
+ "path": "rules/DKRD015.md",
190
+ },
191
+ {
192
+ "content": "---
193
+ type: post-synth-check
194
+ title: DKRD016
195
+ description: COPY --from names a stage that is not defined before it
196
+ id: DKRD016
197
+ severity: error
198
+ category: post-synth
199
+ lexicon: docker
200
+ docs: https://intentius.io/chant/lexicons/docker/rules/
201
+ ---
202
+ COPY --from names a stage that is not defined before it
203
+ ",
204
+ "path": "rules/DKRD016.md",
205
+ },
206
+ {
207
+ "content": "---
208
+ type: post-synth-check
209
+ title: DKRD017
210
+ description: ARG before the first FROM is not used by any FROM or stage
211
+ id: DKRD017
212
+ severity: error
213
+ category: post-synth
214
+ lexicon: docker
215
+ docs: https://intentius.io/chant/lexicons/docker/rules/
216
+ ---
217
+ ARG before the first FROM is not used by any FROM or stage
218
+ ",
219
+ "path": "rules/DKRD017.md",
220
+ },
221
+ {
222
+ "content": "---
223
+ type: post-synth-check
224
+ title: DKRD018
225
+ description: Relative WORKDIR before any absolute WORKDIR in the stage
226
+ id: DKRD018
227
+ severity: error
228
+ category: post-synth
229
+ lexicon: docker
230
+ docs: https://intentius.io/chant/lexicons/docker/rules/
231
+ ---
232
+ Relative WORKDIR before any absolute WORKDIR in the stage
233
+ ",
234
+ "path": "rules/DKRD018.md",
235
+ },
236
+ {
237
+ "content": "---
238
+ type: post-synth-check
239
+ title: DKRD019
240
+ description: ADD fetches a remote URL without --checksum
241
+ id: DKRD019
242
+ severity: error
243
+ category: post-synth
244
+ lexicon: docker
245
+ docs: https://intentius.io/chant/lexicons/docker/rules/
246
+ ---
247
+ ADD fetches a remote URL without --checksum
248
+ ",
249
+ "path": "rules/DKRD019.md",
250
+ },
251
+ {
252
+ "content": "---
253
+ type: post-synth-check
254
+ title: DKRD020
255
+ description: apt-get update in a different RUN from apt-get install — the install can use a stale package index
256
+ id: DKRD020
257
+ severity: error
258
+ category: post-synth
259
+ lexicon: docker
260
+ docs: https://intentius.io/chant/lexicons/docker/rules/
261
+ ---
262
+ apt-get update in a different RUN from apt-get install — the install can use a stale package index
263
+ ",
264
+ "path": "rules/DKRD020.md",
265
+ },
266
+ {
267
+ "content": "---
139
268
  type: lint-rule
140
269
  title: DKRS001
141
270
  description: No Latest Tag
@@ -155,6 +284,25 @@ No Latest Tag
155
284
  },
156
285
  {
157
286
  "content": "---
287
+ type: lint-rule
288
+ title: DKRS002
289
+ description: Per-kind Dockerfile fields written in a different order
290
+ id: DKRS002
291
+ severity: warning
292
+ category: correctness
293
+ lexicon: docker
294
+ docs: https://intentius.io/chant/lexicons/docker/rules/
295
+ ---
296
+ Per-kind Dockerfile fields written in a different order
297
+
298
+ ## Applies to
299
+
300
+ - [Dockerfile](/types/Dockerfile.md)
301
+ ",
302
+ "path": "rules/DKRS002.md",
303
+ },
304
+ {
305
+ "content": "---
158
306
  type: resource-type
159
307
  title: DockerConfig
160
308
  description: A config definition in Docker Compose
@@ -166,11 +314,13 @@ A config definition in Docker Compose
166
314
 
167
315
  ## Properties
168
316
 
169
- - \`file\` (\`string\`): Path to the config file
170
- - \`content\` (\`string\`): Inline config content
171
- - \`external\` (\`boolean\`): Whether the config is external
172
- - \`labels\` (\`Record<string, string>\`): Config labels
173
- - \`name\` (\`string\`): Custom config name
317
+ - \`name\` (\`ComposeString\`): Custom name for this config.
318
+ - \`content\` (\`ComposeString\`): Inline content of the config.
319
+ - \`environment\` (\`ComposeString\`): Name of an environment variable from which to get the config value.
320
+ - \`file\` (\`ComposeString\`): Path to a file containing the config value.
321
+ - \`external\` (\`boolean | ComposeString | { name?: ComposeString }\`): Specifies that this config already exists and was created outside of Compose.
322
+ - \`labels\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`): Add metadata to the config using labels.
323
+ - \`template_driver\` (\`ComposeString\`): Driver to use for templating the config's value.
174
324
  ",
175
325
  "path": "types/DockerConfig.md",
176
326
  },
@@ -201,10 +351,13 @@ A Dockerfile definition with ordered build instructions
201
351
  - \`entrypoint\`: Set the entrypoint executable
202
352
  - \`cmd\`: Default command arguments
203
353
  - \`healthcheck\`: Health check instruction
354
+ - \`globalArgs\`: ARG instructions written before the first FROM
355
+ - \`steps\`: Instructions after FROM, written in the order given; one instruction per step
204
356
 
205
357
  ## Governed by
206
358
 
207
- - [DKRD012](/rules/DKRD012.md): Dockerfile has no USER instruction — container runs as root
359
+ - [DKRD012](/rules/DKRD012.md): Dockerfile's final stage has no USER instruction, or ends on USER root — container runs as root
360
+ - [DKRS002](/rules/DKRS002.md): Per-kind Dockerfile fields written in a different order
208
361
  ",
209
362
  "path": "types/Dockerfile.md",
210
363
  },
@@ -221,10 +374,14 @@ A secret definition in Docker Compose
221
374
 
222
375
  ## Properties
223
376
 
224
- - \`file\` (\`string\`): Path to the secret file
225
- - \`external\` (\`boolean\`): Whether the secret is external
226
- - \`labels\` (\`Record<string, string>\`): Secret labels
227
- - \`name\` (\`string\`): Custom secret name
377
+ - \`name\` (\`ComposeString\`): Custom name for this secret.
378
+ - \`environment\` (\`ComposeString\`): Name of an environment variable from which to get the secret value.
379
+ - \`file\` (\`ComposeString\`): Path to a file containing the secret value.
380
+ - \`external\` (\`boolean | ComposeString | { name?: ComposeString }\`): Specifies that this secret already exists and was created outside of Compose.
381
+ - \`labels\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`): Add metadata to the secret using labels.
382
+ - \`driver\` (\`ComposeString\`): Specify which secret driver should be used for this secret.
383
+ - \`driver_opts\` (\`Record<string, ComposeString | number>\`): Specify driver-specific options.
384
+ - \`template_driver\` (\`ComposeString\`): Driver to use for templating the secret's value.
228
385
  ",
229
386
  "path": "types/DockerSecret.md",
230
387
  },
@@ -241,12 +398,16 @@ A network definition in Docker Compose
241
398
 
242
399
  ## Properties
243
400
 
244
- - \`driver\` (\`string\`): Network driver
245
- - \`driver_opts\` (\`Record<string, string>\`): Driver options
246
- - \`external\` (\`boolean\`): Whether the network is external
247
- - \`labels\` (\`Record<string, string>\`): Network labels
248
- - \`internal\` (\`boolean\`): Restrict external access
249
- - \`ipam\` (\`object\`): IP address management
401
+ - \`name\` (\`ComposeString\`): Custom name for this network.
402
+ - \`driver\` (\`ComposeString\`): Specify which driver should be used for this network. Default is 'bridge'.
403
+ - \`driver_opts\` (\`Record<string, ComposeString | number>\`): Specify driver-specific options defined as key/value pairs.
404
+ - \`ipam\` (\`{ driver?: ComposeString; config?: Array<{ subnet?: ComposeString; ip_range?: ComposeString; gateway?: ComposeString; aux_addresses?: Record<string, ComposeString>; [key: \`x-\${string}\`]: unknown }>; options?: Record<string, ComposeString>; [key: \`x-\${string}\`]: unknown }\`): Custom IP Address Management configuration for this network.
405
+ - \`external\` (\`boolean | ComposeString | { name?: ComposeString; [key: \`x-\${string}\`]: unknown }\`): Specifies that this network already exists and was created outside of Compose.
406
+ - \`internal\` (\`boolean | ComposeString\`): Create an externally isolated network.
407
+ - \`enable_ipv4\` (\`boolean | ComposeString\`): Enable IPv4 networking.
408
+ - \`enable_ipv6\` (\`boolean | ComposeString\`): Enable IPv6 networking.
409
+ - \`attachable\` (\`boolean | ComposeString\`): If true, standalone containers can attach to this network.
410
+ - \`labels\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`): Add metadata to the network using labels.
250
411
  ",
251
412
  "path": "types/Network.md",
252
413
  },
@@ -263,21 +424,99 @@ A containerized service definition in Docker Compose
263
424
 
264
425
  ## Properties
265
426
 
266
- - \`image\` (\`string\`): Container image to use
267
- - \`build\` (\`object\`): Build configuration
268
- - \`command\` (\`string | string[]\`): Override the default command
269
- - \`entrypoint\` (\`string | string[]\`): Override the default entrypoint
270
- - \`environment\` (\`Record<string, string>\`): Environment variables
271
- - \`ports\` (\`string[]\`): Published ports
272
- - \`volumes\` (\`string[]\`): Volume mounts
273
- - \`networks\` (\`string[]\`): Networks to attach
274
- - \`depends_on\` (\`string[] | Record<string, { condition: "service_started" | "service_healthy" | "service_completed_successfully"; restart?: boolean; required?: boolean }>\`): Service dependencies (short list-form, or long form with a wait condition)
275
- - \`restart\` (\`string\`): Restart policy
276
- - \`labels\` (\`Record<string, string>\`): Container labels
277
- - \`healthcheck\` (\`object\`): Health check configuration
278
- - \`deploy\` (\`object\`): Swarm deployment configuration
279
- - \`secrets\` (\`string[]\`): Secrets to expose
280
- - \`configs\` (\`Array<string | { source: string | Declarable; target?: string; uid?: string; gid?: string; mode?: number }>\`): Configs to expose (short form, or long form with a mount target)
427
+ - \`develop\` (\`{ watch?: Array<{ ignore?: ComposeString | Array<ComposeString>; include?: ComposeString | Array<ComposeString>; path: ComposeString; action: "rebuild" | "sync" | "restart" | "sync+restart" | "sync+exec"; target?: ComposeString; exec?: { command: null | ComposeString | Array<ComposeString>; user?: ComposeString; privileged?: boolean | ComposeString; working_dir?: ComposeString; environment?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; [key: \`x-\${string}\`]: unknown }; initial_sync?: boolean; [key: \`x-\${string}\`]: unknown }>; [key: \`x-\${string}\`]: unknown } | null\`)
428
+ - \`deploy\` (\`{ mode?: ComposeString; endpoint_mode?: ComposeString; replicas?: number | ComposeString; labels?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; rollback_config?: { parallelism?: number | ComposeString; delay?: ComposeString; failure_action?: ComposeString; monitor?: ComposeString; max_failure_ratio?: number | ComposeString; order?: "start-first" | "stop-first"; [key: \`x-\${string}\`]: unknown }; update_config?: { parallelism?: number | ComposeString; delay?: ComposeString; failure_action?: ComposeString; monitor?: ComposeString; max_failure_ratio?: number | ComposeString; order?: "start-first" | "stop-first"; [key: \`x-\${string}\`]: unknown }; resources?: { limits?: { cpus?: number | ComposeString; memory?: ComposeString; pids?: number | ComposeString; [key: \`x-\${string}\`]: unknown }; reservations?: { cpus?: number | ComposeString; memory?: ComposeString; generic_resources?: Array<{ discrete_resource_spec?: { kind?: ComposeString; value?: number | ComposeString; [key: \`x-\${string}\`]: unknown }; [key: \`x-\${string}\`]: unknown }>; devices?: Array<{ capabilities: Array<ComposeString>; count?: ComposeString | number; device_ids?: Array<ComposeString>; driver?: ComposeString; options?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; [key: \`x-\${string}\`]: unknown }>; [key: \`x-\${string}\`]: unknown }; [key: \`x-\${string}\`]: unknown }; restart_policy?: { condition?: ComposeString; delay?: ComposeString; max_attempts?: number | ComposeString; window?: ComposeString; [key: \`x-\${string}\`]: unknown }; placement?: { constraints?: Array<ComposeString>; preferences?: Array<{ spread?: ComposeString; [key: \`x-\${string}\`]: unknown }>; max_replicas_per_node?: number | ComposeString; [key: \`x-\${string}\`]: unknown }; [key: \`x-\${string}\`]: unknown } | null\`)
429
+ - \`annotations\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`)
430
+ - \`attach\` (\`boolean | ComposeString\`)
431
+ - \`build\` (\`ComposeString | { context?: ComposeString; dockerfile?: ComposeString; dockerfile_inline?: ComposeString; entitlements?: Array<ComposeString>; args?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; ssh?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; labels?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; cache_from?: Array<ComposeString>; cache_to?: Array<ComposeString>; no_cache?: boolean | ComposeString; no_cache_filter?: ComposeString | Array<ComposeString>; additional_contexts?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; network?: ComposeString; provenance?: ComposeString | boolean; sbom?: ComposeString | boolean; pull?: boolean | ComposeString; target?: ComposeString; shm_size?: number | ComposeString; extra_hosts?: Record<string, ComposeString | Array<ComposeString>> | Array<ComposeString>; isolation?: ComposeString; privileged?: boolean | ComposeString; secrets?: Array<ComposeString | { source?: ComposeString; target?: ComposeString; uid?: ComposeString; gid?: ComposeString; mode?: number | ComposeString; [key: \`x-\${string}\`]: unknown }>; tags?: Array<ComposeString>; ulimits?: Record<string, number | ComposeString | { hard: number | ComposeString; soft: number | ComposeString; [key: \`x-\${string}\`]: unknown }>; platforms?: Array<ComposeString>; [key: \`x-\${string}\`]: unknown }\`): Configuration options for building the service's image.
432
+ - \`blkio_config\` (\`{ device_read_bps?: Array<{ path?: ComposeString; rate?: number | ComposeString }>; device_read_iops?: Array<{ path?: ComposeString; rate?: number | ComposeString }>; device_write_bps?: Array<{ path?: ComposeString; rate?: number | ComposeString }>; device_write_iops?: Array<{ path?: ComposeString; rate?: number | ComposeString }>; weight?: number | ComposeString; weight_device?: Array<{ path?: ComposeString; weight?: number | ComposeString }> }\`): Block IO configuration for the service.
433
+ - \`cap_add\` (\`Array<ComposeString>\`): Add Linux capabilities. For example, 'CAP_SYS_ADMIN', 'SYS_ADMIN', or 'NET_ADMIN'.
434
+ - \`cap_drop\` (\`Array<ComposeString>\`): Drop Linux capabilities. For example, 'CAP_SYS_ADMIN', 'SYS_ADMIN', or 'NET_ADMIN'.
435
+ - \`cgroup\` (\`"host" | "private"\`): Specify the cgroup namespace to join. Use 'host' to use the host's cgroup namespace, or 'private' to use a private cgroup namespace.
436
+ - \`cgroup_parent\` (\`ComposeString\`): Specify an optional parent cgroup for the container.
437
+ - \`command\` (\`null | ComposeString | Array<ComposeString>\`): Override the default command declared by the container image, for example 'CMD' in Dockerfile.
438
+ - \`configs\` (\`Array<ComposeString | { source?: ComposeString; target?: ComposeString; uid?: ComposeString; gid?: ComposeString; mode?: number | ComposeString; [key: \`x-\${string}\`]: unknown }>\`): Grant access to Configs on a per-service basis.
439
+ - \`container_name\` (\`ComposeString\`): Specify a custom container name, rather than a generated default name.
440
+ - \`cpu_count\` (\`ComposeString | number\`): Number of usable CPUs.
441
+ - \`cpu_percent\` (\`ComposeString | number\`): Percentage of CPU resources to use.
442
+ - \`cpu_shares\` (\`number | ComposeString\`): CPU shares (relative weight) for the container.
443
+ - \`cpu_quota\` (\`number | ComposeString\`): Limit the CPU CFS (Completely Fair Scheduler) quota.
444
+ - \`cpu_period\` (\`number | ComposeString\`): Limit the CPU CFS (Completely Fair Scheduler) period.
445
+ - \`cpu_rt_period\` (\`number | ComposeString\`): Limit the CPU real-time period in microseconds or a duration.
446
+ - \`cpu_rt_runtime\` (\`number | ComposeString\`): Limit the CPU real-time runtime in microseconds or a duration.
447
+ - \`cpus\` (\`number | ComposeString\`): Number of CPUs to use. A floating-point value is supported to request partial CPUs.
448
+ - \`cpuset\` (\`ComposeString\`): CPUs in which to allow execution (0-3, 0,1).
449
+ - \`credential_spec\` (\`{ config?: ComposeString; file?: ComposeString; registry?: ComposeString; [key: \`x-\${string}\`]: unknown }\`): Configure the credential spec for managed service account.
450
+ - \`depends_on\` (\`Array<ComposeString> | Record<string, { restart?: boolean | ComposeString; required?: boolean; condition: "service_started" | "service_healthy" | "service_completed_successfully"; [key: \`x-\${string}\`]: unknown }>\`): Express dependency between services. Service dependencies cause services to be started in dependency order. The dependent service will wait for the dependency to be ready before starting.
451
+ - \`device_cgroup_rules\` (\`Array<ComposeString>\`): Add rules to the cgroup allowed devices list.
452
+ - \`devices\` (\`Array<ComposeString | { source: ComposeString; target?: ComposeString; permissions?: ComposeString; [key: \`x-\${string}\`]: unknown }>\`): List of device mappings for the container.
453
+ - \`dns\` (\`ComposeString | Array<ComposeString>\`): Custom DNS servers to set for the service container.
454
+ - \`dns_opt\` (\`Array<ComposeString>\`): Custom DNS options to be passed to the container's DNS resolver.
455
+ - \`dns_search\` (\`ComposeString | Array<ComposeString>\`): Custom DNS search domains to set on the service container.
456
+ - \`domainname\` (\`ComposeString\`): Custom domain name to use for the service container.
457
+ - \`entrypoint\` (\`null | ComposeString | Array<ComposeString>\`): Override the default entrypoint declared by the container image, for example 'ENTRYPOINT' in Dockerfile.
458
+ - \`env_file\` (\`ComposeString | Array<ComposeString | { path: ComposeString; format?: ComposeString; required?: boolean | ComposeString }>\`): Add environment variables from a file or multiple files. Can be a single file path or a list of file paths.
459
+ - \`label_file\` (\`ComposeString | Array<ComposeString>\`): Add metadata to containers using files containing Docker labels.
460
+ - \`environment\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`): Add environment variables. You can use either an array or a list of KEY=VAL pairs.
461
+ - \`expose\` (\`Array<ComposeString | number>\`): Expose ports without publishing them to the host machine - they'll only be accessible to linked services.
462
+ - \`extends\` (\`ComposeString | { service: ComposeString; file?: ComposeString }\`): Extend another service, in the current file or another file.
463
+ - \`provider\` (\`{ type: ComposeString; options?: Record<string, ComposeString | number | boolean | Array<ComposeString | number | boolean>>; [key: \`x-\${string}\`]: unknown }\`): Specify a service which will not be manage by Compose directly, and delegate its management to an external provider.
464
+ - \`external_links\` (\`Array<ComposeString>\`): Link to services started outside this Compose application. Specify services as <service_name>:<alias>.
465
+ - \`extra_hosts\` (\`Record<string, ComposeString | Array<ComposeString>> | Array<ComposeString>\`): Add hostname mappings to the container network interface configuration.
466
+ - \`gpus\` (\`"all" | Array<{ capabilities?: Array<ComposeString>; count?: ComposeString | number; device_ids?: Array<ComposeString>; driver?: ComposeString; options?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString> }>\`): Define GPU devices to use. Can be set to 'all' to use all GPUs, or a list of specific GPU devices.
467
+ - \`group_add\` (\`Array<ComposeString | number>\`): Add additional groups which user inside the container should be member of.
468
+ - \`healthcheck\` (\`{ disable?: boolean | ComposeString; interval?: ComposeString; retries?: number | ComposeString; test?: ComposeString | Array<ComposeString>; timeout?: ComposeString; start_period?: ComposeString; start_interval?: ComposeString; [key: \`x-\${string}\`]: unknown }\`): Configure a health check for the container to monitor its health status.
469
+ - \`hostname\` (\`ComposeString\`): Define a custom hostname for the service container.
470
+ - \`image\` (\`ComposeString\`): Specify the image to start the container from. Can be a repository/tag, a digest, or a local image ID.
471
+ - \`init\` (\`boolean | ComposeString\`): Run as an init process inside the container that forwards signals and reaps processes.
472
+ - \`ipc\` (\`ComposeString\`): IPC sharing mode for the service container. Use 'host' to share the host's IPC namespace, 'service:[service_name]' to share with another service, or 'shareable' to allow other services to share this service's IPC namespace.
473
+ - \`isolation\` (\`ComposeString\`): Container isolation technology to use. Supported values are platform-specific.
474
+ - \`labels\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`): Add metadata to containers using Docker labels. You can use either an array or a list.
475
+ - \`links\` (\`Array<ComposeString>\`): Link to containers in another service. Either specify both the service name and a link alias (SERVICE:ALIAS), or just the service name.
476
+ - \`logging\` (\`{ driver?: ComposeString; options?: Record<string, ComposeString | number | null>; [key: \`x-\${string}\`]: unknown }\`): Logging configuration for the service.
477
+ - \`mac_address\` (\`ComposeString\`): Container MAC address to set.
478
+ - \`mem_limit\` (\`number | ComposeString\`): Memory limit for the container. A string value can use suffix like '2g' for 2 gigabytes.
479
+ - \`mem_reservation\` (\`ComposeString | number\`): Memory reservation for the container.
480
+ - \`mem_swappiness\` (\`number | ComposeString\`): Container memory swappiness as percentage (0 to 100).
481
+ - \`memswap_limit\` (\`number | ComposeString\`): Amount of memory the container is allowed to swap to disk. Set to -1 to enable unlimited swap.
482
+ - \`network_mode\` (\`ComposeString\`): Network mode. Values can be 'bridge', 'host', 'none', 'service:[service name]', or 'container:[container name]'.
483
+ - \`models\` (\`Array<ComposeString> | Record<string, { endpoint_var?: ComposeString; model_var?: ComposeString; [key: \`x-\${string}\`]: unknown } | null>\`): AI Models to use, referencing entries under the top-level models key.
484
+ - \`networks\` (\`Array<ComposeString> | Record<string, { aliases?: Array<ComposeString>; interface_name?: ComposeString; ipv4_address?: ComposeString; ipv6_address?: ComposeString; link_local_ips?: Array<ComposeString>; mac_address?: ComposeString; driver_opts?: Record<string, ComposeString | number>; priority?: number; gw_priority?: number; [key: \`x-\${string}\`]: unknown } | null>\`): Networks to join, referencing entries under the top-level networks key. Can be a list of network names or a mapping of network name to network configuration.
485
+ - \`oom_kill_disable\` (\`boolean | ComposeString\`): Disable OOM Killer for the container.
486
+ - \`oom_score_adj\` (\`ComposeString | number\`): Tune host's OOM preferences for the container (accepts -1000 to 1000).
487
+ - \`pid\` (\`ComposeString | null\`): PID mode for container.
488
+ - \`pids_limit\` (\`number | ComposeString\`): Tune a container's PIDs limit. Set to -1 for unlimited PIDs.
489
+ - \`platform\` (\`ComposeString\`): Target platform to run on, e.g., 'linux/amd64', 'linux/arm64', or 'windows/amd64'.
490
+ - \`ports\` (\`Array<number | ComposeString | { name?: ComposeString; mode?: ComposeString; host_ip?: ComposeString; target?: number | ComposeString; published?: ComposeString | number; protocol?: ComposeString; app_protocol?: ComposeString; [key: \`x-\${string}\`]: unknown }>\`): Expose container ports. Short format ([HOST:]CONTAINER[/PROTOCOL]).
491
+ - \`pre_start\` (\`Array<{ command?: null | ComposeString | Array<ComposeString>; image?: ComposeString; user?: ComposeString; privileged?: boolean | ComposeString; working_dir?: ComposeString; environment?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; per_replica?: boolean | ComposeString; [key: \`x-\${string}\`]: unknown }>\`): Init containers to run to completion before the service container is started. Each step runs in its own ephemeral container, in declared order; a non-zero exit fails the bring-up of the service and its dependents.
492
+ - \`post_start\` (\`Array<{ command: null | ComposeString | Array<ComposeString>; user?: ComposeString; privileged?: boolean | ComposeString; working_dir?: ComposeString; environment?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; [key: \`x-\${string}\`]: unknown }>\`): Commands to run after the container starts. If any command fails, the container stops.
493
+ - \`pre_stop\` (\`Array<{ command: null | ComposeString | Array<ComposeString>; user?: ComposeString; privileged?: boolean | ComposeString; working_dir?: ComposeString; environment?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; [key: \`x-\${string}\`]: unknown }>\`): Commands to run before the container stops. If any command fails, the container stop is aborted.
494
+ - \`privileged\` (\`boolean | ComposeString\`): Give extended privileges to the service container.
495
+ - \`profiles\` (\`Array<ComposeString>\`): List of profiles for this service. When profiles are specified, services are only started when the profile is activated.
496
+ - \`pull_policy\` (\`ComposeString\`): Policy for pulling images. Options include: 'always', 'never', 'if_not_present', 'missing', 'build', or time-based refresh policies.
497
+ - \`pull_refresh_after\` (\`ComposeString\`): Time after which to refresh the image. Used with pull_policy=refresh.
498
+ - \`read_only\` (\`boolean | ComposeString\`): Mount the container's filesystem as read only.
499
+ - \`restart\` (\`ComposeString\`): Restart policy for the service container. Options include: 'no', 'always', 'on-failure', and 'unless-stopped'.
500
+ - \`runtime\` (\`ComposeString\`): Runtime to use for this container, e.g., 'runc'.
501
+ - \`scale\` (\`number | ComposeString\`): Number of containers to deploy for this service.
502
+ - \`security_opt\` (\`Array<ComposeString>\`): Override the default labeling scheme for each container.
503
+ - \`shm_size\` (\`number | ComposeString\`): Size of /dev/shm. A string value can use suffix like '2g' for 2 gigabytes.
504
+ - \`secrets\` (\`Array<ComposeString | { source?: ComposeString; target?: ComposeString; uid?: ComposeString; gid?: ComposeString; mode?: number | ComposeString; [key: \`x-\${string}\`]: unknown }>\`): Grant access to Secrets on a per-service basis.
505
+ - \`sysctls\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`): Kernel parameters to set in the container. You can use either an array or a list.
506
+ - \`stdin_open\` (\`boolean | ComposeString\`): Keep STDIN open even if not attached.
507
+ - \`stop_grace_period\` (\`ComposeString\`): Time to wait for the container to stop gracefully before sending SIGKILL (e.g., '1s', '1m30s').
508
+ - \`stop_signal\` (\`ComposeString\`): Signal to stop the container (e.g., 'SIGTERM', 'SIGINT').
509
+ - \`storage_opt\` (\`Record<string, unknown>\`): Storage driver options for the container.
510
+ - \`tmpfs\` (\`ComposeString | Array<ComposeString>\`): Mount a temporary filesystem (tmpfs) into the container. Can be a single value or a list.
511
+ - \`tty\` (\`boolean | ComposeString\`): Allocate a pseudo-TTY to service container.
512
+ - \`ulimits\` (\`Record<string, number | ComposeString | { hard: number | ComposeString; soft: number | ComposeString; [key: \`x-\${string}\`]: unknown }>\`): Override the default ulimits for a container.
513
+ - \`use_api_socket\` (\`boolean\`): Bind mount Docker API socket and required auth.
514
+ - \`user\` (\`ComposeString\`): Username or UID to run the container process as.
515
+ - \`uts\` (\`ComposeString\`): UTS namespace to use. 'host' shares the host's UTS namespace.
516
+ - \`userns_mode\` (\`ComposeString\`): User namespace to use. 'host' shares the host's user namespace.
517
+ - \`volumes\` (\`Array<ComposeString | { type: "bind" | "volume" | "tmpfs" | "cluster" | "npipe" | "image"; source?: ComposeString; target?: ComposeString; read_only?: boolean | ComposeString; consistency?: ComposeString; bind?: { propagation?: ComposeString; create_host_path?: boolean | ComposeString; recursive?: "enabled" | "disabled" | "writable" | "readonly"; selinux?: "z" | "Z"; [key: \`x-\${string}\`]: unknown }; volume?: { labels?: Record<string, ComposeString | number | boolean | null> | Array<ComposeString>; nocopy?: boolean | ComposeString; subpath?: ComposeString; [key: \`x-\${string}\`]: unknown }; tmpfs?: { size?: number | ComposeString; mode?: number | ComposeString; [key: \`x-\${string}\`]: unknown }; image?: { subpath?: ComposeString; [key: \`x-\${string}\`]: unknown }; [key: \`x-\${string}\`]: unknown }>\`): Mount host paths or named volumes accessible to the container. Short syntax (VOLUME:CONTAINER_PATH[:MODE])
518
+ - \`volumes_from\` (\`Array<ComposeString>\`): Mount volumes from another service or container. Optionally specify read-only access (ro) or read-write (rw).
519
+ - \`working_dir\` (\`ComposeString\`): The working directory in which the entrypoint or command will be run
281
520
 
282
521
  ## Governed by
283
522
 
@@ -300,11 +539,11 @@ A named volume definition in Docker Compose
300
539
 
301
540
  ## Properties
302
541
 
303
- - \`driver\` (\`string\`): Volume driver
304
- - \`driver_opts\` (\`Record<string, string>\`): Driver options
305
- - \`external\` (\`boolean\`): Whether the volume is external
306
- - \`labels\` (\`Record<string, string>\`): Volume labels
307
- - \`name\` (\`string\`): Custom volume name
542
+ - \`name\` (\`ComposeString\`): Custom name for this volume.
543
+ - \`driver\` (\`ComposeString\`): Specify which volume driver should be used for this volume.
544
+ - \`driver_opts\` (\`Record<string, ComposeString | number>\`): Specify driver-specific options.
545
+ - \`external\` (\`boolean | ComposeString | { name?: ComposeString; [key: \`x-\${string}\`]: unknown }\`): Specifies that this volume already exists and was created outside of Compose.
546
+ - \`labels\` (\`Record<string, ComposeString | number | boolean | null> | Array<ComposeString>\`): Add metadata to the volume using labels.
308
547
 
309
548
  ## Governed by
310
549
 
@@ -133,6 +133,19 @@ chant build src --lexicon docker -o docker-compose.yml
133
133
  chant build src --lexicon aws -o template.json
134
134
  \`\`\``;
135
135
 
136
+ // "Optional: hand this page to your coding agent", shown under the overview's
137
+ // title. The Dockerfile shape is the ordered \`steps\` list from chant #3926.
138
+ const prompt = `Read https://intentius.io/chant/lexicons/docker/ and https://intentius.io/chant/lexicons/docker/dockerfiles/ first.
139
+ Bring this project's Docker files into chant TypeScript under src/.
140
+ Import each existing file. \`-o\` names a directory, and each import writes main.ts in it: \`chant import --lexicon docker docker-compose.yml -o src/compose/\`, and \`chant import --lexicon docker Dockerfile -o src/<name>/\` for each Dockerfile.
141
+ An imported Dockerfile is exported as \`app\`. Rename each export after its image, since the export name sets the output file (Dockerfile.<export>), and point the Compose service's \`build.dockerfile\` at that export (\`dockerfile: webImage\`) instead of the old file name.
142
+ Write every Dockerfile stage as an ordered \`steps\` list, one instruction per step, with FROM as the stage's \`from\` and ARGs before the first FROM in \`globalArgs\`:
143
+ steps: [{ workdir: "/app" }, { copy: "package*.json ./" }, { run: "npm ci" }, { copy: ". ." }, { user: "node" }, { cmd: ["node", "dist/index.js"] }]
144
+ Where two Dockerfiles repeat a stage or a run of steps, export it once as a const (a \`DockerfileStage\` or a \`DockerfileStep[]\`) from its own module and import it in both. Spread imported consts, not function results; a Dockerfile that needs parameters is a \`Composite\`.
145
+ Run \`chant build src --lexicon docker -o build/docker-compose.yml\` (Dockerfiles are written beside it) and compare with the original files, then \`chant lint src\`. Run \`chant lint src --fix\` for DKRS002 (per-kind fields to \`steps\`, then reorder the steps it writes), fix every other finding by hand, and repeat until lint is clean.
146
+ Report the generated docker-compose.yml and each Dockerfile.<name>, and any finding you left and why.
147
+ Never push an image, run \`docker compose up\` against anything but the local Docker daemon, or change files outside this project.`;
148
+
136
149
  export async function generateDocs(opts?: { verbose?: boolean }): Promise<void> {
137
150
  const pkgDir = dirname(dirname(dirname(fileURLToPath(import.meta.url))));
138
151
 
@@ -145,6 +158,7 @@ export async function generateDocs(opts?: { verbose?: boolean }): Promise<void>
145
158
  basePath: "/chant/lexicons/docker/",
146
159
  overview,
147
160
  outputFormat,
161
+ prompt,
148
162
  };
149
163
 
150
164
  const result = docsPipeline(config);