@heroiclands/package-build 22.15.1 → 22.16.0

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 (221) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/README.md +39 -678
  3. package/bin/{content-build.mjs → content-commands.mjs} +197 -118
  4. package/bin/package-build.mjs +303 -42
  5. package/bin/report.mjs +1 -1
  6. package/ci/ci-docker.mjs +6 -3
  7. package/ci/ci-steps.mjs +6 -4
  8. package/ci/content-format-reference.mjs +106 -0
  9. package/config.mjs +22 -2
  10. package/content-config.mjs +74 -134
  11. package/docs/api.md +294 -234
  12. package/docs/authoring/assets.md +31 -0
  13. package/docs/authoring/dates-and-calendars.md +33 -0
  14. package/docs/authoring/first-note.md +48 -0
  15. package/docs/authoring/frontmatter.md +40 -0
  16. package/docs/authoring/links-and-markup.md +137 -0
  17. package/docs/commands.md +631 -162
  18. package/docs/configuration.md +176 -140
  19. package/docs/content-format.md +50 -4229
  20. package/docs/design.md +32 -0
  21. package/docs/diagnostics.md +29 -22
  22. package/docs/getting-started.md +21 -877
  23. package/docs/guides/book.md +153 -0
  24. package/docs/guides/e2e.md +143 -0
  25. package/docs/guides/icons.md +126 -0
  26. package/docs/guides/localization.md +120 -0
  27. package/docs/guides/module-project.md +915 -0
  28. package/docs/guides/packs.md +167 -0
  29. package/docs/guides/reference-pages.md +148 -0
  30. package/docs/guides/release-and-deploy.md +114 -0
  31. package/docs/guides/site.md +152 -0
  32. package/docs/guides/system-project.md +45 -0
  33. package/docs/index.md +16 -0
  34. package/docs/project-setup.md +54 -35
  35. package/docs/reference/format-details.md +4420 -0
  36. package/docs/reference/note-types.md +531 -0
  37. package/engine/address-render.mjs +26 -0
  38. package/engine/address.mjs +3 -20
  39. package/engine/anchors.mjs +15 -6
  40. package/engine/asset-bindings.mjs +6 -2
  41. package/engine/base-compiler.mjs +47 -11
  42. package/engine/being-measurements.mjs +70 -0
  43. package/engine/calendar-artifacts.mjs +1 -1
  44. package/engine/calendar-choice.mjs +32 -0
  45. package/engine/calendar-human.mjs +71 -0
  46. package/engine/calendar-notes.mjs +41 -3
  47. package/engine/calendars.mjs +8 -1
  48. package/engine/changelog-lint.mjs +2 -2
  49. package/engine/code-fences.mjs +23 -97
  50. package/engine/compile-corpus.mjs +6 -7
  51. package/engine/content-admonitions.mjs +114 -0
  52. package/engine/content-captions.mjs +181 -0
  53. package/engine/content-embeds.mjs +2 -2
  54. package/engine/content-footnotes.mjs +34 -0
  55. package/engine/content-format-check.mjs +2 -2
  56. package/engine/content-format.mjs +127 -73
  57. package/engine/content-format.yaml +745 -0
  58. package/engine/content-html.mjs +1 -1
  59. package/engine/content-icons.mjs +45 -92
  60. package/engine/content-images.mjs +22 -74
  61. package/engine/content-index.mjs +12 -3
  62. package/engine/content-links.mjs +21 -26
  63. package/engine/content-lint.mjs +1 -5
  64. package/engine/content-secrets.mjs +3 -1
  65. package/engine/content-tables.mjs +47 -1257
  66. package/engine/culture-choice.mjs +32 -0
  67. package/engine/date-conversion.mjs +47 -0
  68. package/engine/declaration-check.mjs +87 -0
  69. package/engine/docs-checks.mjs +140 -0
  70. package/engine/documentation-links.mjs +31 -0
  71. package/engine/exported-scene.mjs +1 -1
  72. package/engine/extension-attributes.mjs +74 -0
  73. package/engine/field-reference.mjs +1 -1
  74. package/engine/field-spec.mjs +4 -0
  75. package/engine/foreign-catalog.mjs +5 -5
  76. package/engine/format-generated.mjs +15 -0
  77. package/engine/foundry-entries.mjs +3 -1
  78. package/engine/frontmatter-lint.mjs +5 -1
  79. package/engine/frontmatter.mjs +10 -0
  80. package/engine/generate.mjs +2 -2
  81. package/engine/helpers.mjs +71 -117
  82. package/engine/homepage.mjs +2 -3
  83. package/engine/index-records.mjs +1 -0
  84. package/engine/index.mjs +18 -3
  85. package/engine/infobox-registry.mjs +3 -1
  86. package/engine/infobox.mjs +38 -20
  87. package/engine/item-compiler.mjs +10 -8
  88. package/engine/item-docs.mjs +7 -6
  89. package/engine/journals.mjs +51 -10
  90. package/engine/macros.mjs +1 -1
  91. package/engine/map-build.mjs +1 -1
  92. package/engine/map-dot.mjs +1 -1
  93. package/engine/markdown-expressions.mjs +117 -0
  94. package/engine/metadata-index.mjs +7 -3
  95. package/engine/note-addresses.mjs +1 -0
  96. package/engine/note-dates.mjs +283 -61
  97. package/engine/note-package.mjs +5 -25
  98. package/engine/note-state.mjs +6 -2
  99. package/engine/note-vocabulary.mjs +74 -19
  100. package/engine/number-words.mjs +75 -0
  101. package/engine/office-holders.mjs +188 -0
  102. package/engine/pack-config.mjs +2 -15
  103. package/engine/pack-router.mjs +24 -5
  104. package/engine/packages.mjs +3 -2
  105. package/engine/pathnames.mjs +21 -24
  106. package/engine/pdf-build.mjs +217 -55
  107. package/engine/pdf-fonts.mjs +2 -2
  108. package/engine/pdf-images.mjs +82 -0
  109. package/engine/pdf-render.mjs +174 -22
  110. package/engine/populations.mjs +3 -2
  111. package/engine/project-init.mjs +499 -0
  112. package/engine/prose-config.mjs +1 -1
  113. package/engine/prose-lint.mjs +7 -6
  114. package/engine/readability-lint.mjs +86 -0
  115. package/engine/reckoning-markers.mjs +205 -93
  116. package/engine/scenes.mjs +5 -2
  117. package/engine/schema-check.mjs +3 -3
  118. package/engine/site-build.mjs +87 -37
  119. package/engine/site-config.mjs +8 -8
  120. package/engine/site-index.mjs +4 -0
  121. package/engine/site-maps.mjs +1 -1
  122. package/engine/site-preview.mjs +19 -8
  123. package/engine/social-ties.mjs +5 -1
  124. package/engine/sql-tables.mjs +92 -22
  125. package/engine/web-wikilinks.mjs +15 -31
  126. package/engine/wikilink-syntax.mjs +4 -1
  127. package/engine/wikilinks.mjs +12 -14
  128. package/hm3/item-fields.mjs +1 -1
  129. package/hm3/items.mjs +12 -45
  130. package/index.mjs +2 -14
  131. package/manifest.mjs +31 -4
  132. package/markdownlint-config.mjs +1 -1
  133. package/package.json +32 -11
  134. package/prettier-config.mjs +1 -1
  135. package/sohl/being-info.mjs +3 -145
  136. package/sohl/index.mjs +1 -1
  137. package/sohl/infobox.mjs +2 -1
  138. package/sohl/item-builders.mjs +3 -27
  139. package/sohl/item-fields.mjs +61 -22
  140. package/sohl/kb-passes.mjs +2 -2
  141. package/sohl/note-schemas.mjs +0 -8
  142. package/stage.mjs +19 -0
  143. package/types/config.d.mts +12 -3
  144. package/types/content-config.d.mts +15 -81
  145. package/types/engine/address-render.d.mts +13 -0
  146. package/types/engine/address.d.mts +2 -11
  147. package/types/engine/anchors.d.mts +3 -4
  148. package/types/engine/asset-bindings.d.mts +9 -2
  149. package/types/engine/base-compiler.d.mts +1 -2
  150. package/types/engine/being-measurements.d.mts +16 -0
  151. package/types/engine/calendar-choice.d.mts +14 -0
  152. package/types/engine/calendar-human.d.mts +4 -0
  153. package/types/engine/calendar-notes.d.mts +2 -0
  154. package/types/engine/calendars.d.mts +5 -3
  155. package/types/engine/code-fences.d.mts +6 -72
  156. package/types/engine/compile-corpus.d.mts +1 -3
  157. package/types/engine/content-admonitions.d.mts +24 -0
  158. package/types/engine/content-captions.d.mts +45 -0
  159. package/types/engine/content-footnotes.d.mts +10 -0
  160. package/types/engine/content-format-check.d.mts +17 -4
  161. package/types/engine/content-format.d.mts +24 -11
  162. package/types/engine/content-icons.d.mts +14 -23
  163. package/types/engine/content-images.d.mts +2 -2
  164. package/types/engine/content-index.d.mts +9 -2
  165. package/types/engine/content-links.d.mts +3 -5
  166. package/types/engine/content-tables.d.mts +11 -140
  167. package/types/engine/culture-choice.d.mts +14 -0
  168. package/types/engine/date-conversion.d.mts +4 -0
  169. package/types/engine/declaration-check.d.mts +24 -0
  170. package/types/engine/docs-checks.d.mts +28 -0
  171. package/types/engine/documentation-links.d.mts +7 -0
  172. package/types/engine/exported-scene.d.mts +6 -2
  173. package/types/engine/extension-attributes.d.mts +14 -0
  174. package/types/engine/field-spec.d.mts +9 -0
  175. package/types/engine/format-generated.d.mts +7 -0
  176. package/types/engine/frontmatter.d.mts +14 -4
  177. package/types/engine/generate.d.mts +1 -1
  178. package/types/engine/helpers.d.mts +37 -92
  179. package/types/engine/homepage.d.mts +2 -3
  180. package/types/engine/index.d.mts +5 -0
  181. package/types/engine/infobox-registry.d.mts +3 -1
  182. package/types/engine/infobox.d.mts +17 -6
  183. package/types/engine/item-compiler.d.mts +4 -4
  184. package/types/engine/item-docs.d.mts +4 -3
  185. package/types/engine/journals.d.mts +10 -7
  186. package/types/engine/map-graphviz.d.mts +1 -1
  187. package/types/engine/markdown-expressions.d.mts +17 -0
  188. package/types/engine/note-dates.d.mts +47 -1
  189. package/types/engine/note-package.d.mts +3 -19
  190. package/types/engine/note-state.d.mts +2 -1
  191. package/types/engine/note-vocabulary.d.mts +9 -0
  192. package/types/engine/number-words.d.mts +4 -0
  193. package/types/engine/office-holders.d.mts +14 -0
  194. package/types/engine/pack-config.d.mts +1 -1
  195. package/types/engine/packages.d.mts +3 -2
  196. package/types/engine/pdf-images.d.mts +38 -0
  197. package/types/engine/populations.d.mts +2 -2
  198. package/types/engine/project-init.d.mts +17 -0
  199. package/types/engine/prose-config.d.mts +1 -1
  200. package/types/engine/prose-lint.d.mts +3 -2
  201. package/types/engine/readability-lint.d.mts +22 -0
  202. package/types/engine/reckoning-markers.d.mts +4 -2
  203. package/types/engine/schema-check.d.mts +3 -3
  204. package/types/engine/site-build.d.mts +38 -28
  205. package/types/engine/site-config.d.mts +2 -2
  206. package/types/engine/site-index.d.mts +4 -0
  207. package/types/engine/site-preview.d.mts +1 -1
  208. package/types/engine/social-ties.d.mts +8 -2
  209. package/types/engine/sql-tables.d.mts +13 -2
  210. package/types/engine/web-wikilinks.d.mts +2 -1
  211. package/types/engine/wikilinks.d.mts +7 -1
  212. package/types/hm3/items.d.mts +5 -6
  213. package/types/labels.d.mts +40 -0
  214. package/types/manifest.d.mts +3 -3
  215. package/types/sohl/actors.d.mts +2 -2
  216. package/types/sohl/being-info.d.mts +3 -43
  217. package/types/sohl/index.d.mts +1 -1
  218. package/types/sohl/infobox.d.mts +5 -2
  219. package/types/sohl/item-fields.d.mts +4 -13
  220. package/types/stage.d.mts +9 -0
  221. package/CONTENT.md +0 -3239
