@heroiclands/package-build 23.4.0 → 23.5.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.
- package/CHANGELOG.md +34 -0
- package/README.md +29 -25
- package/assets/images/provenance.yaml +1 -0
- package/bin/package-build.mjs +259 -28
- package/ci/prettier.mjs +73 -0
- package/config.mjs +10 -0
- package/container.mjs +232 -1
- package/content-config.mjs +5 -1
- package/docs/api.md +100 -52
- package/docs/authoring/assets.md +16 -1
- package/docs/commands.md +154 -7
- package/docs/configuration.md +39 -2
- package/docs/content-format.md +30 -6
- package/docs/guides/e2e.md +38 -0
- package/docs/guides/icons.md +5 -0
- package/docs/guides/release-and-deploy.md +36 -1
- package/docs/reference/format-details.md +218 -50
- package/docs/reference/note-types.md +71 -71
- package/engine/asset-index.mjs +63 -22
- package/engine/asset-references.mjs +355 -0
- package/engine/asset-shipping.mjs +363 -0
- package/engine/asset-types.mjs +70 -0
- package/engine/base-compiler.mjs +24 -1
- package/engine/cdn-publish.mjs +618 -0
- package/engine/index.mjs +6 -0
- package/engine/note-vocabulary.mjs +40 -2
- package/engine/pathnames.mjs +21 -10
- package/engine/rank-ladder.mjs +40 -16
- package/engine/scenes.mjs +1 -1
- package/engine/standing-terms.mjs +3 -1
- package/package.json +4 -3
- package/packagebuild-metadata.jsonl +13 -13
- package/release.mjs +69 -7
- package/sohl/actors.mjs +12 -4
- package/sohl/default-item-art.mjs +23 -19
- package/types/config.d.mts +7 -0
- package/types/container.d.mts +137 -1
- package/types/engine/asset-index.d.mts +3 -2
- package/types/engine/asset-references.d.mts +136 -0
- package/types/engine/asset-shipping.d.mts +240 -0
- package/types/engine/asset-types.d.mts +36 -0
- package/types/engine/base-compiler.d.mts +7 -1
- package/types/engine/cdn-publish.d.mts +311 -0
- package/types/engine/index.d.mts +2 -0
- package/types/engine/pathnames.d.mts +2 -1
- package/types/engine/rank-ladder.d.mts +25 -6
- package/types/release.d.mts +5 -3
- package/types/sohl/default-item-art.d.mts +2 -1
|
@@ -917,7 +917,9 @@ of ownership** and every surface derives its own address from it.
|
|
|
917
917
|
|
|
918
918
|
**The first segment names the package, when an `assets/` follows it.**
|
|
919
919
|
Everything after that `assets/` is the _suffix_ — the path inside the package's
|
|
920
|
-
|
|
920
|
+
`assets/` directory, and the one piece every derived form is built from. A
|
|
921
|
+
suffix under `icons/` or `images/` reaches Foundry and the website in the
|
|
922
|
+
deployed layout, by type root and basename alone. A pathname
|
|
921
923
|
that does not open `<package>/assets/` belongs to the package being compiled,
|
|
922
924
|
and the whole of it is the suffix.
|
|
923
925
|
|
|
@@ -931,7 +933,7 @@ ships as the Foundry module `harn-ensemble`) writing `images/map.webp`:
|
|
|
931
933
|
|
|
932
934
|
| Surface | Address |
|
|
933
935
|
| ----------- | ---------------------------------------------------------- |
|
|
934
|
-
| **Foundry** | `modules/harn-ensemble/
|
|
936
|
+
| **Foundry** | `modules/harn-ensemble/images/map.webp` |
|
|
935
937
|
| **Local** | `assets/images/map.webp` |
|
|
936
938
|
| **Web** | `https://cdn.heroiclands.org/harnensemble/images/map.webp` |
|
|
937
939
|
| **Book** | `assets/images/map.webp`, staged beside the Typst source |
|
|
@@ -941,9 +943,9 @@ system ships and this repository does not hold:
|
|
|
941
943
|
|
|
942
944
|
| Surface | Address |
|
|
943
945
|
| ----------- | ------------------------------------------------------------- |
|
|
944
|
-
| **Foundry** | `systems/sohl/
|
|
946
|
+
| **Foundry** | `systems/sohl/icons/shieldnn.svg` |
|
|
945
947
|
| **Local** | `assets/icons/noun/shieldnn.svg`, in the `sohl` repository |
|
|
946
|
-
| **Web** | `https://cdn.heroiclands.org/sohl/icons/
|
|
948
|
+
| **Web** | `https://cdn.heroiclands.org/sohl/icons/shieldnn.svg` |
|
|
947
949
|
| **Book** | not carried, unless a declared replacement carries it instead |
|
|
948
950
|
|
|
949
951
|
**The content package name and Foundry id are separate values.**
|
|
@@ -1863,7 +1865,7 @@ nothing about itself, compiles into no document, and publishes no page, so the
|
|
|
1863
1865
|
| `path` | the walk | Where the file sits inside the emitting package's asset directory. |
|
|
1864
1866
|
| `attribution` | provenance | The person holding the rights, to whom attribution is legally due. |
|
|
1865
1867
|
| `source` | provenance | Where it came from — a URL, or a sentence. |
|
|
1866
|
-
| `ai` | provenance | Whether the file is machine-generated — strictly the YAML boolean `true` or `false`; any other value is a finding, never a stringified record.
|
|
1868
|
+
| `ai` | provenance | Whether the file is machine-generated — strictly the YAML boolean `true` or `false`; any other value is a finding, never a stringified record. Required: a record that leaves it out is a finding, never read as `false`. |
|
|
1867
1869
|
| `license` | provenance | The licence it is used under — an SPDX identifier, or terms. |
|
|
1868
1870
|
| `notes` | provenance | Anything else a person reading the attribution needs. |
|
|
1869
1871
|
| `role` | provenance | What the picture is for — `portrait`, `emblem`, `banner`, `plate` or `map`. Absent for an ordinary picture; a value outside that set is a finding. The `image` type only — a value on an `icon` address is a finding and is dropped. |
|
|
@@ -1874,17 +1876,21 @@ Every field is present on every record, blank where nothing states one. A fixed
|
|
|
1874
1876
|
shape is what lets a consumer read `asset.license` without first asking whether
|
|
1875
1877
|
the package happened to record one.
|
|
1876
1878
|
|
|
1877
|
-
**`path` is
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
|
1883
|
-
|
|
|
1884
|
-
|
|
|
1885
|
-
|
|
|
1886
|
-
|
|
1887
|
-
|
|
1879
|
+
**`path` is the source path.** The record is emitted by the package holding
|
|
1880
|
+
the bytes, so the path is where the file sits in that package's repository. The
|
|
1881
|
+
book stages from it; Foundry and the website serve the **deployed layout**, the
|
|
1882
|
+
type root and the basename alone:
|
|
1883
|
+
|
|
1884
|
+
| Consumer | `thalorna-none-image-thorn` resolves to |
|
|
1885
|
+
| -------- | ----------------------------------------------------------- |
|
|
1886
|
+
| Web | `<cdn base>/thalorna/images/thorn.webp` |
|
|
1887
|
+
| Book | `<asset base>/thalorna/images/beings/characters/thorn.webp` |
|
|
1888
|
+
| Foundry | `modules/thalorna/images/thorn.webp` |
|
|
1889
|
+
|
|
1890
|
+
Foundry and the website serve a picture under `icons/` or `images/` flat, by
|
|
1891
|
+
type root and basename — see [what a package ships](#what-a-package-ships);
|
|
1892
|
+
every other file keeps its path under `assets/`, and the local and book forms
|
|
1893
|
+
keep the repository's arrangement. Foundry paths use the **Foundry package id**. The two values are both `thalorna`
|
|
1888
1894
|
for this image; `harnensemble` content uses `harn-ensemble` in its Foundry paths.
|
|
1889
1895
|
|
|
1890
1896
|
##### What a role declares
|
|
@@ -1987,19 +1993,131 @@ One address resolves its record in this order:
|
|
|
1987
1993
|
2. Otherwise the nearest `provenance.yaml`, searching the file's own directory
|
|
1988
1994
|
and then its ancestors, **stopping at the type root**. A record above the root
|
|
1989
1995
|
would speak for trees it says nothing about.
|
|
1990
|
-
3. Otherwise nothing, and
|
|
1991
|
-
|
|
1996
|
+
3. Otherwise nothing, and that is a **finding at the file**: every asset is
|
|
1997
|
+
covered by a record, because the stage decides from the record whether the
|
|
1998
|
+
file ships.
|
|
1999
|
+
|
|
2000
|
+
Resolution is per file. One directory routinely holds files its own
|
|
2001
|
+
`provenance.yaml` covers beside files a sidecar answers for, and each is
|
|
2002
|
+
resolved on its own.
|
|
1992
2003
|
|
|
1993
2004
|
**The nearest record is the whole answer.** It is never merged with the one
|
|
1994
2005
|
above it, so a record states every key it means to claim — which is what lets a
|
|
1995
2006
|
reader open one file and know what the tree beneath it carries, instead of
|
|
1996
2007
|
resolving a chain by hand.
|
|
1997
2008
|
|
|
1998
|
-
That is also why `attribution` and `
|
|
1999
|
-
|
|
2000
|
-
record stating
|
|
2001
|
-
|
|
2002
|
-
|
|
2009
|
+
That is also why `attribution`, `license` and `ai` are **required in every
|
|
2010
|
+
record**: a key left out is not inherited from above, it is simply absent, so a
|
|
2011
|
+
record stating none leaves every file it covers with no rights holder, no terms,
|
|
2012
|
+
or no statement of whether a machine made it. Omitting one is a finding at the
|
|
2013
|
+
record, which an empty file is held to as well. An unstated `ai` is never read as
|
|
2014
|
+
`false`. `source`, `notes` and `role` stay optional, because a blank is a
|
|
2015
|
+
truthful answer for each of them.
|
|
2016
|
+
|
|
2017
|
+
##### What a package ships
|
|
2018
|
+
|
|
2019
|
+
The repository keeps every picture; the Foundry package carries a filtered copy.
|
|
2020
|
+
`package-build assets` stages a file from `assets/icons/` or `assets/images/`
|
|
2021
|
+
only when its resolved record says `ai: false` **and** its `license` is one of:
|
|
2022
|
+
|
|
2023
|
+
| Licence | Spelled |
|
|
2024
|
+
| ---------------------------- | ---------------------------- |
|
|
2025
|
+
| Public domain | `LicenseRef-PublicDomain` |
|
|
2026
|
+
| Creative Commons Zero | `CC0-1.0`, or `CC0` |
|
|
2027
|
+
| Creative Commons Attribution | `CC-BY-3.0`, `CC-BY-4.0` |
|
|
2028
|
+
| Attribution-ShareAlike | `CC-BY-SA-4.0` |
|
|
2029
|
+
| Noun Project Pro | `LicenseRef-NounProject-Pro` |
|
|
2030
|
+
|
|
2031
|
+
The spelling is matched exactly; nothing is normalised. A package adds licences
|
|
2032
|
+
to this list with `packageBuild.shippingLicenses`, and ships under the list
|
|
2033
|
+
together with its additions. `ai: true` is never shipped, whatever the
|
|
2034
|
+
additions say. Audio is not filtered
|
|
2035
|
+
and not laid out flat — a package stages it with an ordinary
|
|
2036
|
+
`packageBuild.assets` row.
|
|
2037
|
+
|
|
2038
|
+
**The deployed layout is flat.** A shipped picture sits at the package root as
|
|
2039
|
+
`icons/<basename>` or `images/<basename>`, whatever directories hold it in the
|
|
2040
|
+
repository. The root is the type and the basename is the shortcode with its
|
|
2041
|
+
extension, so the path follows from the address alone, and a root's shortcodes
|
|
2042
|
+
being one namespace is what keeps the flattening collision-free. The same
|
|
2043
|
+
layout serves Foundry (`modules/thalorna/images/thorn.webp`), the website's CDN
|
|
2044
|
+
(`<cdn base>/thalorna/images/thorn.webp`), and every location a world copies
|
|
2045
|
+
the pictures to.
|
|
2046
|
+
|
|
2047
|
+
**The package's asset set**, `asset-sets/default.json` under the package
|
|
2048
|
+
root, lists what it ships. The name is fixed, so a world always finds the
|
|
2049
|
+
package's own set there:
|
|
2050
|
+
|
|
2051
|
+
```json
|
|
2052
|
+
{
|
|
2053
|
+
"name": "Thalorna — shipped art",
|
|
2054
|
+
"package": "thalorna",
|
|
2055
|
+
"assets": [
|
|
2056
|
+
{
|
|
2057
|
+
"address": "thalorna-none-icon-anvil",
|
|
2058
|
+
"source": "../icons/anvil.svg",
|
|
2059
|
+
"target": "icons/anvil.svg",
|
|
2060
|
+
"size": 412
|
|
2061
|
+
}
|
|
2062
|
+
]
|
|
2063
|
+
}
|
|
2064
|
+
```
|
|
2065
|
+
|
|
2066
|
+
| Key | What it says |
|
|
2067
|
+
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
2068
|
+
| `name` | The set's display name: the package's manifest title with ` — shipped art` appended, or the content package without a title. |
|
|
2069
|
+
| `package` | The content package — the addresses' first segment, not the Foundry id. |
|
|
2070
|
+
| `assets` | One entry per file, in `target` order. |
|
|
2071
|
+
| `address` | The file's canonical address. |
|
|
2072
|
+
| `target` | The file's path relative to the location's root, in the deployed layout, extension included. |
|
|
2073
|
+
| `source` | Where the file is fetched from, resolved against the URL of the set file holding it — `new URL(source, setUrl)`. The package's own set sits in `asset-sets/`, so its `source` is `../<target>`. |
|
|
2074
|
+
| `size` | The staged file's size in bytes. |
|
|
2075
|
+
|
|
2076
|
+
`target` is never the record's source `path`. Each release attaches
|
|
2077
|
+
`icons.zip` and `images.zip` beside the package archive: one picture root of
|
|
2078
|
+
the stage each, with `asset-sets/default.json`, for a GM placing the files by
|
|
2079
|
+
hand.
|
|
2080
|
+
|
|
2081
|
+
##### Every reference states its address
|
|
2082
|
+
|
|
2083
|
+
A compiled document names a picture by its Foundry path, and beside each
|
|
2084
|
+
reference it states the picture's canonical address, so a world can rebuild the
|
|
2085
|
+
path for wherever it keeps the file:
|
|
2086
|
+
|
|
2087
|
+
- **HTML.** Each `<img>` whose `src` names an asset carries
|
|
2088
|
+
`data-asset="<address>"`.
|
|
2089
|
+
- **Path fields.** The address sits in `flags.<system>.assets` on the document
|
|
2090
|
+
holding the field, as nested objects mirroring the field's path — never a
|
|
2091
|
+
dotted key, which Foundry's `expandObject` splits. `<system>` is the system
|
|
2092
|
+
the document is compiled for, its `_stats.systemId`.
|
|
2093
|
+
|
|
2094
|
+
| Document | Flag on | Keys |
|
|
2095
|
+
| ------------------------------------------- | ---------------------- | ------------- |
|
|
2096
|
+
| Actor, Item, ActiveEffect, Macro, RollTable | the document | `img` |
|
|
2097
|
+
| Actor token art | `prototypeToken.flags` | `texture.src` |
|
|
2098
|
+
| Table result | the result | `img` |
|
|
2099
|
+
| Journal image page | the page | `src` |
|
|
2100
|
+
|
|
2101
|
+
```json
|
|
2102
|
+
"img": "modules/thalorna/icons/anvil.svg",
|
|
2103
|
+
"flags": { "sohl": { "assets": { "img": "thalorna-none-icon-anvil" } } },
|
|
2104
|
+
"prototypeToken": {
|
|
2105
|
+
"texture": { "src": "modules/thalorna/icons/anvil.svg" },
|
|
2106
|
+
"flags": { "sohl": { "assets": { "texture": { "src": "thalorna-none-icon-anvil" } } } }
|
|
2107
|
+
}
|
|
2108
|
+
```
|
|
2109
|
+
|
|
2110
|
+
Embedded documents — an actor's items and effects, a journal's pages, an
|
|
2111
|
+
Adventure's contents — each carry their own. A path or an `<img>` naming no
|
|
2112
|
+
asset is left as it is.
|
|
2113
|
+
|
|
2114
|
+
**A picture the package does not ship draws a stand-in.** A reference to an
|
|
2115
|
+
excluded picture compiles to its package's own stand-in,
|
|
2116
|
+
`<package>-none-icon-missing` or `<package>-none-image-missing` — a picture
|
|
2117
|
+
under `icons/` or `images/` named `missing`, human-made and licensed to ship —
|
|
2118
|
+
and keeps the excluded picture's address in its flag or `data-asset`. A
|
|
2119
|
+
package that leaves out a picture a note references and ships no stand-in of
|
|
2120
|
+
that type fails the build with an error at the referencing note.
|
|
2003
2121
|
|
|
2004
2122
|
##### A declared replacement resolves first
|
|
2005
2123
|
|
|
@@ -3688,6 +3806,13 @@ tattoo, scar or brand may show gear or a gesture, as in `a tattoo of a knight's
|
|
|
3688
3806
|
helmet`, and stands; the voice, impression, handedness, sterility and age rules
|
|
3689
3807
|
hold even for a mark.
|
|
3690
3808
|
|
|
3809
|
+
A condition is a feature only through what it shows. Its visible sign is a mark
|
|
3810
|
+
— `trembling hands`, `one eye missing`, `a withered left arm` — and a skin sign
|
|
3811
|
+
the complexion words cover goes in `complexion`, so healed pox is `pockmarked`
|
|
3812
|
+
and acne scarring `scarred`. A condition with no visible sign, such as epilepsy,
|
|
3813
|
+
haemophilia or a parasite, stays in the being's prose and is not an appearance
|
|
3814
|
+
fact at all.
|
|
3815
|
+
|
|
3691
3816
|
```yaml
|
|
3692
3817
|
data:
|
|
3693
3818
|
gender: female
|
|
@@ -3735,29 +3860,44 @@ The words, and what each means:
|
|
|
3735
3860
|
| `blue` | Blue | Unmixed blue, from pale ice to deep sea. |
|
|
3736
3861
|
| `brown` | Brown | Mid-brown, the iris pattern still legible in ordinary light. |
|
|
3737
3862
|
| `dark_brown` | Dark Brown | Brown so deep the iris barely separates from the pupil. |
|
|
3863
|
+
| `gold` | Gold | A bright metallic yellow iris, brighter and colder than `amber`. |
|
|
3738
3864
|
| `grey` | Grey | Grey or grey-blue, cool and without green. |
|
|
3739
3865
|
| `green` | Green | Green dominant, with no brown ring worth naming. |
|
|
3740
3866
|
| `hazel` | Hazel | Brown and green together, often shifting with the light; the commonest mixed eye. |
|
|
3867
|
+
| `red` | Red | An iris that is red, as in some undead and elder folk. |
|
|
3868
|
+
| `pink` | Pink | A pale pink or rose iris, as in albinism. |
|
|
3869
|
+
| `silver` | Silver | A grey iris with a bright metallic sheen rather than a dull cast. |
|
|
3741
3870
|
| `violet` | Violet | The pink-violet of an iris carrying no pigment. |
|
|
3871
|
+
| `white` | White | An iris white or near-white, so that the eye reads pale throughout. |
|
|
3872
|
+
| `yellow` | Yellow | A pale, flat yellow iris without the warmth of `amber`. |
|
|
3742
3873
|
|
|
3743
3874
|
**`data.appearance.hair_color`**
|
|
3744
3875
|
|
|
3745
|
-
| Word
|
|
3746
|
-
|
|
|
3747
|
-
| `auburn`
|
|
3748
|
-
| `black`
|
|
3749
|
-
| `blonde`
|
|
3750
|
-
| `brown`
|
|
3751
|
-
| `chestnut`
|
|
3752
|
-
| `dark_blonde`
|
|
3753
|
-
| `dark_brown`
|
|
3754
|
-
| `grey`
|
|
3755
|
-
| `
|
|
3756
|
-
| `
|
|
3757
|
-
| `
|
|
3758
|
-
| `
|
|
3759
|
-
| `
|
|
3760
|
-
| `
|
|
3876
|
+
| Word | Label | Meaning |
|
|
3877
|
+
| -------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
3878
|
+
| `auburn` | Auburn | Red-brown with the red dominant. |
|
|
3879
|
+
| `black` | Black | True black, with no brown cast in sunlight. |
|
|
3880
|
+
| `blonde` | Blonde | Light yellow, from near-white to wheat. |
|
|
3881
|
+
| `brown` | Brown | Mid-brown, neither dark nor reddish. |
|
|
3882
|
+
| `chestnut` | Chestnut | Mid-brown with a red cast, the brown dominant — between brown and auburn. |
|
|
3883
|
+
| `dark_blonde` | Dark Blonde | Blonde darkened towards light brown. |
|
|
3884
|
+
| `dark_brown` | Dark Brown | Brown approaching black, still brown in sunlight. |
|
|
3885
|
+
| `grey` | Grey | Grey throughout, with nothing of the original colour left to read. |
|
|
3886
|
+
| `greying_auburn` | Greying Auburn | Auburn still dominant, grey coming in. |
|
|
3887
|
+
| `greying_black` | Greying Black | Black still dominant, grey coming in. |
|
|
3888
|
+
| `greying_blonde` | Greying Blonde | Blonde still dominant, grey coming in. |
|
|
3889
|
+
| `greying_brown` | Greying Brown | Brown still dominant, grey coming in. |
|
|
3890
|
+
| `greying_chestnut` | Greying Chestnut | Chestnut still dominant, grey coming in. |
|
|
3891
|
+
| `greying_dark_blonde` | Greying Dark Blonde | Dark Blonde still dominant, grey coming in. |
|
|
3892
|
+
| `greying_dark_brown` | Greying Dark Brown | Dark Brown still dominant, grey coming in. |
|
|
3893
|
+
| `greying_light_brown` | Greying Light Brown | Light Brown still dominant, grey coming in. |
|
|
3894
|
+
| `light_brown` | Light Brown | Brown lightened toward dark blonde: paler than `brown`, darker than `dark_blonde`. |
|
|
3895
|
+
| `greying_red` | Greying Red | Red still dominant, grey coming in. |
|
|
3896
|
+
| `greying_strawberry_blond` | Greying Strawberry Blond | Strawberry Blond still dominant, grey coming in. |
|
|
3897
|
+
| `red` | Red | Ginger or copper, the red unmixed with brown. |
|
|
3898
|
+
| `silver` | Silver | A bright metallic pale between white and grey: the silver of great age, or the natural silver some elder folk are born with. |
|
|
3899
|
+
| `strawberry_blond` | Strawberry Blond | Pale red-gold: blonde with a red cast, lighter than red. |
|
|
3900
|
+
| `white` | White | Wholly white, whether from age or from carrying no pigment. |
|
|
3761
3901
|
|
|
3762
3902
|
**`data.appearance.skin_color`**
|
|
3763
3903
|
|
|
@@ -4397,18 +4537,19 @@ a propertied or senatorial order supplies nearly everyone who holds them, it is
|
|
|
4397
4537
|
**Democracy**.
|
|
4398
4538
|
|
|
4399
4539
|
The distinction is not academic: it is the difference between a ladder whose top
|
|
4400
|
-
rungs are a class one is born or bought into, and
|
|
4401
|
-
|
|
4402
|
-
**both** — the civic status (Citizen) and the standing in the governing
|
|
4403
|
-
it (Senator) — because a citizen is not a member of the Senate, and
|
|
4404
|
-
two is the commonest way to get a non-monarchy wrong.
|
|
4540
|
+
rungs are a class one is born or bought into, and a body whose highest posts are
|
|
4541
|
+
offices one is voted into and then vacates. A republic's ladder therefore carries
|
|
4542
|
+
**both** standings — the civic status (Citizen) and the standing in the governing
|
|
4543
|
+
body above it (Senator) — because a citizen is not a member of the Senate, and
|
|
4544
|
+
conflating the two is the commonest way to get a non-monarchy wrong. The
|
|
4545
|
+
magistracies held for a term are offices, not rungs.
|
|
4405
4546
|
|
|
4406
4547
|
**Rank**
|
|
4407
4548
|
Definition of a level within the organization (e.g., Priest, Layperson, Member, Gang Leader, Master, etc.)
|
|
4408
4549
|
|
|
4409
4550
|
| Property | Required | Values | Description |
|
|
4410
4551
|
| ------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
4411
|
-
| `level` | yes | integer | The ranking within the affiliation,
|
|
4552
|
+
| `level` | yes | integer | The ranking within the affiliation: 0 those it excludes (expelled, excommunicated), 1 its ordinary members, higher values above them |
|
|
4412
4553
|
| `title` | yes | string | Title associated with the Rank |
|
|
4413
4554
|
| `description` | yes | string | Description of the Rank |
|
|
4414
4555
|
| `lore` | no | `Address` | The standing this rank _is_ — a `lore` note of subType `law`, shared with every other body that confers the same thing |
|
|
@@ -4429,11 +4570,37 @@ moving two lines renames the standing. A body that confers two titles at one
|
|
|
4429
4570
|
standing writes them as one rung — `title: Knight or Dame` — or gives each its
|
|
4430
4571
|
own level.
|
|
4431
4572
|
|
|
4573
|
+
**Every ladder has rung 0 and rung 1.** Level 1 is the ordinary member, and level
|
|
4574
|
+
0 names those the body excludes. A body that can name its members can name those
|
|
4575
|
+
it shuts out, whether or not it ever does, so an affiliation whose
|
|
4576
|
+
`governance.ranks` lacks either is an **error** at the `ranks` key, as is one
|
|
4577
|
+
with no ladder at all. The level-0 title is the body's own word for the excluded
|
|
4578
|
+
— Outlaw, Apostate, Níðing — never a generic "Excluded".
|
|
4579
|
+
|
|
4580
|
+
Those two rungs are the minimum. Add rungs above level 1 only where the body
|
|
4581
|
+
truly has them, generally no more than five. **A rung is a standing, what a member
|
|
4582
|
+
is; an office is a post, what a member does.** Leadership is normally an office
|
|
4583
|
+
held by the top rank rather than a rank above it, and a rank never falls when an
|
|
4584
|
+
office is left: a bishop stays a bishop after being Presiding Bishop.
|
|
4585
|
+
|
|
4586
|
+
```yaml
|
|
4587
|
+
data:
|
|
4588
|
+
governance:
|
|
4589
|
+
ranks:
|
|
4590
|
+
- { level: 0, title: Apostate, description: Put out of the communion. }
|
|
4591
|
+
- { level: 1, title: Layman, description: A baptised member of the faith. }
|
|
4592
|
+
- { level: 2, title: Priest, description: Ordained to serve a parish. }
|
|
4593
|
+
- { level: 3, title: Bishop, description: Consecrated to oversee a diocese. }
|
|
4594
|
+
offices:
|
|
4595
|
+
Presiding Bishop: Chairs the synod of bishops for a term.
|
|
4596
|
+
```
|
|
4597
|
+
|
|
4432
4598
|
```yaml
|
|
4433
4599
|
data:
|
|
4434
4600
|
governance:
|
|
4435
4601
|
ranks:
|
|
4436
4602
|
- { level: 0, title: Vrystrith, description: Kinless and owed nothing. }
|
|
4603
|
+
- { level: 1, title: Kinsman, description: Born or adopted into a household. }
|
|
4437
4604
|
- { level: 4, title: Fródrád, description: A householder whose word carries. }
|
|
4438
4605
|
- level: 5
|
|
4439
4606
|
title: Hárár
|
|
@@ -4469,7 +4636,7 @@ rank names the standing, and the standing says.
|
|
|
4469
4636
|
| `symbol` | `string` | Its emblem in words: a feather atop a golden scale, a chisel carving a star |
|
|
4470
4637
|
| `governance.model` | `GovernanceModel` | Type of government structure, if applicable |
|
|
4471
4638
|
| `governance.summary` | `string` | summary of the governance situation |
|
|
4472
|
-
| `governance.ranks` | `Rank[]` | The ranks
|
|
4639
|
+
| `governance.ranks` | `Rank[]` | The ranks the affiliation confers; level 0 and level 1 are required |
|
|
4473
4640
|
| `governance.ranks[].level` | `integer`, required | The rung's position on this body's ladder; a member's `rank` names it |
|
|
4474
4641
|
| `governance.ranks[].title` | `string`, required | What the standing is called |
|
|
4475
4642
|
| `governance.ranks[].description` | `string`, required | What the standing is |
|
|
@@ -4519,14 +4686,15 @@ the ranks and offices that exist, and a membership names which of them it holds.
|
|
|
4519
4686
|
**Rank is the organisation's, not the member's.** A bare `level: 4` on a
|
|
4520
4687
|
membership says nothing on its own; it means _Knight_ only because the polity
|
|
4521
4688
|
declared that rung. So the ladder is authored once, on the body that confers it,
|
|
4522
|
-
and a member's rank is an index into it. Level 0 is
|
|
4523
|
-
|
|
4524
|
-
recognises, and so
|
|
4689
|
+
and a member's rank is an index into it. Level 0 is the excluded — outlawed,
|
|
4690
|
+
expelled, excommunicated — which is a standing the organisation still
|
|
4691
|
+
recognises, and so every ladder defines it beside level 1.
|
|
4525
4692
|
|
|
4526
4693
|
**Offices are named, not ranked.** A Chancellor and a Marshal are both great
|
|
4527
4694
|
officers and neither is above the other, so an office is a key with a
|
|
4528
4695
|
description rather than a rung — and a being may hold an office at any rank, or a
|
|
4529
|
-
rank with no office at all.
|
|
4696
|
+
rank with no office at all. The head of a body is usually an office of this kind,
|
|
4697
|
+
held by a member of the top rank, who keeps that rank when the term ends.
|
|
4530
4698
|
|
|
4531
4699
|
An office may remain a string description or declare a `description` and a
|
|
4532
4700
|
`holders` list. Each holder names a `being` Address; optional `start` and `end`
|