@heroiclands/package-build 24.0.2 → 24.0.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @heroiclands/package-build
2
2
 
3
+ ## 24.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ **Languages**
8
+
9
+ - Core vocabulary coverage uses only the nearest definition when a language
10
+ redefines an inherited expression.
11
+
12
+ - Inherited dictionary words appear in a daughter language’s script with the
13
+ applicable native spelling.
14
+
15
+ **Verse**
16
+
17
+ - Parallel verse keeps its Roman reading beside the native script, with
18
+ gaps between stanzas.
19
+
20
+ ## 24.0.3
21
+
22
+ ### Patch Changes
23
+
24
+ **Sites**
25
+
26
+ - Glossary and dictionary entries link only to pages a reader can reach, and such links never make a page reachable.
27
+
28
+ **Configuration**
29
+
30
+ - A package can no longer declare a dependency whose images replace its own: `assetReplacement` and `assetArchive` are refused as unknown options.
31
+
32
+ **Languages and scripts**
33
+
34
+ - A sound mark can say `apart`, beside `stress` and `length`: the mark sets a vowel to be said apart from its neighbour, as a diaeresis does.
35
+ - A skeleton row can state `third`, the third consonants it holds for, beside `second`, so a rule that depends on the third consonant can be written.
36
+ - Text in the Veldikko script draws no charset warnings.
37
+
3
38
  ## 24.0.2
4
39
 
5
40
  ### Patch Changes
