Packages can now carry a special status from a data-driven registry — adding or removing a special is an edit of one entry in lib/game/specials.ts, no scattered branches.
Registry: flat SPECIALS record (house style, like PLANE_TYPES) with per-status modifiers: reward multiplier, deadline scale, reputation bonus. First status: priority — ×1.5 reward, ×0.5 deadline window, +0.5 rep on delivery.
Spawn: one appended RNG draw in generatePackage() (fixed order preserved); 15% chance of a special, uniform among registered statuses; forced override skips the draw.
Unit: +10 tests (registry application, pickSpecial distribution with fixed RNG, removed-entry cleanly disables a status, delivery rep bonus). E2E: new test forces a priority package and asserts the badge renders. Verified by CI against the isolated dind stack.
Fixes #73
Packages can now carry a **special status** from a data-driven registry — adding or removing a special is an edit of one entry in `lib/game/specials.ts`, no scattered branches.
- **Registry**: flat `SPECIALS` record (house style, like `PLANE_TYPES`) with per-status modifiers: reward multiplier, deadline scale, reputation bonus. First status: **priority** — ×1.5 reward, ×0.5 deadline window, +0.5 rep on delivery.
- **Spawn**: one appended RNG draw in `generatePackage()` (fixed order preserved); 15% chance of a special, uniform among registered statuses; forced override skips the draw.
- **State shape**: nullable `special` column (3-sync: Drizzle schema + DDL + guarded migration — legacy rows stay NULL), `SeedPackage`, `PackageState`, row mapping.
- **UI**: sky-blue "Priority" badge on open and on-board job rows (`package-special-{id}` testid).
- **Test hook**: create-package accepts `special` (string or null); omitted → forced null so existing e2e expectations stay deterministic; expire-package passes null explicitly.
- **OpenAPI**: optional `PackageState.special` + sorted-key pin updated.
Unit: +10 tests (registry application, pickSpecial distribution with fixed RNG, removed-entry cleanly disables a status, delivery rep bonus). E2E: new test forces a priority package and asserts the badge renders. Verified by CI against the isolated dind stack.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #73
Packages can now carry a special status from a data-driven registry — adding or removing a special is an edit of one entry in
lib/game/specials.ts, no scattered branches.SPECIALSrecord (house style, likePLANE_TYPES) with per-status modifiers: reward multiplier, deadline scale, reputation bonus. First status: priority — ×1.5 reward, ×0.5 deadline window, +0.5 rep on delivery.generatePackage()(fixed order preserved); 15% chance of a special, uniform among registered statuses; forced override skips the draw.specialcolumn (3-sync: Drizzle schema + DDL + guarded migration — legacy rows stay NULL),SeedPackage,PackageState, row mapping.package-special-{id}testid).special(string or null); omitted → forced null so existing e2e expectations stay deterministic; expire-package passes null explicitly.PackageState.special+ sorted-key pin updated.Unit: +10 tests (registry application, pickSpecial distribution with fixed RNG, removed-entry cleanly disables a status, delivery rep bonus). E2E: new test forces a priority package and asserts the badge renders. Verified by CI against the isolated dind stack.