@@ -1,3 +1,10 @@
1
+ ---
2
+ shortcode: configuration
3
+ name: { full: "Configuration" }
4
+ type: doc
5
+ subType: reference
6
+ ---
7
+
1
8
  ## Configuration: `package-build.config.yaml`, key by key
2
9
 
3
10
  Every repository built by `@heroiclands/package-build` declares itself in one
@@ -7,8 +14,8 @@ validates the object, fills every optional key with its default, and returns a
7
14
  deeply frozen copy. It performs no I/O and knows nothing about any particular
8
15
  package's content — the configuration is data, and the compilers read it.
9
16
 
10
- The reserved `packageBuild:` section belongs to the packaging half of the
11
- toolchain and is validated separately, by `resolvePackageBuildConfig` in
17
+ The reserved `packageBuild:` section holds packaging settings and is validated
18
+ by `resolvePackageBuildConfig` in
12
19
  `config.mjs`. `content-config.mjs` checks only that the section is a mapping
13
20
  and hands it back frozen; its own key-by-key reference is
14
21
  [below](#the-packagebuild-section).
@@ -54,29 +61,29 @@ alongside `foundryPackage`, `homepage`, `author` and `itemBuilders`, whose
54
61
  data-configuration behaviour is also derivation rather than ordinary
55
62
  authoring.
56
63
 
57
- | Key | Type | Required | Default |
58
- | ------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------- |
59
- | [`contentPackage`](#contentpackage) | string | yes | — |
60
- | [`foundryPackage`](#foundrypackage) | string | yes (`.mjs` only — derived in YAML); refused in a `documentation` package | — |
61
- | [`homepage`](#homepage) | string | no (`.mjs` only — derived in YAML) | `null` |
62
- | [`author`](#author) | string, or `{name, email?, url?}` | no (`.mjs` only — derived in YAML) | `null` |
63
- | [`packageKind`](#packagekind) | `"systems"` \| `"modules"` \| `"documentation"` | yes | — |
64
- | [`stats`](#stats) | object | yes; refused in a `documentation` package | — |
65
- | [`itemBuilders`](#itembuilders) | object, or list of `{system, builders}` (or a name/list of names, in YAML) | no; refused in a `documentation` package | `{}` |
66
- | [`paths`](#paths) | object | no | see [`paths`](#paths) |
67
- | [`skipDirectories`](#skipdirectories) | string[] | no | `[]` |
68
- | [`icons`](#icons) | object, or a path to a file holding one | no | empty registry |
69
- | [`packs`](#packs) | array | yes, at least one entry, in a `systems` or `modules` package; refused in a `documentation` package | — |
70
- | [`docs`](#docs) | object | no; refused in a `documentation` package | `{}` |
71
- | [`site`](#site) | object | no | see [`site`](#site) |
72
- | [`pdf`](#pdf) | object | no | `null` |
73
- | [`compatibility`](#compatibility) | object | no; refused in a `documentation` package | `null` |
74
- | [`relationships`](#relationships) | object | no; refused in a `documentation` package | `{}` |
75
- | [`systems`](#systems) | object | no; refused in a `documentation` package | `{}` |
76
- | [`requiresSystem`](#requiressystem) | string | no; refused in a `documentation` package | `null` |
77
- | [`packageBuild`](#the-packagebuild-section) | object | no | `{}` |
78
- | [`publish`](#publish) | object | no; **required**, with `site: content`, in a `documentation` package | `{site: "homepage", address: {prefix: ""}}` |
79
- | [`changelog`](#changelog) | object | no | `{labels: null}` |
64
+ | Key | Type | Required | Default |
65
+ | ------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------- |
66
+ | [`contentPackage`](#contentpackage) | string | yes | — |
67
+ | [`foundryPackage`](#foundrypackage) | string | yes (`.mjs` only — derived in YAML); refused in a `documentation` package | — |
68
+ | [`homepage`](#homepage) | string | no (`.mjs` only — derived in YAML) | `null` |
69
+ | [`author`](#author) | string, or `{name, email?, url?}` | no (`.mjs` only — derived in YAML) | `null` |
70
+ | [`packageKind`](#packagekind) | `"systems"` \| `"modules"` \| `"documentation"` | yes | — |
71
+ | [`stats`](#stats) | object | yes; refused in a `documentation` package | — |
72
+ | [`itemBuilders`](#itembuilders) | object, or list of `{system, builders}` (or a name/list of names, in YAML) | no; refused in a `documentation` package | `{}` |
73
+ | [`paths`](#paths) | object | no | see [`paths`](#paths) |
74
+ | [`skipDirectories`](#skipdirectories) | string[] | no | `[]` |
75
+ | [`icons`](#icons) | object, or a path to a file holding one | no | empty registry |
76
+ | [`packs`](#packs) | array | yes, at least one entry, in a `systems` or `modules` package; refused in a `documentation` package | — |
77
+ | [`docs`](#docs) | object | no; refused in a `documentation` package | `{}` |
78
+ | [`site`](#site) | object | no | see [`site`](#site) |
79
+ | [`pdf`](#pdf) | object | no | `null` |
80
+ | [`compatibility`](#compatibility) | object | no; refused in a `documentation` package | `null` |
81
+ | [`relationships`](#relationships) | object | no; refused in a `documentation` package | `{}` |
82
+ | [`systems`](#systems) | object | no; refused in a `documentation` package | `{}` |
83
+ | [`requiresSystem`](#requiressystem) | string | no; refused in a `documentation` package | `null` |
84
+ | [`packageBuild`](#the-packagebuild-section) | object | no | `{}` |
85
+ | [`publish`](#publish) | object | no | `{address: {prefix: ""}}` |
86
+ | [`changelog`](#changelog) | object | no | `{labels: null}` |
80
87
 
81
88
  Any key outside this list is refused:
82
89
 
@@ -170,7 +177,7 @@ declares none.
170
177
  `homepage` is not itself checked against `contentPackage` by `defineConfig`.
171
178
  `checkHomepage` in `config.mjs` is the check: `homepage` is required
172
179
  unconditionally — every package publishes a site — and must be an absolute
173
- URL whose path ends `/<contentPackage>/`. `content-build site` makes it
180
+ URL whose path ends `/<contentPackage>/`. `package-build site` makes it
174
181
  before the generated `baseURL` is written, so a missing or mismatched
175
182
  `homepage` is a finding on every site build:
176
183
 
@@ -352,7 +359,7 @@ optional (either of npm's forms) in an `.mjs` one.
352
359
 
353
360
  Which kind of package this repository builds. `systems` and `modules` are the
354
361
  two Foundry answers — also the directory Foundry installs the package under,
355
- and what `assetRoot` and the packaging half's `artifact` (`system` or
362
+ and what `assetRoot` and the release `artifact` (`system` or
356
363
  `module`) are derived from. `documentation` is the answer "not a Foundry
357
364
  package at all": it publishes a site and a book from its notes, installs into
358
365
  no Foundry data directory and compiles no compendium.
@@ -596,7 +603,7 @@ Every icon name is checked against the charset a note may write between the
596
603
  colons — lowercase letters, digits and hyphens, the same charset an address
597
604
  segment uses:
598
605
 
599
- > ``package-build config: `icons.icons.Bad_Name` is not a name a note can write — `:icon-…:` takes lowercase letters, digits and hyphens, the charset an address segment uses.``
606
+ > ``package-build config: `icons.icons.Bad_Name` is not a name a note can write — `:icon …:` takes lowercase letters, digits and hyphens, the charset an address segment uses.``
600
607
 
601
608
  `defaultFamily`, if set, must name a family the registry actually declares:
602
609
 
@@ -641,8 +648,27 @@ packs:
641
648
  | `packs[].prebuilt` | string (directory) | no | `null` |
642
649
  | `packs[].system` | string | no | `null` — falls back to `stats.systemId` |
643
650
 
651
+ `private: true` restricts a Foundry compendium to GMs. A note tagged `gm`
652
+ compiles only into private packs. Set `data.pack` to a private pack for the
653
+ note's own document. A note that also creates a JournalEntry needs one private
654
+ JournalEntry pack; the derived entry routes there automatically when the
655
+ ordinary JournalEntry default is public.
656
+
644
657
  `packs` itself:
645
658
 
659
+ The list's order is the order shown in the Foundry manifest. Compilation
660
+ orders its passes by what each compiler reads: for example, Item packs run
661
+ before an Actor pack that embeds their Items, regardless of their positions
662
+ in this list. A run restricted to `package-build package compile <name>`
663
+ requires any pack whose compiled output it reads to be included in the run
664
+ or already present under `build/packs-json/`. If that output is absent, the
665
+ command names the required pack and asks for a whole-package compile or for
666
+ that pack to be compiled first.
667
+
668
+ `packs[].ownership` is not a pack-spec key. The configuration rejects it;
669
+ neither the compiled pack nor the manifest receives an ownership value from
670
+ this list.
671
+
646
672
  > ``package-build config: `packs` must be an array.``
647
673
 
648
674
  A package may declare **no** packs. A module that ships assets and compiles
@@ -724,7 +750,7 @@ How this repository frames the documentation pages it generates.
724
750
  > ``package-build config: `docs.<key>` is not a recognized option (expected one of: itemFields).``
725
751
 
726
752
  `docs.itemFields` frames the item-frontmatter reference rendered by
727
- `content-build docs item-fields` — the tables come from the `itemBuilders`
753
+ `package-build docs item-fields` — the tables come from the `itemBuilders`
728
754
  registry and are the same wherever rendered; everything here is the
729
755
  consumer's: heading, orientation, where the page is filed.
730
756
 
@@ -747,7 +773,7 @@ consumer's: heading, orientation, where the page is filed.
747
773
  > ``package-build config: `docs.itemFields.preamble[<index>]` must be a string.``
748
774
 
749
775
  `frontmatter` is deep-merged over the note envelope written when `out` is
750
- under the content tree — see [`content-build docs item-fields`](commands.md#content-build-docs-item-fields):
776
+ under the content tree — see [`package-build docs item-fields`](commands.md#package-build-docs-item-fields):
751
777
 
752
778
  > ``package-build config: `docs.itemFields.frontmatter` must be a mapping.``
753
779
 
@@ -759,21 +785,22 @@ Any other key under `docs.itemFields` is refused:
759
785
 
760
786
  **Type:** object · **Optional** · every key defaults to nothing published:
761
787
 
762
- | Key | Type | Default |
763
- | ------------------ | -------- | ------------------------------------------- |
764
- | `site.base` | string | `""` |
765
- | `site.assets` | string | `""`, but required for `content-build site` |
766
- | `site.description` | string | `""`, but required for `content-build site` |
767
- | `site.packages` | string[] | `[]` |
768
- | `site.pass` | string | `""` |
769
- | `site.passOptions` | object | `{}` |
770
- | `site.notfound` | object | `null` |
771
- | `site.hugo` | object | `{}` |
772
- | `site.search` | boolean | `true` |
773
- | `site.maps` | boolean | `true` |
774
-
775
- How much of a package reaches the web at all is **not** here — it is
776
- [`publish.site`](#publish). `site` is framing: which named pass bundle
788
+ | Key | Type | Default |
789
+ | ------------------ | -------- | -------------------------------------------- |
790
+ | `site.base` | string | `""` |
791
+ | `site.title` | string | `""`, required when no manifest title exists |
792
+ | `site.assets` | string | `""`, but required for `package-build site` |
793
+ | `site.description` | string | `""`, but required for `package-build site` |
794
+ | `site.packages` | string[] | `[]` |
795
+ | `site.pass` | string | `""` |
796
+ | `site.passOptions` | object | `{}` |
797
+ | `site.notfound` | object | `null` |
798
+ | `site.hugo` | object | `{}` |
799
+ | `site.search` | boolean | `true` |
800
+ | `site.maps` | boolean | `true` |
801
+
802
+ The authored content tree determines which pages reach the web. `site` is
803
+ framing: which named pass bundle
777
804
  supplies the repository's own body rewrites, and the residue of the
778
805
  [generated Hugo configuration](#the-generated-hugo-configuration) that is
779
806
  genuinely this repository's own.
@@ -810,7 +837,7 @@ listing renders is a content table's to say:
810
837
 
811
838
  > ``package-build config: `site.list` is retired — a site is its homepage and its pages, and any index between them is a `doc` note: write one with `type: doc`, a `shortcode` and `pack: none`, carrying a content table over the notes it lists, and link it from the homepage. Nothing is generated between the homepage and the pages, so delete the key.``
812
839
 
813
- Where the Hugo tree is written is not a choice. `content-build site` writes
840
+ Where the Hugo tree is written is not a choice. `package-build site` writes
814
841
  the whole Hugo source tree under `build/hugo/` — the generated `hugo.toml`,
815
842
  the content mount at `build/hugo/content/`, Hugo's own cache — as a sibling
816
843
  of the deployment root `build/site/`, so nothing Hugo reads lands in what is
@@ -833,7 +860,7 @@ Absolute, and the trailing slash is trimmed:
833
860
 
834
861
  > ``package-build config: `site.assets` must be an absolute `http://` or `https://` address — it is the host every package's imagery is served from, and a relative value resolves against whichever page happens to carry the image.``
835
862
 
836
- `content-build site` refuses to generate a configuration with no
863
+ `package-build site` refuses to generate a configuration with no
837
864
  `site.assets` at all — there is no defensible default, because the theme
838
865
  resolves every relative asset against it:
839
866
 
@@ -844,11 +871,14 @@ The generated Hugo configuration carries the same host as
844
871
  The two are one value read by two readers: the toolchain emits it into a
845
872
  page, and the theme joins it onto anything the toolchain left relative.
846
873
 
874
+ `site.title` gives a documentation package its website title. For a Foundry
875
+ package, the site reads `packageBuild.manifest.title` when `site.title` is
876
+ absent.
877
+
847
878
  `site.description` is the site's `<meta name="description">` — one plain
848
879
  sentence, distinct from the Foundry package browser's pitch
849
880
  ([`packageBuild.manifest.descriptionHtml`](#packagebuildmanifest), which
850
- allows HTML). Required for `content-build site`, the way `packageBuild.manifest.title`
851
- is:
881
+ allows HTML). Required for `package-build site`, the way its title is:
852
882
 
853
883
  > ``package-build config: `site.description` is not declared, and the site's `<meta name="description">` reads from it.``
854
884
 
@@ -952,7 +982,7 @@ site:
952
982
  > ``package-build config: `site.search` must be a boolean.``
953
983
 
954
984
  `site.maps` is whether every place page carries the map from that place. On
955
- by default: `content-build site` draws the map `content-build map --from`
985
+ by default: `package-build site` draws the map `package-build map --from`
956
986
  draws — the place's borders and routes, each neighbour at its bearing — for
957
987
  every place that states a border or a route or is named in one, lays it beside
958
988
  the page as `from-<shortcode>.svg`, and names the file in the page's front
@@ -970,13 +1000,13 @@ site:
970
1000
 
971
1001
  ### The generated Hugo configuration
972
1002
 
973
- `content-build site` writes `build/hugo/hugo.toml` on every run. Every value
1003
+ `package-build site` writes `build/hugo/hugo.toml` on every run. Every value
974
1004
  in it has one source, and that source is where it is edited:
975
1005
 
976
1006
  | Key | Derived from |
977
1007
  | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
978
1008
  | `baseURL` | `package.json` `homepage`, checked by `checkHomepage` — an absolute URL ending `/<contentPackage>/` |
979
- | `title` | `packageBuild.manifest.title`, which is required |
1009
+ | `title` | `site.title` when declared, otherwise `packageBuild.manifest.title` |
980
1010
  | `locale` | the organisation's locale, `en-us`, in `engine/site-config.mjs` |
981
1011
  | `publishDir` | `contentPackage`, under the deployment root `build/site` — written relative to `build/hugo/`, so `../site/<contentPackage>` |
982
1012
  | `contentDir` | the fixed content mount, `build/hugo/content` — written as `content` |
@@ -991,21 +1021,20 @@ in it has one source, and that source is where it is edited:
991
1021
  | `params.brand` | the organisation's brand links — `logo`, `licenseURL`, `discordURL` — in `engine/site-config.mjs` |
992
1022
  | `params.notfound` | `site.notfound`; absent when undeclared |
993
1023
  | `markup.goldmark.renderer.unsafe` | the toolchain, whose pages carry raw HTML — a `<figure>` for every image, a `<span>` marking an unresolved link |
994
- | `menu` | the navigation `content-build deps fetch` caches from `https://www.heroiclands.org/nav.json`, entry for entry, a dropdown's entries as `parent` entries |
1024
+ | `menu` | the navigation `package-build deps fetch` caches from `https://www.heroiclands.org/nav.json`, entry for entry, a dropdown's entries as `parent` entries |
995
1025
 
996
1026
  The site build reads the navigation from the cache only. A cold cache is an
997
1027
  error naming the command that fills it:
998
1028
 
999
- > `the site navigation has not been fetched. Run `content-build deps fetch` first.`
1029
+ > `the site navigation has not been fetched. Run `package-build deps fetch` first.`
1000
1030
 
1001
1031
  A missing theme names the package to install:
1002
1032
 
1003
1033
  > `@heroiclands/hugo-theme is not installed anywhere above <rootDir> — add it to `devDependencies`and run`npm ci``
1004
1034
 
1005
- And a site's title reads from the manifest's, so a configuration declaring
1006
- none fails the site build:
1035
+ The site needs a title from `site.title` or the package manifest:
1007
1036
 
1008
- > ``package-build config: `packageBuild.manifest.title` is not declared, and the site's `title` reads from it.``
1037
+ > ``package-build config: declare `site.title` or `packageBuild.manifest.title` for the site's title.``
1009
1038
 
1010
1039
  `params.description` reads from `site.description` the same way, and fails
1011
1040
  the same way when it is absent:
@@ -1034,9 +1063,8 @@ The content tree published as a book — a **selection**, not a rendering of
1034
1063
  everything: `pdf.document` names the tree that says which notes the volume
1035
1064
  carries and in what order, parsed by `engine/pdf-toc.mjs`'s
1036
1065
  `parseDocumentTree` and not validated here. Whether a book is built at all
1037
- is [`publish.site`](#publish), the same switch that gates the website —
1038
- `content` builds one, `homepage` does not, so a package cannot end up with
1039
- two switches that disagree about whether it publishes its content tree.
1066
+ determined by the authored content tree: a tree containing only a homepage has
1067
+ no content pages for a book.
1040
1068
 
1041
1069
  Each selected place with a border or route receives a dedicated full-page
1042
1070
  vector itinerary after its entry. A selected authored regional SVG map also
@@ -1113,7 +1141,7 @@ Any other key on `pdf` is refused:
1113
1141
 
1114
1142
  ### `compatibility`
1115
1143
 
1116
- **Type:** object · **Optional** · default `null`. Refused in a
1144
+ **Type:** object · **Required for Foundry packages**. Refused in a
1117
1145
  `documentation` package, which installs into no Foundry data directory and so
1118
1146
  has no Foundry core range to support:
1119
1147
 
@@ -1132,23 +1160,22 @@ aspiration.
1132
1160
  compatibility: { minimum: "14.359", verified: "14.364" }
1133
1161
  ```
1134
1162
 
1135
- | Key | Type | Required | Default |
1136
- | ------------------------ | ------ | -------------------------------------- | ------- |
1137
- | `compatibility.minimum` | string | yes, once `compatibility:` is declared | — |
1138
- | `compatibility.verified` | string | no | none |
1163
+ | Key | Type | Required | Default |
1164
+ | ------------------------ | ------ | ------------------------ | ------- |
1165
+ | `compatibility.minimum` | string | yes for Foundry packages | — |
1166
+ | `compatibility.verified` | string | no | none |
1139
1167
 
1140
1168
  > ``package-build config: `compatibility` must be a mapping.``
1141
1169
 
1142
1170
  > ``package-build config: `compatibility.minimum` must be a non-empty string.``
1143
1171
 
1144
- > ``package-build config: `compatibility.<key>` is not a recognized option (expected one of: minimum, verified).``
1172
+ > ``package-build config: `compatibility.minimum` is required for a Foundry package.``
1145
1173
 
1146
- `compatibility` itself is optional at this validation layer — absent for a
1147
- content-only consumer, which has none to invent — but a repository that
1148
- compiles any pack needs one in practice: reading the floor throws, at
1149
- compile time rather than at configuration time, without it:
1174
+ > ``package-build config: `compatibility.<key>` is not a recognized option (expected one of: minimum, verified).``
1150
1175
 
1151
- > ``package-build: the configuration declares no `compatibility.minimum`, so compiled documents have no honest core version to stamp. Declare it at the top level of package-build.config.yaml.``
1176
+ `compatibility` belongs to every `systems` or `modules` package, including a
1177
+ module that ships only assets. A `documentation` package declares none because
1178
+ it installs no Foundry package and stamps no documents.
1152
1179
 
1153
1180
  ### `relationships`
1154
1181
 
@@ -1199,8 +1226,8 @@ Each entry, in any of the four lists:
1199
1226
 
1200
1227
  `contentPackage` names what the other package's _content_ is called, where
1201
1228
  that differs from its Foundry id. A note addresses a file by the content
1202
- package that owns it — `thalorna/assets/images/map.webp` — and the Foundry id
1203
- (`sohl-thalorna`) appears only in the install path that pathname resolves to.
1229
+ package that owns it — `harnensemble/assets/images/map.webp` — and the Foundry id
1230
+ (`harn-ensemble`) appears only in the install path that pathname resolves to.
1204
1231
  Omit it where the two are the same word, which they are for every system:
1205
1232
 
1206
1233
  > ``package-build config: `relationships.<kind>[<index>].contentPackage` must be a non-empty string.``
@@ -1224,6 +1251,11 @@ this tree never cites — so `deps fetch` fetches nothing for it and a wikilink
1224
1251
  into it fails, naming the key, rather than resolving against a stale
1225
1252
  declaration or an index nobody fetched:
1226
1253
 
1254
+ Run `package-build deps fetch` before compiling content that addresses a
1255
+ declared dependency's notes or embeds its Items. Compilation reads the cached
1256
+ index and Item catalogue for the declared version; it does not fetch them on
1257
+ demand.
1258
+
1227
1259
  > ``package-build config: `relationships.<kind>[<index>].contentIndex` must be true or false.``
1228
1260
 
1229
1261
  > ``package-build config: `relationships.<kind>[<index>].contentIndex` cannot be false together with `itemCatalog: true` — a catalogue is fetched from the same index.``
@@ -1311,46 +1343,28 @@ mapping:
1311
1343
 
1312
1344
  ### `publish`
1313
1345
 
1314
- **Type:** object · **Optional** for a `systems` or `modules` package, default
1315
- `{site: "homepage", address: {prefix: ""}}`. **Required** for a
1316
- `documentation` package, with `site: content` — publishing the content tree is
1317
- the whole of what that kind does:
1318
-
1319
- > ``package-build config: `publish` is required in a `documentation` package: publishing the content tree is the whole of what it does. Write `publish: {site: content}`.``
1346
+ **Type:** object · **Optional** · default `{address: {prefix: ""}}`.
1320
1347
 
1321
- > ``package-build config: `publish.site` must be `content` in a `documentation` package — `homepage` fences the content surfaces off, and a package that compiles nothing and publishes nothing from its tree would produce a single authored page and no book.``
1348
+ `publish.address` controls where content-page addresses mount inside the
1349
+ package. The content tree determines which pages are published.
1322
1350
 
1323
- Publishing switches — how much of this package reaches the web, and where
1324
- its content tree's addresses mount inside the package.
1325
-
1326
- | Key | Type | Required | Default |
1327
- | ------------------------ | --------------------------- | -------- | -------------- |
1328
- | `publish.site` | `"homepage"` \| `"content"` | no | `"homepage"` |
1329
- | `publish.address` | object | no | `{prefix: ""}` |
1330
- | `publish.address.prefix` | string | no | `""` |
1351
+ | Key | Type | Required | Default |
1352
+ | ------------------------ | ------ | -------- | -------------- |
1353
+ | `publish.address` | object | no | `{prefix: ""}` |
1354
+ | `publish.address.prefix` | string | no | `""` |
1331
1355
 
1332
1356
  > ``package-build config: `publish` must be an object.``
1333
1357
 
1334
- > ``package-build config: `publish.<key>` is not a recognized option (expected one of: site, address).``
1335
-
1336
- Every HeroicLands package publishes at least an authored homepage at
1337
- `https://www.heroiclands.org/<contentPackage>/` — there is no value meaning
1338
- _no web presence at all_. `homepage` is the floor: the authored homepage
1339
- and nothing else, no content-tree walk. `content` is the homepage plus every
1340
- page the content tree publishes. `publishesContentPages(config)`, exported from
1341
- `content-config.mjs` alongside [`compilesFoundryDocuments`](#packagekind),
1342
- answers the one question every reader of the mode actually asks — the site
1343
- build, to decide whether to walk the tree at all, and the content index, to
1344
- decide whether an entry carries a web `path`. It returns
1345
- `config.publish.site === "content"`.
1346
-
1347
- This was a boolean before `5.0.0`, and both spellings are refused rather
1348
- than silently mapped, because a value reinterpreted reads to its author as
1349
- though it still means what it said:
1358
+ > ``package-build config: `publish.<key>` is not a recognized option (expected one of: address).``
1350
1359
 
1351
- > ``package-build config: `publish.site` is no longer a boolean — write `site: content`. Every package publishes an authored homepage at /<contentPackage>/, so no value means "no web presence": `homepage` publishes that page and nothing else, and `content` publishes it plus every page the content tree compiles to.``
1360
+ Every HeroicLands package publishes an authored homepage at
1361
+ `https://www.heroiclands.org/<contentPackage>/`. Each other publishable note in
1362
+ the content tree supplies a content page. `publishesContentPages(config)`,
1363
+ exported from `content-config.mjs`, checks that tree for notes beyond the
1364
+ homepage. Site, PDF, index, and Foundry address emission use this same answer.
1365
+ Remove `publish.site` from package configurations:
1352
1366
 
1353
- > ``package-build config: `publish.site` must be one of homepage, content (got "public").``
1367
+ > ``package-build config: `publish.site` is not configured; publishing follows the authored content tree.``
1354
1368
 
1355
1369
  `publish.address.prefix` is where the content tree mounts _inside the
1356
1370
  package_ — `"kb/"` for a repository whose knowledgebase is one surface
@@ -1359,6 +1373,11 @@ end in a slash when set (a missing one would silently fuse the prefix to
1359
1373
  the first section) and must not begin with one (which would make the
1360
1374
  recorded address package-absolute):
1361
1375
 
1376
+ The site build uses this prefix for its Hugo source mount. Published note
1377
+ addresses and content-index paths stay relative to the package root; the
1378
+ manifest's package homepage also stays at that root. A page staged under
1379
+ `kb/` can therefore publish at `/<contentPackage>/<type>-<shortcode>/`.
1380
+
1362
1381
  > ``package-build config: `publish.address` must be an object.``
1363
1382
 
1364
1383
  > ``package-build config: `publish.address.prefix` must end in a slash when it is set.``
@@ -1418,13 +1437,10 @@ and [`package-build changelog group`](commands.md#package-build-changelog-group)
1418
1437
 
1419
1438
  ## The `packageBuild` section
1420
1439
 
1421
- Validated by `resolvePackageBuildConfig` in `config.mjs`, not by
1422
- `content-config.mjs`. The two halves split by **input** — the content half
1423
- reads the content tree, this one reads `lang/`, `styles/`, `src/`, the
1424
- assets and the manifest template — and neither validates the other's keys.
1425
- `packageBuild` is an ordinary section of the one configuration file; the
1426
- split exists only to stop one key being checked twice against two
1427
- disagreeing ideas of what it means.
1440
+ Validated by `resolvePackageBuildConfig` in `config.mjs`. Content settings
1441
+ are validated by `content-config.mjs`; packaging settings live in the
1442
+ `packageBuild` section of the same configuration file. Each key has one
1443
+ validator.
1428
1444
 
1429
1445
  ```yaml
1430
1446
  packageBuild:
@@ -1441,23 +1457,37 @@ packageBuild:
1441
1457
  envPrefix: SOHL
1442
1458
  ```
1443
1459
 
1444
- | Key | Type | Required | Default |
1445
- | ------------------------------------------------------------------------------------------ | ------------------------------------------- | -------- | --------------------------------- |
1446
- | [`packageBuild.stageDir`](#packagebuildstagedir-and-packagebuildassets) | string | no | `build/stage` |
1447
- | [`packageBuild.assets`](#packagebuildstagedir-and-packagebuildassets) | array | no | `[]` |
1448
- | [`packageBuild.assetTransform`](#packagebuildassettransform-and-packagebuildmanifestflags) | string (path to a module) | no | `null` |
1449
- | [`packageBuild.manifest`](#packagebuildmanifest) | object, pass-through | no | `{}` |
1450
- | [`packageBuild.manifestFlags`](#packagebuildassettransform-and-packagebuildmanifestflags) | string (path to a module) | no | `null` |
1451
- | [`packageBuild.schema`](#packagebuildschema) | object (`{documentType: {from, registry}}`) | no | `[]` |
1452
- | [`packageBuild.clean`](#packagebuildclean) | object | no | `{extra: []}` |
1453
- | [`packageBuild.lang`](#packagebuildlang) | object | no | see below |
1454
- | [`packageBuild.deploy`](#packagebuilddeploy) | object | no | `{envPrefix: "SOHL"}` |
1455
- | [`packageBuild.release`](#packagebuildrelease) | object | no | `{artifact: <from packageKind>}` |
1456
- | [`packageBuild.bundle`](#packagebuildbundle) | object | no | `{entry: "<foundryPackage>.mjs"}` |
1457
- | [`packageBuild.container`](#packagebuildcontainer) | object | no | see below |
1458
- | [`packageBuild.e2e`](#packagebuilde2e) | object | no | see below |
1459
-
1460
- > ``package-build config: `packageBuild.<key>` is not a recognised key (expected one of: stageDir, assets, assetTransform, manifest, manifestFlags, schema, clean, lang, deploy, release, bundle, container, e2e).``
1460
+ | Key | Type | Required | Default |
1461
+ | ------------------------------------------------------------------------------------------ | ------------------------------------------- | -------- | -------------------------------------- |
1462
+ | [`packageBuild.stageDir`](#packagebuildstagedir-and-packagebuildassets) | string | no | `build/stage` |
1463
+ | [`packageBuild.assets`](#packagebuildstagedir-and-packagebuildassets) | array | no | `[]` |
1464
+ | [`packageBuild.assetTransform`](#packagebuildassettransform-and-packagebuildmanifestflags) | string (path to a module) | no | `null` |
1465
+ | [`packageBuild.manifest`](#packagebuildmanifest) | object, pass-through | no | `{}` |
1466
+ | [`packageBuild.manifestFlags`](#packagebuildassettransform-and-packagebuildmanifestflags) | string (path to a module) | no | `null` |
1467
+ | [`packageBuild.schema`](#packagebuildschema) | object (`{documentType: {from, registry}}`) | no | `[]` |
1468
+ | [`packageBuild.clean`](#packagebuildclean) | object | no | `{extra: []}` |
1469
+ | [`packageBuild.lang`](#packagebuildlang) | object | no | see below |
1470
+ | [`packageBuild.deploy`](#packagebuilddeploy) | object | no | `{envPrefix: "SOHL"}` |
1471
+ | [`packageBuild.release`](#packagebuildrelease) | object | no | `{artifact: <from packageKind>}` |
1472
+ | [`packageBuild.bundle`](#packagebuildbundle) | object | no | `{entry: "<foundryPackage>.mjs"}` |
1473
+ | [`packageBuild.container`](#packagebuildcontainer) | object | no | see below |
1474
+ | [`packageBuild.e2e`](#packagebuilde2e) | object | no | see below |
1475
+ | [`packageBuild.proseLint`](#packagebuildproselint) | object | no | `{age: 21, threshold: 5, minWords: 8}` |
1476
+
1477
+ > ``package-build config: `packageBuild.<key>` is not a recognised key (expected one of: stageDir, assets, assetTransform, manifest, manifestFlags, schema, clean, lang, deploy, release, bundle, container, e2e, proseLint).``
1478
+
1479
+ ### `packageBuild.proseLint`
1480
+
1481
+ Optional defaults for [`package-build prose lint`](commands.md#package-build-prose-lint-path).
1482
+ `age` is the reader age, `threshold` is the number of readability algorithms
1483
+ required to flag a sentence (1–7), and `minWords` is the minimum sentence
1484
+ length. Each setting is a positive integer; command-line options can override
1485
+ them for one analysis.
1486
+
1487
+ ```yaml
1488
+ packageBuild:
1489
+ proseLint: { age: 21, threshold: 5, minWords: 8 }
1490
+ ```
1461
1491
 
1462
1492
  ### `packageBuild.stageDir` and `packageBuild.assets`
1463
1493
 
@@ -1489,7 +1519,7 @@ filename, without the extension, as a foreign Address shortcode. `package`
1489
1519
  and `type` are required; `system` defaults to `note`. The relationship with
1490
1520
  that package must provide a content index for the build to check the binding.
1491
1521
  The check reads the cached index, reports an unresolved file as an error, and
1492
- does not fetch during compilation. Run `content-build deps fetch` to fill a
1522
+ does not fetch during compilation. Run `package-build deps fetch` to fill a
1493
1523
  cold cache.
1494
1524
 
1495
1525
  ### `packageBuild.assetTransform` and `packageBuild.manifestFlags`
@@ -1506,24 +1536,30 @@ repository has to compute. Neither declares anything, both default to
1506
1536
 
1507
1537
  ### `packageBuild.manifest`
1508
1538
 
1539
+ `packageBuild.manifest.title` is a required, non-empty string for a Foundry
1540
+ system or module. It is the package name Foundry displays during installation;
1541
+ `package-build manifest` refuses to write a manifest without it.
1542
+
1509
1543
  Everything declared here is emitted into the generated manifest unchanged —
1510
1544
  **deliberately not key-checked**, so a key Foundry adds in a later version
1511
- can be declared without waiting on a release of this package. The one rule
1512
- that has a wrong answer rather than an unknown one: a key the build
1545
+ can be declared without waiting on a release of this package. A key the build
1513
1546
  **derives** must not also be authored, since the authored value would be
1514
1547
  silently overwritten and the two would be free to disagree with nothing to
1515
1548
  say so.
1516
1549
 
1550
+ `packageBuild.manifest.packFolders` groups declared packs in Foundry's pack
1551
+ browser. When it is set, a folder naming a pack absent from `packs` is an
1552
+ error at that folder's pack name. A declared pack named by no folder is a
1553
+ warning at `packFolders`: it still ships at the root. With no `packFolders`
1554
+ declaration, all packs ship at the root without a finding.
1555
+
1517
1556
  `packageBuild.manifest.descriptionHtml` is the exception worth calling out on
1518
1557
  its own: it is not forbidden, it **is** how `description` is authored. It is
1519
1558
  the pitch Foundry's package browser shows — HTML allowed, any length — and it
1520
1559
  is emitted into the generated manifest as `description`; the key itself never
1521
- survives into the manifest under its own name. `package.json`'s own
1522
- `description` is read by neither this nor the site (see
1523
- [`site.description`](#site)) — a declared one is reported as a warning naming
1524
- both real keys, so it cannot drift back into use:
1525
-
1526
- > `package.json: warning: \`description\` is read by nothing; the Foundry pitch is \`packageBuild.manifest.descriptionHtml\` and the site's is \`site.description\`` — a JSON manifest carries no line to point at, so only the file is named.
1560
+ survives into the manifest under its own name. `package.json.description` is
1561
+ npm package metadata. It does not supply the Foundry description or the site
1562
+ description (see [`site.description`](#site)); each surface has its own copy.
1527
1563
 
1528
1564
  | Forbidden key | Derived from |
1529
1565
  | ------------------------------------- | ---------------------------------------------------------------- |
@@ -1771,5 +1807,5 @@ the source directory:
1771
1807
  | `site.trees`, `site.readmeSections` | Retired — a page is a note in the content tree. |
1772
1808
  | `site.sections`, `site.landing`, `site.backfillSections`, `site.list` | Retired — a site is its homepage and its pages, and any index between them is a `doc` note. |
1773
1809
  | `site.hugo.baseURL`, `.title`, `.locale`, `.publishDir`, `.contentDir`, `.themesDir`, `.theme`, `.disableKinds`, `.taxonomies`, `.outputs`, `.params.description`, `.params.author`, `.params.cdnBaseURL`, `.params.brand`, `.params.notfound`, `.markup.goldmark.renderer.unsafe`, `.menu` | Forbidden — each is written by the site build from a source it names; see [the generated Hugo configuration](#the-generated-hugo-configuration). |
1774
- | `publish.site: true` / `publish.site: false` | Refused rather than mapped — write `homepage` or `content`. |
1810
+ | `publish.site` (any value) | Refused — publication follows the authored content tree. |
1775
1811
  | `packs`, `itemBuilders`, `docs`, `compatibility`, `relationships`, `systems`, `requiresSystem`, `stats`, `foundryPackage` | Forbidden in a `documentation` package — each describes a Foundry package this kind is not; see the key's own section for its located refusal message. |