@@ -2815,18 +2815,16 @@ async function fetchFromLocalArtifact(config, argv) {
2815
2815
 
2816
2816
  /**
2817
2817
  * `deps fetch` — fill the caches this build resolves other packages through:
2818
- * the **content index** of every declared dependency, the **item catalogue
2819
- * or asset archive** of those additionally declaring `itemCatalog: true` or
2820
- * `assetArchive: true`, and the **site navigation** heroiclands.org
2818
+ * the **content index** of every declared dependency, the **item catalogue**
2819
+ * of those additionally declaring `itemCatalog: true`, and the **site navigation** heroiclands.org
2821
2820
  * publishes, which the site build writes its menu from.
2822
2821
  *
2823
2822
  * The dependency sets differ deliberately. Citing another package's
2824
- * *addresses*, embedding its *items*, and staging its *asset bytes* are
2825
- * separate edges, and a package may declare any of them without the others —
2823
+ * *addresses* and embedding its *items* are separate edges, and a package may
2824
+ * declare either without the other —
2826
2825
  * `harn-ensemble` cites no foreign address and embeds 324,016 item
2827
2826
  * references. The navigation is fetched for every package, because every
2828
- * package publishes a site. A relationship declaring both `itemCatalog: true`
2829
- * and `assetArchive: true` is fetched once.
2827
+ * package publishes a site.
2830
2828
  *
2831
2829
  * Its own command rather than a step of `package compile` or `site`, so that
2832
2830
  * neither reaches the network. A build that downloads silently is not
@@ -2887,7 +2885,7 @@ function depsCommand() {
2887
2885
  const indexes = await fetchAllMetadata(config);
2888
2886
  if (indexes) log.info(`Fetched ${indexes} dependency content index(es).`);
2889
2887
  const count = await fetchAllCatalogs(config);
2890
- if (count) log.info(`Fetched ${count} dependency catalogue(s) or archive(s).`);
2888
+ if (count) log.info(`Fetched ${count} dependency catalogue(s).`);
2891
2889
  if (!indexes && !count) {
2892
2890
  // Distinguished from a package declaring nothing at all: a
2893
2891
  // relationship may still be declared, just narrowed to the
@@ -2899,8 +2897,8 @@ function depsCommand() {
2899
2897
  );
2900
2898
  log.info(
2901
2899
  declared ?
2902
- "No declared dependency needs a fetched content index, item " +
2903
- "catalogue, or asset archive."
2900
+ "No declared dependency needs a fetched content index or item " +
2901
+ "catalogue."
2904
2902
  : "This package declares no dependencies.",
2905
2903
  );
2906
2904
  }
@@ -350,8 +350,7 @@ export function publishesContentPages(config) {
350
350
  * @property {string} [stage] Compiled LevelDB packs.
351
351
  * @property {string} [unpack] Where `unpack` extracts JSON back to.
352
352
  * @property {string} [foreignCache] Where a dependency declaring
353
- * `itemCatalog: true` or
354
- * `assetArchive: true` is unpacked.
353
+ * `itemCatalog: true` is unpacked.
355
354
  * Inbound, and fetched rather than
356
355
  * committed.
357
356
  * @property {string} [metadataCache] Where a dependency's published content
@@ -474,10 +473,6 @@ export function publishesContentPages(config) {
474
473
  * its Item packs, so the actors pass can
475
474
  * resolve embedded items this repository
476
475
  * does not hold. Needs a `manifest`.
477
- * @property {boolean} [assetArchive] Whether `deps fetch` unpacks this
478
- * dependency's release archive for its
479
- * asset bytes alone, building no item
480
- * catalogue from it. Needs a `manifest`.
481
476
  * @property {boolean} [contentIndex] Whether `deps fetch` fetches this
482
477
  * dependency's content index. Default
483
478
  * `true`. `false` declares the dependency
@@ -486,13 +481,6 @@ export function publishesContentPages(config) {
486
481
  * `itemCatalog: true` on the same entry,
487
482
  * since a catalogue is fetched from the same
488
483
  * index.
489
- * @property {boolean} [assetReplacement] Whether this dependency's asset
490
- * tree answers this package's own asset
491
- * addresses ahead of its local record.
492
- * Default `false`. Refuses `contentIndex:
493
- * false` on the same entry, since a
494
- * replacement with no fetched index to
495
- * check against resolves nothing.
496
484
  */
497
485
 
498
486
  /**
@@ -859,9 +847,7 @@ export const RELATIONSHIP_KEYS = [
859
847
  "manifest",
860
848
  "compatibility",
861
849
  "itemCatalog",
862
- "assetArchive",
863
850
  "contentIndex",
864
- "assetReplacement",
865
851
  ];
866
852
  const AUTHOR_KEYS = ["name", "email", "url", "discord", "role"];
867
853
  /**
@@ -2611,23 +2597,6 @@ function normalizeRelationships(value) {
2611
2597
  }
2612
2598
  spec.itemCatalog = rel.itemCatalog;
2613
2599
  }
2614
- // Opt-in, sibling to `itemCatalog`: unpack this dependency's
2615
- // release archive for its asset bytes alone, building no item
2616
- // catalogue from it. Buys the archive for a package with no
2617
- // items of its own to extract — an asset-replacement source
2618
- // ships no Item packs and has no use for `itemCatalog: true`.
2619
- if (rel.assetArchive !== undefined) {
2620
- if (typeof rel.assetArchive !== "boolean") {
2621
- fail(`${at}.assetArchive`, "must be true or false");
2622
- }
2623
- if (rel.assetArchive && spec.manifest === undefined) {
2624
- fail(
2625
- `${at}.assetArchive`,
2626
- "needs a `manifest` naming the package to fetch",
2627
- );
2628
- }
2629
- spec.assetArchive = rel.assetArchive;
2630
- }
2631
2600
  // Opt-out: declares the dependency for the Foundry manifest
2632
2601
  // only, so `deps fetch` fetches no content index for it and a
2633
2602
  // wikilink into it is refused rather than silently dead. A
@@ -2646,26 +2615,6 @@ function normalizeRelationships(value) {
2646
2615
  }
2647
2616
  spec.contentIndex = rel.contentIndex;
2648
2617
  }
2649
- // Opt-in: this dependency's asset tree answers this
2650
- // package's own asset addresses ahead of its local record —
2651
- // the "rewrite table" `engine/asset-replacement.mjs` reads.
2652
- // A replacement with no fetched index to check against
2653
- // resolves nothing, so it cannot pair with
2654
- // `contentIndex: false`.
2655
- if (rel.assetReplacement !== undefined) {
2656
- if (typeof rel.assetReplacement !== "boolean") {
2657
- fail(`${at}.assetReplacement`, "must be true or false");
2658
- }
2659
- if (rel.assetReplacement && rel.contentIndex === false) {
2660
- fail(
2661
- `${at}.assetReplacement`,
2662
- "cannot be true together with `contentIndex: false` — a " +
2663
- "replacement with no fetched index to check against resolves " +
2664
- "nothing",
2665
- );
2666
- }
2667
- spec.assetReplacement = rel.assetReplacement;
2668
- }
2669
2618
  return Object.freeze(spec);
2670
2619
  }),
2671
2620
  );
package/docs/api.md CHANGED
@@ -2624,14 +2624,15 @@ occupies one line and the file ends with a newline.
2624
2624
  `@heroiclands/package-build/engine/dictionary-layout` renders SQL results as
2625
2625
  Markdown for the dictionary or glossary on its owner's note:
2626
2626
 
2627
- | Export | Signature | Returns | Use it when |
2628
- | ------------------------- | ------------------------------------ | -------------------------- | ----------------------------------------------------------------------------------- |
2629
- | `LAYOUT_REQUIRED_COLUMNS` | `const LAYOUT_REQUIRED_COLUMNS` | Required columns by layout | Checking the columns a dictionary or glossary query must select. |
2630
- | `COMMON_MARK` | `const COMMON_MARK` | `string` | Reading the mark a common glossary entry opens with. |
2631
- | `DICTIONARY_ENTRY_CLASS` | `const DICTIONARY_ENTRY_CLASS` | `string` | Identifying generated headword spans that are native dictionary targets in Foundry. |
2632
- | `dictionaryEntryPlugin` | `dictionaryEntryPlugin(md)` | `void` | Registering native dictionary headword rendering on the Foundry Markdown parser. |
2633
- | `renderDictionary` | `renderDictionary(result, options?)` | `string` | Rendering a language's words with classes, etymology, senses and citations. |
2634
- | `renderGlossary` | `renderGlossary(result, options?)` | `string` | Rendering an owner's glossary entries, ranks and offices. |
2627
+ | Export | Signature | Returns | Use it when |
2628
+ | ------------------------- | ------------------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------ |
2629
+ | `LAYOUT_REQUIRED_COLUMNS` | `const LAYOUT_REQUIRED_COLUMNS` | Required columns by layout | Checking the columns a dictionary or glossary query must select. |
2630
+ | `COMMON_MARK` | `const COMMON_MARK` | `string` | Reading the mark a common glossary entry opens with. |
2631
+ | `DICTIONARY_ENTRY_CLASS` | `const DICTIONARY_ENTRY_CLASS` | `string` | Identifying generated headword spans that are native dictionary targets in Foundry. |
2632
+ | `LEXICAL_LINK_CLASS` | `const LEXICAL_LINK_CLASS` | `string` | Identifying the links an entry writes, which a site sets as text where they lead nowhere a reader can reach. |
2633
+ | `dictionaryEntryPlugin` | `dictionaryEntryPlugin(md)` | `void` | Registering native dictionary headword rendering on the Foundry Markdown parser. |
2634
+ | `renderDictionary` | `renderDictionary(result, options?)` | `string` | Rendering a language's words with classes, etymology, senses and citations. |
2635
+ | `renderGlossary` | `renderGlossary(result, options?)` | `string` | Rendering an owner's glossary entries, ranks and offices. |
2635
2636
 
2636
2637
  `result` is `{ columns: string[], rows: object[] }`. Both layouts require
2637
2638
  `name`, `senses` and `usage`; a missing column throws an error naming it.
@@ -2677,6 +2678,11 @@ headword's span and paragraph. `anchorsOf` maps this dictionary target to
2677
2678
  its containing page's UUID with the word fragment; generic authored spans
2678
2679
  keep their containing-page behavior.
2679
2680
 
2681
+ `LEXICAL_LINK_CLASS` is `"lexical-ref"`. Every link an entry writes to
2682
+ another note, a citation, a headword's link to its dictionary word or a
2683
+ wikilink in a gloss, carries it as an attribute. A site build sets such a link
2684
+ as its text when the target is a page a reader cannot reach.
2685
+
2680
2686
  ## Automatic dictionary and glossary sections
2681
2687
 
2682
2688
  `@heroiclands/package-build/engine/lexical-sections` derives and inserts the
@@ -490,7 +490,11 @@ column stacks one or more **entries**, joined by `:`. An entry is
490
490
  - **`mapping`** names a [mapping note](#mapping-notes), which rewrites the
491
491
  line before it is set. Left out, the line is set as written.
492
492
  - **`font`** names a face or a generic family, as `font=` does. Left out, the
493
- line is set in the roman serif.
493
+ line keeps the page's normal typeface.
494
+
495
+ A language-only entry stays in Roman letters even when the language's
496
+ `data.writtenIn` names its usual script. Ordinary language-marked prose still
497
+ selects that script automatically; columns use the entry's explicit mapping.
494
498
 
495
499
  A poem has at most two columns, and either may be left out. In every column
496
500
  the first entry is set in the normal tone and each later one in grey.
@@ -805,7 +809,12 @@ is one of them.
805
809
 
806
810
  **With `lang=`, the language's dictionary comes first.** Where
807
811
  [`languages.<name>.note`](../configuration.md#languages) names the language's
808
- note, each word of the run is looked up in its `data.words`:
812
+ note, each word of the run is looked up in its `data.words` and the words of
813
+ its `data.family` chain. The nearest exact NFC form supplies the entire word
814
+ entry, including variants and native spellings; an override replaces the whole
815
+ ancestor entry. Case and word separators remain part of that identity.
816
+ Grammar, registered names and the default writing script remain the daughter's
817
+ own. An inherited native spelling applies only to the map and face it names:
809
818
 
810
819
  1. **A word whose entry states a `native` form for the map** is written by it:
811
820
  the form stated for the run's face where there is one, else the form stated
@@ -1469,7 +1478,7 @@ A column's heading is its SQL alias, so `AS "Name"` is what a reader sees. A cel
1469
1478
  | `joining` | One row per entry of a language note's `data.sounds.joining`: `first`, `second`, `written` and `example`. |
1470
1479
  | `joins` | One row per entry of a language note's `data.sounds.joins`: `meeting`, `rule`, `letters` and `"where"`. |
1471
1480
  | `marks` | One row per entry of a language note's or a spelling guide's `data.sounds.marks`: `mark`, `letters`, `kind` and `"limit"`. |
1472
- | `skeleton` | One row per entry of a language note's `data.sounds.skeleton`: `second` and `between`. |
1481
+ | `skeleton` | One row per entry of a language note's `data.sounds.skeleton`: `second`, `third` and `between`. |
1473
1482
  | `frames` | One row per frame of a language note's `data.sounds.frames`: `frame`, `shape`, `class`, `makes` and `examples` as `{ root, form }`. |
1474
1483
  | `read_past` | One row per entry of a language note's `data.sounds.readPast`: `written`, `readAs` and `what`. |
1475
1484
  | `mutations` | One row per entry of a language note's `data.sounds.mutations`: `mutation`, `sound`, `becomes` and `example`. |
package/docs/commands.md CHANGED
@@ -1718,13 +1718,11 @@ package-build deps fetch [--from <zip|dir>] [--id <id>]
1718
1718
  The only action is `fetch`, which fills three caches under `build/cache/`:
1719
1719
  the **content index** of every declared dependency and of every
1720
1720
  `recommends` or `conflicts` relationship that declares `itemCatalog: true`,
1721
- the **item catalogue or
1722
- asset archive** of those that additionally declare `itemCatalog: true` or
1723
- `assetArchive: true`, and the **site navigation** —
1721
+ the **item catalogue** of those that additionally declare `itemCatalog: true`,
1722
+ and the **site navigation** —
1724
1723
  `https://www.heroiclands.org/nav.json`, the header menu every package site
1725
1724
  renders, fetched for every package because every package publishes a site.
1726
- A relationship declaring both `itemCatalog: true` and `assetArchive: true`
1727
- is fetched once. Its own command rather than a step of `package compile` or
1725
+ Its own command rather than a step of `package compile` or
1728
1726
  `site`, so neither reaches the network — a build that downloads silently is
1729
1727
  not reproducible and hides a dependency's version change behind a passing
1730
1728
  run. Each cache is stamped complete only once its fetch finishes, so a
@@ -1766,7 +1764,7 @@ including when the repository declares no dependencies at all.
1766
1764
  ```
1767
1765
  $ package-build deps fetch
1768
1766
  […] Fetched the site navigation to build/cache/navigation/nav.json.
1769
- […] No relationship declares `itemCatalog: true` or `assetArchive: true`; nothing to fetch.
1767
+ […] No relationship declares `itemCatalog: true`; nothing to fetch.
1770
1768
  […] This package declares no dependencies.
1771
1769
 
1772
1770
  $ package-build deps fetch --from build/dist/module.zip
@@ -606,7 +606,7 @@ HeroicLands layout, resolved against `rootDir`:
606
606
  | `paths.packJson` | `build/packs-json` | Build-only per-entry JSON intermediate. |
607
607
  | `paths.stage` | `build/stage/packs` | Compiled LevelDB packs. |
608
608
  | `paths.unpack` | `build/tmp/packs` | Where `unpack` extracts JSON back to. |
609
- | `paths.foreignCache` | `build/cache/foreign` | Where a dependency declaring `itemCatalog: true` or `assetArchive: true` is unpacked. |
609
+ | `paths.foreignCache` | `build/cache/foreign` | Where a dependency declaring `itemCatalog: true` is unpacked. |
610
610
  | `paths.metadataCache` | `build/cache/metadata` | Where a published content index is fetched to, for every declared dependency and every relationship declaring `itemCatalog: true`. |
611
611
  | `paths.navigationCache` | `build/cache/navigation` | Where the site navigation heroiclands.org publishes is fetched to, for the site's menu. |
612
612
 
@@ -1228,7 +1228,7 @@ writes its own `sitemap.xml` whether or not it states this key.
1228
1228
  ```yaml
1229
1229
  site:
1230
1230
  base: /
1231
- sitemaps: [sohl, hm3, thalorna, kethira, thalornaaltart, harnensemble, harnadventures]
1231
+ sitemaps: [sohl, hm3, thalorna, kethira, harnensemble, harnadventures]
1232
1232
  ```
1233
1233
 
1234
1234
  `site.mergeIndexes` names the package sites, by `contentPackage`, whose search
@@ -1275,7 +1275,7 @@ site:
1275
1275
  projects: doc-projects
1276
1276
  feed: blog
1277
1277
  tags: true
1278
- sitemaps: [sohl, hm3, thalorna, kethira, thalornaaltart, harnensemble, harnadventures]
1278
+ sitemaps: [sohl, hm3, thalorna, kethira, harnensemble, harnadventures]
1279
1279
  mergeIndexes: [sohl, thalorna, kethira, harnensemble]
1280
1280
  ```
1281
1281
 
@@ -1645,17 +1645,15 @@ system relationship it declares — see [`stats.systemVersion`](#statssystemvers
1645
1645
 
1646
1646
  Each entry, in any of the four lists:
1647
1647
 
1648
- | Key (under `relationships.<kind>[]`) | Type | Required | Default |
1649
- | ------------------------------------------ | ------------------------------- | -------- | ------- |
1650
- | `relationships.systems[].id` | string | yes | — |
1651
- | `relationships.systems[].contentPackage` | string | no | the id |
1652
- | `relationships.systems[].type` | string | no | none |
1653
- | `relationships.systems[].manifest` | string | no | none |
1654
- | `relationships.systems[].compatibility` | object, `{minimum?, verified?}` | no | none |
1655
- | `relationships.systems[].itemCatalog` | boolean | no | `false` |
1656
- | `relationships.systems[].assetArchive` | boolean | no | `false` |
1657
- | `relationships.systems[].contentIndex` | boolean | no | `true` |
1658
- | `relationships.systems[].assetReplacement` | boolean | no | `false` |
1648
+ | Key (under `relationships.<kind>[]`) | Type | Required | Default |
1649
+ | ---------------------------------------- | ------------------------------- | -------- | ------- |
1650
+ | `relationships.systems[].id` | string | yes | — |
1651
+ | `relationships.systems[].contentPackage` | string | no | the id |
1652
+ | `relationships.systems[].type` | string | no | none |
1653
+ | `relationships.systems[].manifest` | string | no | none |
1654
+ | `relationships.systems[].compatibility` | object, `{minimum?, verified?}` | no | none |
1655
+ | `relationships.systems[].itemCatalog` | boolean | no | `false` |
1656
+ | `relationships.systems[].contentIndex` | boolean | no | `true` |
1659
1657
 
1660
1658
  (the same keys apply under `requires[]`, `recommends[]` and
1661
1659
  `conflicts[]`.)
@@ -1664,7 +1662,7 @@ Each entry, in any of the four lists:
1664
1662
 
1665
1663
  > ``package-build config: `relationships.<kind>[<index>].id` must be a non-empty string.``
1666
1664
 
1667
- > ``package-build config: `relationships.<kind>[<index>].<key>` is not a recognized option (expected one of: id, contentPackage, type, manifest, compatibility, itemCatalog, assetArchive, contentIndex, assetReplacement).``
1665
+ > ``package-build config: `relationships.<kind>[<index>].<key>` is not a recognized option (expected one of: id, contentPackage, type, manifest, compatibility, itemCatalog, contentIndex).``
1668
1666
 
1669
1667
  `contentPackage` names what the other package's _content_ is called, where
1670
1668
  that differs from its Foundry id. A note addresses a file by the content
@@ -1685,31 +1683,6 @@ embedded-item addresses the compile does. It requires a `manifest`:
1685
1683
 
1686
1684
  > ``package-build config: `relationships.<kind>[<index>].itemCatalog` needs a `manifest` naming the package to fetch.``
1687
1685
 
1688
- `assetArchive` opts into unpacking the named package's release archive for
1689
- its asset bytes alone — the sibling of `itemCatalog`, for a dependency whose
1690
- bytes are wanted and whose items are not. It builds no item catalogue from
1691
- the archive, which is what distinguishes it from `itemCatalog: true`. It
1692
- requires a `manifest`:
1693
-
1694
- > ``package-build config: `relationships.<kind>[<index>].assetArchive` must be true or false.``
1695
-
1696
- > ``package-build config: `relationships.<kind>[<index>].assetArchive` needs a `manifest` naming the package to fetch.``
1697
-
1698
- A relationship with no items of its own to extract, such as an asset
1699
- replacement module, declares only `assetArchive: true`:
1700
-
1701
- ```yaml
1702
- relationships:
1703
- requires:
1704
- - id: thalornaaltart
1705
- manifest: https://…/releases/latest/download/module.json
1706
- compatibility: { verified: "1.0.0" }
1707
- assetArchive: true
1708
- ```
1709
-
1710
- A relationship declaring both `itemCatalog: true` and `assetArchive: true` is
1711
- fetched once: `deps fetch` does not download the archive twice for one entry.
1712
-
1713
1686
  `contentIndex` and `itemCatalog` are the two edges a relationship may declare,
1714
1687
  and a package may have either without the other. `itemCatalog` says a
1715
1688
  dependency supplies _items_; `contentIndex`, `true` by default, says
@@ -1729,35 +1702,6 @@ demand.
1729
1702
 
1730
1703
  > ``package-build config: `relationships.<kind>[<index>].contentIndex` cannot be false together with `itemCatalog: true` — a catalogue is fetched from the same index.``
1731
1704
 
1732
- `assetReplacement` opts a relationship into serving this package's own asset
1733
- addresses from the named dependency's tree instead of its local one —
1734
- `engine/asset-replacement.mjs`'s `resolveAssetReplacement` is what reads the
1735
- declaration. Off by default: declaring a dependency is not the same as
1736
- wanting its pictures in place of the ones this package ships itself. It
1737
- requires a fetched index to check the replacement against, so it cannot pair
1738
- with `contentIndex: false`:
1739
-
1740
- ```yaml
1741
- relationships:
1742
- requires:
1743
- - id: thalornaaltart
1744
- manifest: https://…/releases/latest/download/module.json
1745
- assetReplacement: true
1746
- contentIndex: true
1747
- ```
1748
-
1749
- With that declared, an address `thalorna` would otherwise answer itself —
1750
- `thalorna-none-image-thorn` — resolves against
1751
- `thalornaaltart-none-image-thorn` first, falling back to `thalorna`'s own
1752
- record when `thalornaaltart` carries no file at that address. A package
1753
- declaring more than one `assetReplacement: true` relationship is tried in
1754
- the order the relationships are declared, and the first one carrying the
1755
- address wins.
1756
-
1757
- > ``package-build config: `relationships.<kind>[<index>].assetReplacement` must be true or false.``
1758
-
1759
- > ``package-build config: `relationships.<kind>[<index>].assetReplacement` cannot be true together with `contentIndex: false` — a replacement with no fetched index to check against resolves nothing.``
1760
-
1761
1705
  ### `systems`
1762
1706
 
1763
1707
  **Type:** object (`{id: spec}`) · **Optional** · default `{}`. Refused in a
@@ -247,7 +247,9 @@ generated after a note's text (Within, Governed by, Governed places,
247
247
  Chronology, Events, Accounts, What followed, In song and story). Each is drawn
248
248
  without a link to a page outside the reachable set, and a section left with
249
249
  nothing under it is not drawn. An infobox value that names an unreachable page
250
- is set as plain text. A link written in prose or produced by a query is kept
250
+ is set as plain text. So is a link in a dictionary or glossary entry, whether
251
+ it names a word's entry, cites a note or sits in a gloss; it does not make its
252
+ target reachable. A link written in prose or produced by a query is kept
251
253
  wherever it points, and it is what makes its target reachable.
252
254
 
253
255
  A page that is not reachable is the way to preview a page in place. Write the