Skip to content

fix(coop): harnessEquip/harnessSetArmor enforce the real craft-capacity gate - #122

Closed
NonPolynomialTim wants to merge 1 commit into
mainfrom
claude/coop-harness-craft-capacity-gate
Closed

fix(coop): harnessEquip/harnessSetArmor enforce the real craft-capacity gate#122
NonPolynomialTim wants to merge 1 commit into
mainfrom
claude/coop-harness-craft-capacity-gate

Conversation

@NonPolynomialTim

Copy link
Copy Markdown
Collaborator

Follow-up to #120 (merged). #120 landed the mid-battle-resume fix plus the harness "real button" hardening (start/resume/inline callers). This PR carries the one commit that missed the #120 merge window: the harness craft-capacity gate fixes. Rebased on current origin/main.

What

The harness* fidelity audit found two methods that bypassed the client-side capacity gate their real button enforces — and which the SHARED host validators do not re-check — so a test could reach an over-capacity craft no player can (the same class of hazard as the resumeCampaign() lobby bypass #120 fixed):

  • harnessSetArmor called applyArmorSelection() directly, skipping lstArmorClick's Craft::validateArmorChange (STR_NOT_ENOUGH_CRAFT_SPACE).
  • harnessEquip called equipSelectedWeapon() directly, skipping lstWeaponsClick's four capacity gates (cargo / HWP / storage_1 / storage_2).

Extracted lstWeaponsClick's capacity checks into a pure CraftWeaponsState::equipCapacityError() — one source of truth, no state-stack side effects — used by both the UI handler and harnessEquip; added the matching validateArmorChange guard to harnessSetArmor. Both now refuse an over-capacity change exactly like a player. test_shared_equip2 stays green.

Not in this PR

The deeper engine half — the SHARED host validators (craftRearmValidate / soldierArmorValidate in SharedEcon.cpp) not re-checking craft capacity, so capacity is client-only-enforced in SHARED — is a real latent bug tracked in #121.

🤖 Generated with Claude Code

…ty gate

The harness* fidelity audit found two methods that bypassed the client-side
capacity gate their real button enforces - and which the SHARED host validators
do NOT re-check - so a test could reach an over-capacity craft no player can
reach (the same class of hazard as the resumeCampaign() lobby bypass):

- harnessSetArmor called applyArmorSelection() directly, skipping lstArmorClick's
  Craft::validateArmorChange (STR_NOT_ENOUGH_CRAFT_SPACE).
- harnessEquip called equipSelectedWeapon() directly, skipping lstWeaponsClick's
  four capacity gates (cargo / HWP / storage_1 / storage_2).

Extract lstWeaponsClick's capacity checks into a pure
CraftWeaponsState::equipCapacityError() - one source of truth, no state-stack
side effects - used by both the UI handler and harnessEquip; add the matching
validateArmorChange guard to harnessSetArmor. Both now refuse an over-capacity
change exactly like a player. test_shared_equip2 stays green.

The deeper half - craftRearmValidate / soldierArmorValidate in SharedEcon.cpp not
re-checking craft capacity host-side (so capacity is client-only-enforced in
SHARED) - is a real latent bug filed as a separate follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@NonPolynomialTim

Copy link
Copy Markdown
Collaborator Author

Superseded by #123, which fixed issue #121 (host-side craft-capacity re-validation) and in doing so redid this PR's harness gate fixes with a better, shareable equipCapacityError(Mod*, Craft*, ...) and a bypassGate/blockedBy harness API. Content here is a strict subset of #123 (and its old harnessEquip/harnessSetArmor signatures would now conflict with #123's TestServer callers). Nothing to add — closing.

@NonPolynomialTim
NonPolynomialTim deleted the claude/coop-harness-craft-capacity-gate branch August 1, 2026 23:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant