A user has been able to spam ingame chat with the disband notification. They claim they can still run commands related to the business, but they don't seem to function fully. Further investigation is needed.

Root-caused and fixed on develop (commit 7a95933).
Cause — getFirmByNameOrId resolved firms regardless of is_archived, so after a disband every command/service path (balance, deposit, withdraw, pay, staff, roles, accounts, requests, tax …) still resolved the firm and partially acted on it. That's the "can still run commands… don't seem to function fully" report.
Fix — made getFirmByNameOrId active-only (returns null for an archived firm). Because ~60 command/service call sites funnel through this one method, that single change centrally rejects disbanded firms everywhere with a clean "not found".
Added getAnyFirmByNameOrId (archived-inclusive) for the handful of places that legitimately need defunct firms:
BusinessApi.getFirm / getFirmByAccountId — consumers may display defunct firms (and getFirmByAccountId already returns null for disbanded firms since the firm_account link is dropped on disband);/firm info — renders the (Defunct) status;disband — so a repeat reports "already disbanded" (idempotent) rather than "not found".The disband-notification-spam half was already addressed by PAR-24 (Pending Release); this closes the "commands still work on a disbanded firm" half.
Tests: archived→null, active→resolves, getAny→archived; existing API delegate tests updated to the archived-inclusive read. Full suite + ≥95% coverage gate green.
Root cause confirmed. Two parts:
disbandFirmthrows "already disbanded" if archived). Ships with that.FirmServiceImpl.getFirmByNameOrId→FirmMapper.getFirmById/getFirmByNamereturn the firm regardless ofis_archived(no archived filter), so mutating commands resolve a disbanded firm and act on it.Fix plan: make
getFirmByNameOrIdactive-only (return null whenis_archived), so every command path rejects a disbanded firm; switchdisbandFirm's "already disbanded" check to an explicit archived-inclusive lookup; keep any admin/info view path on an archived-inclusive resolver. Add aFirmServiceImplTestcase (archived firm → resolver returns null) to satisfy the ≥95% coverage gate. Bounded but touches the central resolver — deserves its own focused pass, not a tail-end rush.