Skip to content

Station Protection

Status: 🚧 Partial β€” station-defense drone tiers, attack_port deterrence kernel, on-dock security-tier banner, owner StationSecurityMonitoringPane, and the server-side STATION_SECURITY garrison wiring are shipped. Security-tier synchronization provisions and maintains the Station.security roster linkage through station-linked NPCBarracks for Standard/Premium tiers; Basic/none clears the named-roster keys and stops spawning, but does not decommission old NPC rows/barracks. (Garrison: services/gameserver/src/services/station_security_garrison.py:171-244; synchronization: services/gameserver/src/services/station_security_service.py:331-341,348-360,364-398,459-473.) Capture/disable, guard wages, a dedicated defense-budget schema, patrol UI, and dock-undock dialogue remain design-only. (Reconciled against the authenticated Gameserver source checkout 2026-09-26.)

The third pillar of universe-level security alongside police forces (faction-driven, jurisdiction-based) and player-built sector defenses (drone blocks, mines per ../galaxy/sectors.md). Station protection is station-driven in the design model β€” intended to be paid for by the station's docking-fee revenue, run by the station's owner, and bounded by the station's perimeter. The live security service records upkeep but has no STATION_SECURITY wage consumer (services/gameserver/src/services/station_security_service.py:53-66).

When a player docks at a Standard-tier or Premium-tier station, they receive the live docked-ship attack block and undock tractor-lock protection. The server-side STATION_SECURITY garrison wiring is live through station-linked NPCBarracks (services/gameserver/src/services/station_security_garrison.py:171-244; services/gameserver/src/services/station_security_service.py:331-341,348-360,364-398,459-473). Claims that guards walk the docking ring, defense drones patrol the local sector, or station security prevents boarding remain design-only presentation/behavior claims. The station-level tractor beam is strong enough to stop a stolen ship from leaving; its docking-fee funding remains a design-model assumption, not evidence of a live garrison wage budget.

What station protection covers

Two live guarantees apply to any ship docked at a station with security_level >= basic; anti-board protection is a separate design-only concept:

  1. No external attack on docked ships. A hostile player in the same sector cannot target a docked ship. The combat-resolver rejects attack attempts with ERR_DOCKED_SHIP_PROTECTED. This complements (not replaces) the NPC-barracks shield rule from ../gameplay/police-forces.md β€” barracks shielding applies to NPC ships specifically; station protection applies to any docked ship (including player-owned).
  2. Anti-theft tractor lock on undock. When a ship attempts to undock, the live station-security gate checks the pilot's status. If the ship is Ship.stolen_status = true, or the pilot is Wanted at a tier above the station's threshold, or the pilot is on the station's deny-list, the station's tractor beam locks the ship to the docking ring. A station-security response after the lock is design-only; the live lock gate and payload are implemented in services/gameserver/src/services/station_security_service.py:510-530,638-683. Strong stations can hold the ship indefinitely.
  3. Anti-board protection β€” design-only. The hatch-pin / salvage-break mechanic from ../../SYSTEMS/ship-registry.md is not currently gated by station protection: board_ship checks ownership, pin, sector, and salvage-break state, with no station-protection check (services/gameserver/src/services/ship_registry_service.py:866-930). Do not treat a docked ship's inability to be boarded as shipped station security.

Stations at security_level = none (frontier outposts, abandoned hulks, lawless ports) provide neither of the live guarantees. Players who dock there are taking the same risk as parking in space; anti-board protection remains design-only at every tier.

Security tiers

Four tiers of station protection. The defense shares and recurring percentages below are design-model targets, not a live STATION_SECURITY funding or wage schedule; the tiers are configured by the station's owner (or by faction policy for operator-managed stations). (services/gameserver/src/services/station_security_service.py:53-66.)

