A .patch file does not carry enough for an installer to run the tier safely.
The installer additionally needs to know which patches form one all-or-nothing
unit (the two vendor-sale patches are useless apart), which companion .cs may
only be copied once that unit has landed, whether the change needs a core
solution rebuild or just ServUO's dynamic script build, and what capability an
operator loses by declining. None of that is derivable from the diffs.
patches/tier.json declares it, and release.yml folds it into manifest.json as
`patch_tier` — so a new or changed patch regenerates release metadata rather
than requiring an installer release, which is the same rule §7.1 already
applies to the bundle. The staged copy is removed from patches/ so the tarball
carries exactly one statement of the table.
The release gate now checks the table in both directions: every .patch
described by exactly one feature, every named patch and companion present,
every declared target equal to the file the diff actually edits, and every
rebuild kind one the installer understands. All four were previously invisible
until someone ran the tier on a live shard.
Refs: docs/installer/PLAN.md §2.2, §7.0
Co-Authored-By: Claude <noreply@anthropic.com>