Tier Drones Hired guards Tractor strength Defense budget share (design target) Live player guarantees
None 0 0 None 0% (no defenses) None β€” docked ships are at risk
Basic 4 0 Weak (75% engine + 10 turns to break) ~5% of revenue No-attack on docked ships; weak tractor on stolen-ship undock
Standard 8 2 named guards Strong (90% engine + 20 turns to break) ~10% of revenue No-attack on docked ships; strong tractor on stolen-ship undock; guard response design-only
Premium 12 4 named guards + 1 Captain Immobilizing (cannot break) ~20% of revenue No-attack on docked ships; immobilizing tractor on stolen-ship undock; guard response design-only

The no-attack and tractor claims above are the live station-protection guarantees; guard combat or response timing is not implied by the garrison roster. (services/gameserver/src/services/station_security_service.py:510-530,638-683; garrison wiring: services/gameserver/src/services/station_security_garrison.py:171-244.)

Operator-managed stations (Federation Capital station, Nexus Starport Prime, Terran Space hub stations) are seeded at Standard or Premium tier by the galaxy generator. Player-owned stations default to Basic if the owner wishes to keep operating costs low; the owner can upgrade tier at any time by paying the upgrade fee.

Ordinary NPC-seeded ports (any StationClass, in any region, that isn't one of the named operator-managed anchors above) are seeded per a class-based security gradient (ratified 2026-08-04, Max β€” replacing an earlier uniform Basic floor), matching the docking-slips per-class banding: CLASS_1-6 (basic/mid-tier trading) seed at Basic; CLASS_7-11 (premium/refining, Tech Specialist) seed at Standard. Premium is never granted by class alone β€” reserved for the three literal operator-managed anchors above.

Tier upgrade cost

Upgrade One-time cost Recurring upkeep (design target) Construction time
None β†’ Basic 50,000 cr ~5% of station revenue 24 real-time hours
Basic β†’ Standard 200,000 cr ~10% of station revenue (cumulative) 72 real-time hours
Standard β†’ Premium 750,000 cr ~20% of station revenue (cumulative) 7 real-time days

Downgrading is free but takes 24 hours (the intended dismissal of guards, decommissioning of drones, and tractor-beam shutdown). The shipped garrison path clears its Station.security roster IDs and stops spawning for Basic/none, but does not yet decommission existing STATION_SECURITY NPC rows or the station-linked NPCBarracks (services/gameserver/src/services/station_security_garrison.py:171-196).

Hired security guards (STATION_SECURITY archetype)

The station-paid security force is a new NPC archetype within the unified NPC lifecycle framework: STATION_SECURITY. Distinct from LAW_ENFORCEMENT (police, who are faction-funded and faction-jurisdictioned) and FACTION_PATROL (Federation Navy, AM enforcers β€” also faction-driven). The claimed station-funded patrol jurisdiction β€” docking ring, host sector, and adjacent 1-hop ring β€” remains design-only; the live garrison wiring is limited to provisioning and maintaining the tier-sized Station.security roster linkage through NPCBarracks (services/gameserver/src/services/station_security_garrison.py:171-244).

Roster

Per Station.security_level:

  • Basic: zero named guards. The 4 anonymous defense drones are outside this STATION_SECURITY garrison wiring; no named guard response is claimed. (services/gameserver/src/services/station_security_garrison.py:50-57,171-194.)
  • Standard: 2 named NPC guards; the 12-hour shifts and 1-hour handoff overlap remain design-only. Capacity in the station's NPCBarracks is 2. (Live roster: services/gameserver/src/services/station_security_garrison.py:50-57,171-244.)
  • Premium: 4 named guards + 1 named Captain; incident handling and routine docking-ring patrol behavior remain design-only. Barracks capacity 5. (Live roster: services/gameserver/src/services/station_security_garrison.py:50-57,171-244.)

Live garrison wiring

Security-tier synchronization now provisions and maintains the STATION_SECURITY garrison linkage through a station-linked NPCBarracks. ensure_station_security_garrison is idempotent for a fully staffed tier: Standard provisions 2 routine guards with barracks capacity 2; Premium provisions 4 routine guards plus 1 Captain with capacity 5; Basic and none clear guard_npc_ids / guard_captain_npc_id and do not spawn NPCs. The live function records barracks_id, routine-guard IDs, and the Premium captain ID in Station.security. On a downshift, this function does not delete already-existing STATION_SECURITY NPC rows or the station-linked barracks; β€œno named garrison” therefore means no active roster IDs in Station.security, not storage cleanup. (services/gameserver/src/services/station_security_garrison.py:171-244; barracks lookup/creation: services/gameserver/src/services/station_security_garrison.py:74-116.)

The security service calls that garrison synchronization on security-status reads and on tier upgrade/downgrade operations, so the Station.security roster linkage follows the station's live security tier when those paths run. The service skips synchronization when region_id is absent and logs a garrison failure on ValueError; these are source-level boundaries, not patrol or wage behavior. (services/gameserver/src/services/station_security_service.py:331-341,348-360,364-398,459-473.)

This shipped wiring is limited to provisioning and maintaining the garrison. Guard wages, shift overlap, KIA respawn, a dedicated defense-budget schema/consumer, player-visible patrol UI, and dock-undock dialogue remain design-only; the garrison source explicitly avoids inventing wages, shift overlap, or KIA respawn, and the security service identifies wages as having no consumer yet. (services/gameserver/src/services/station_security_garrison.py:1-14; services/gameserver/src/services/station_security_service.py:53-66.)

The live garrison creates named STATION_SECURITY NPC rows and assigns their station ships and barracks home. Promotions, retirement, KIA handling, and respawn timing remain design-only; the garrison source explicitly does not invent KIA respawn. (services/gameserver/src/services/station_security_garrison.py:1-14,119-168.)

Ships

STATION_SECURITY NPCs use the live standard ship assignments: routine guards fly Light Freighters and the Premium captain flies a Defender. (services/gameserver/src/services/station_security_garrison.py:119-168,217-229.) Interdictor hulls, custom paint, and defense-budget/posture selection remain outside this garrison wiring.

The 1:1 lifetime assignment, off-duty parking, and player-attack shielding claims remain design-only; the live source verifies the ship assignments and barracks home recorded during garrison provisioning, not those lifecycle behaviors (services/gameserver/src/services/station_security_garrison.py:119-168,217-229).

Engagement triggers (design-only)

The following engagement triggers are design-only; the live garrison wiring provisions the roster but does not substantiate these response behaviors:

  • Combat against a docked ship β€” the instant guard response and named-guard squad are design-only; the live docked-ship targeting rejection is documented separately.
  • Stolen-ship undock attempt β€” the tractor lock is live; any named-guard/security-squad response is design-only (services/gameserver/src/services/station_security_service.py:638-699).
  • Attack against the station itself β€” full security response remains design-only; see the intended model in ./port-ownership.md#takeover-defense.
  • Brawl in the station bar / docking ring β€” flavor scene, guard intervention, and combat resolution remain design-only.
  • Wanted-Status pilot on station property β€” Premium detention and Standard watch behavior remain design-only; Wanted Status is otherwise a Federation-Marshal concern, not station security's.

Design-only patrol range: the claim that guards do not patrol outside the station's host sector + 1-hop ring, including the resulting 2-hop pursuit boundary, is not established by the live garrison wiring.

Anti-theft tractor beam

The station-level tractor beam is the load-bearing mechanic for "ships docked here are safe." When any ship attempts to undock, the station runs a fast deny-list check:

  1. Is Ship.stolen_status = true? (per the existing stolen-report flow in ../../SYSTEMS/ship-registry.md)
  2. Is the pilot's Player.personal_reputation < station.wanted_threshold?
  3. Is the pilot on the station's deny_list_player_ids (set by owner; defaults empty)?

If any check hits, the undock is rejected with tractor lock:

ERR_STATION_TRACTOR_LOCK
{
  "station_id": "<uuid>",
  "tractor_strength": "weak | strong | immobilizing",
  "reason": "stolen_ship | wanted_pilot | deny_listed",
  "break_attempt_cost": "75-pct engine + 10 turns | 90-pct engine + 20 turns | impossible"
}

The pilot has three options:

  1. Surrender. Abandon the ship at the station; security takes custody. The owner of the stolen ship is notified via the realtime bus; the ship is held for retract / transfer. The thief is fined 15% of cargo value plus a reputation hit β€” the four provisional tractor-lock numbers (15% cargo fine, βˆ’100 failed-break reputation hit, βˆ’500 auto-wanted threshold, and the tier percentages below) were ratified as canon by ADR-0093 item 5 (folded from ADR-0093, re-verified 2026-08-07); serious violations result in arrest and detention (βœ… Shipped β€” Player.detained_until for stolen_ship / wanted_pilot lock reasons: 6h / 3h canonical via game_time.scaled_deadline [NO-CANON exact hours within the 1–6h band]; turn regen freezes; non-Escape-Pod ship boarding gated ERR_DETAINED until expiry. deny_listed surrender does not detain).
  2. Attempt to break free. Pour 75% / 90% of engine power into the tractor for 10 / 20 turns (90% engine / ~20 turns at Premium β€” see Tractor strength tiers below); success rolls against tractor strength. Premium tier is immobilizing β€” break attempts always fail. Each failed break costs the turns regardless and carries a βˆ’100 reputation hit; repeated failed breaks can push personal_reputation under the auto-Wanted threshold (βˆ’500, per ../gameplay/police-forces.md). Any security-squad engagement during the break attempt is design-only; the live service documents the turn spend, roll, and lock outcome (services/gameserver/src/services/station_security_service.py:686-729).
  3. Be destroyed β€” design-only security response. The security squad attacking the locked ship, combat resolution, and escape-pod treatment are not established by the live station-security service. The shipped source documents the tractor lock, break, and surrender paths only (services/gameserver/src/services/station_security_service.py:638-699,876-894).

The tractor lock applies only at undock. Players moving around inside the station, dining at the cafeteria, browsing the market β€” all unaffected. The tractor activates only when the engines fire to leave the docking ring.

Tractor strength tiers

  • Weak (Basic): 25% chance per turn that a 75%-engine break attempt succeeds; expected break time ~10 turns. Used by frontier-zone budget stations.
  • Strong (Standard): 10% chance per turn at 90% engine; expected break time ~20 turns. Used by typical Federation-zone stations.
  • Immobilizing (Premium): a break attempt costs the same investment as Strong (90% engine, ~20 turns) but rolls 0% chance per turn β€” the ship cannot escape under any circumstances. Used by Capital stations, Nexus Starport Prime, fortress-grade industrial hubs.

A team of players cannot stack break attempts β€” the tractor locks one ship at a time and the station can lock multiple ships independently. A coordinated extraction (decoy + tractor-cut sabotage) is πŸ“ future content; not at launch.

Docking fee economics

Design model: docking fees are paid on the dock attempt, separate from any trade tariffs, and are intended to fund the station's security infrastructure (drones, guards, tractor beam upkeep) plus a cut to the owner. The live service's upkeep record is not a garrison wage consumer (services/gameserver/src/services/station_security_service.py:53-66).

Base fee structure

Ship size Base docking fee
Tiny (Escape Pod) 0 cr (free)
Small (Scout, Fast Courier) 100 cr
Medium (Light Freighter, Defender) 250 cr
Large (Cargo Hauler, Colony Ship, Warp Jumper) 500 cr
Capital (Carrier) 1,000 cr

Multiplied by the station's security tier:

Tier Multiplier
None 0Γ— (free dock; you get what you pay for)
Basic 1.0Γ— base
Standard 1.5Γ— base
Premium 3.0Γ— base

A Cargo Hauler docking at a Premium-tier Capital station thus pays 1,500 cr per dock. The fee is collected on dock-arrival (POST /api/v1/stations/{id}/dock) before the player is granted docking-ring access.

Fee distribution

Each docking fee is split three ways in the design model; these percentages are not live STATION_SECURITY funding allocations:

Bucket Share Purpose
Defense fund 40% Planned drone replenishment, guard wages, tractor-beam upkeep, security barracks operating costs
Owner cut 30% Goes to the player or team that owns the station; revenue flows into team treasury or player wallet
Operating cost 30% Station maintenance, faction taxes, ambient operating overhead

Design model: operator-managed stations (Federation Capital, Nexus Starport Prime) split 70% defense / 30% operating with no owner cut β€” there is no owner. The operator-managed cut is sunk into the station's treasury for ambient infrastructure.

Design model: the owner can adjust the split within bounds (πŸ“): - Defense fund: 30%–60% (lower starves defenses; eventually downgrades the security tier) - Owner cut: 10%–50% (higher extracts more profit; eventually triggers Federation-faction attention if perceived as predatory) - Operating: fixed at 30% (non-negotiable)

Defense-fund accounting

Design-only accounting: the proposed Station.defense_budget (Integer, credits) is not a live dedicated schema/consumer for the garrison. Planned drone replenishment, guard wages, and tractor upkeep would be paid from this budget on a daily tick; the live security service currently records upkeep without a wage consumer. (services/gameserver/src/services/station_security_service.py:53-66.)

Defense underfunding cascade is station-tier lifecycle accounting, not a live garrison wage budget (reconciled with ./port-ownership.md per ADR-0093): defense_pct < 0.35 (i.e. the defense bucket falls under 35% of revenue) defines underfunding. 3 consecutive deficit days β†’ the station auto-downgrades by one tier, with an owner warning notification fired on day 1 of the deficit. 7 consecutive deficit days β†’ the station downgrades to none, triggering a forced "your station is undefended" notification.

The proposed owner contribution endpoint (POST /api/v1/stations/{id}/defense-budget/contribute) is design-only β€” useful in the model for surge defense ahead of a known threat (e.g., a hostile team is staging in adjacent sectors).

Free-dock exemptions

A docking fee is waived for: - Owner of the station. - Owner's team-mates (configurable per station; defaults to free). - Allied-faction NPCs (e.g., Federation Marshals dock free at Federation-aligned stations). - Players with active docking contracts (πŸ“ future β€” pre-paid bulk docking deals).

The owner can add per-player exemptions via the station governance UI; abuse-prevention rate-limits per the warp-gate-toll bypass mitigation in DECISIONS SK10.

Schema impact

Station fields

Station schema (DATA_MODELS/stations.md) gains:

Field Type Notes
security_level Enum station_security_tier none / basic / standard / premium
defense_budget Integer Design-only dedicated field; not part of the live garrison schema/consumer
tractor_strength Enum tractor_strength none / weak / strong / immobilizing (derived from security_level)
wanted_threshold Integer Personal-rep cutoff for tractor activation; default βˆ’500
deny_list_player_ids JSONB array Owner-set blocklist
fee_distribution JSONB {defense_pct: float, owner_pct: float, operating_pct: float} (sum = 1.0)

Station.security JSONB shape

A new Station.security JSONB column carries the live security state:

{
  "tier": "standard",
  "defense_drones_active": 8,
  "defense_drones_max": 8,
  "guard_npc_ids": ["<uuid>", "<uuid>"],
  "guard_captain_npc_id": null,
  "barracks_id": "<npc_barracks_uuid>",
  "tractor_lock_active": false,
  "tractor_locked_ship_id": null,
  "tractor_locked_at": null,
  "last_attack_at": null,
  "last_tractor_event_at": null
}

For the live garrison path, the security service synchronizes the station roster on security-status reads and tier changes; the garrison function updates the Station.security roster IDs after provisioning or refresh. It does not perform downshift cleanup of old NPC rows or barracks. (services/gameserver/src/services/station_security_service.py:331-341,348-360,364-398,459-473; services/gameserver/src/services/station_security_garrison.py:171-244.)

Sector and station relationships

Design-only sector integration: the proposed Sector.defenses entries for station guards in the existing patrol_ships array β€” squad_kind = "station_security" and faction_code = "<station_owner_or_faction>" β€” plus player visibility around the host sector are not part of the live garrison wiring.

Design-only off-duty integration: the claim that off-duty guard ships land in Sector.defenses.docked_npc_ships and receive the standard shielding behavior is not verified by the live garrison source. The source does verify station-linked NPCBarracks home assignment (services/gameserver/src/services/station_security_garrison.py:119-168).

NPC lifecycle integration

STATION_SECURITY is added to the npc_archetype enum (per ../../DATA_MODELS/npcs.md). The live garrison path ensures the configured Station.security roster IDs, filling missing rows and assigning their station-linked barracks; it does not prune excess/stale rows. Schedules, promotions, KIA, succession, respawn, and wage accounting remain design-only. (services/gameserver/src/services/station_security_garrison.py:119-168,171-244; services/gameserver/src/services/station_security_service.py:53-66.)

Player-side experience

Honesty vs origin/feat tip 489e31851 (docs↔code status, not a new game rule).

A player docking at a Premium-tier Capital station:

  • On dock β€” security-tier banner βœ… tip-PRESENT β€” StationSecurityBanner.tsx mounted from GameDashboard.tsx (tip-delta β‰₯ 449ca3589; tip 489e31851). Live banner renders Security tier: {tier} from GET station-security status (formatStationSecurityBanner). Design-target example copy ("Docked at Capital Station Prime. Security tier: Premium. Guards on duty: 5. Defense drones: 12/12. Anti-theft tractor: armed.") remains richer than the tip line β€” do not invent guards-on-duty / drone-count / tractor-armed fields as tip-PRESENT. StatusBar title="Defense drones" remains player-hull drone count, distinct from this station dock banner.
  • Inside the station πŸ“ flavor / not verified player HUD β€” guards walking the docking ring, bar scenes. Market access and "no ship-attack risk while docked" follow the GS docked-ship protection path, not a dedicated in-station security UI.
  • On undock / stolen-ship tractor βœ… player-live actions β€” TractorLockPrompt.tsx plus stationSecurityAPI break/surrender routes; WS impound copy in WebSocketContext.tsx. The quoted dialogue ("This vessel matches a stolen-report flag. Surrender, attempt break-free, or fight.") is design-only copy; the live station-security source documents the lock, break, and surrender actions (services/gameserver/src/services/station_security_service.py:638-699,876-894).

A player attempting to attack a docked ship at a protected station:

  • Targeting attempt βœ… GS shipped β€” rejected before any turn charge (ERR_DOCKED_SHIP_PROTECTED / WO-CB1). Do not invent a player toast beyond that GS error path.
  • Persistent attempts / guards engage the attacker πŸ“ design-only β€” the live garrison wiring provisions the roster, but this guide does not claim a shipped patrol/engagement UI or dialogue.

A station owner security monitoring pane βœ… tip-PRESENT β€” StationSecurityMonitoringPane.tsx mounted from PortOfficeVenue.tsx (tip 489e31851 β‰₯ 449ca3589). Live tier + monitoring chrome ship; the server-side named-guard garrison wiring also ships through NPCBarracks and Station.security (services/gameserver/src/services/station_security_garrison.py:171-244; services/gameserver/src/services/station_security_service.py:331-341,348-360,364-398,459-473). A dedicated defense_budget column, STATION_SECURITY wage consumer, patrol UI, and dock-undock dialogue remain πŸ“.

Player-facing affordances

  • βœ… Anti-theft tractor lock on undock β€” TractorLockPrompt.tsx + stationSecurityAPI break/surrender routes; GS check_tractor_lock at undock (trading.py); WS impound copy in WebSocketContext.tsx (origin/feat 5f4d750c). Live lock/break/surrender mechanics: services/gameserver/src/services/station_security_service.py:638-699,876-894.
  • βœ… Docked-ship attack block β€” GS rejects targeting docked ships at protected stations with ERR_DOCKED_SHIP_PROTECTED (combat_service.py:933-955, WO-CB1).
  • βœ… On-dock security-tier banner β€” tip-PRESENT: StationSecurityBanner.tsx mounted GameDashboard (tip 489e31851 β‰₯ 449ca3589).
  • βœ… Owner security monitoring pane β€” tip-PRESENT: StationSecurityMonitoringPane.tsx mounted PortOfficeVenue (tip 489e31851 β‰₯ 449ca3589).
  • βœ… Named-guard roster / STATION_SECURITY garrison wiring β€” security-tier synchronization provisions and maintains the tier-sized Station.security roster linkage through station-linked NPCBarracks and records its IDs in Station.security; downshift decommissioning of old NPC rows/barracks is not included (services/gameserver/src/services/station_security_garrison.py:171-244; services/gameserver/src/services/station_security_service.py:331-341,348-360,364-398,459-473).
  • πŸ“ STATION_SECURITY patrol UI β€” no player-visible patrol interface is claimed by the live garrison wiring.
  • πŸ“ Dedicated defense_budget column / STATION_SECURITY wage-roster consumer / dock-undock flavor dialogue β€” remain design-only residuals.

Status

🚧 Partial. The security-tier + anti-theft tractor-lock core is βœ… shipped: Station.security JSONB (models/station.py:371) backs the security_level property (station.py:441, tier string via security_tier_rank) and a full station_security_service.py (get/upgrade/downgrade tier, tractor_lock_reason/check_tractor_lock/attempt_tractor_break/surrender_tractor_locked_ship, per-ship security["tractor_locks"] entries), routed at POST/GET /stations/{id}/... (api/routes/station_security.py, registered api/api.py:163) and enforced at the real undock choke point β€” check_tractor_lock is called from api/routes/trading.py:2005. Guarantee #1 attack-targeting block against docked ships at a protected station is also βœ… shipped (combat_service.py:933-955, ERR_DOCKED_SHIP_PROTECTED / WO-CB1 β€” rejects before any turn charge when defender_station.security_rank >= SECURITY_TIER_PROTECTED_MIN_RANK). The Station.defenses JSONB (defense_drones / auto_turrets / defense_grid / shield_strength / patrol_ships / military_contract, v1 schema) stays the separate station-vs-ship siege-infrastructure block per ./port-ownership.md β€” security is the docked-ship-protection/anti-theft block; the design model proposes both systems be funded from station revenue, but that is not a live STATION_SECURITY wage allocation. βœ… tip-PRESENT player chrome: on-dock StationSecurityBanner.tsx (GameDashboard) + owner StationSecurityMonitoringPane.tsx (PortOfficeVenue) on tip 489e31851 β‰₯ 449ca3589. The server-side STATION_SECURITY garrison wiring is also βœ… shipped: security-tier synchronization provisions and maintains the Station.security roster linkage through station-linked NPCBarracks, recording barracks_id, guard_npc_ids, and guard_captain_npc_id; downshift decommissioning of old NPC rows/barracks is not included (services/gameserver/src/services/station_security_garrison.py:171-244; synchronization calls in services/gameserver/src/services/station_security_service.py:331-341,348-360,364-398,459-473). Still πŸ“ design-only: capture/disable, guard wages, a dedicated defense_budget column/consumer, patrol UI, and dock/undock flavor dialogue. (Reconciled against the authenticated Gameserver source checkout 2026-09-26.)

Cross-references