{ "verdict": "minimal one-file source correction prepared; apply-check passed; independent actual-method tests pending", "title": "Refuse futile small-arms convoy trips when all remaining original cargo is incompatible", "trigger": "A fresh complete delivered small-arms shortage for an original AK-armed squad is within200m of a ready quiet original ammunition truck. Its frozen unspent stock now contains only PKM belts or launcher rounds because compatible AK magazines were used or looted. TryPlan ordinary branch treats any contained unspent magazine as available, reserves the squad/truck, consumes the delivered MessageId and applies180s cooldown. Later Transfer checks Compatible(actor,magazine,false), rejects all remaining cargo and can only time out. PlanResupplyTask returns immediately from this false-positive rifle admission, delaying actually supportable later-priority requests.", "proof_chain": [ { "file": "addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c", "lines": "289-309", "evidence": "Launcher branch calls LauncherStock(recipient); ordinary branch only tests nonnull, not-spent, Contains. Shared mutation follows availability: ReserveLogistics, token/trip state, m_Consumed and m_NextAttempt." }, { "file": "addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c", "lines": "337-354", "evidence": "Existing bounded launcher availability examines all96 original identities by32 attributable original members and uses Compatible(...,true). This mechanism is already sufficient with mode=false for small arms." }, { "file": "addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c", "lines": "461-485", "evidence": "At actual rendezvous, Transfer refuses every incompatible actor-magazine pair; no other source enters frozen stock except already separately proved finite depot imports." }, { "file": "addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c", "lines": "1341-1367", "evidence": "PlanResupplyTask returns on first admitted small-arms trip, before mounted/launcher/mine alternatives." } ], "owned_reference": { "files": [ "/home/jakub/devel/escapists/escapists-ai/Scripts/Game/EscapistsAI/EAI_Resupply.c", "/home/jakub/devel/escapists/escapists-ai/Scripts/Game/EscapistsAI/EAI_DepotLoading.c" ], "comparison": "Original received need manifests retain exact prefab lines. EAI_DepotLoading.Select only selects usable physical source cargo whose prefab matches a requested line. No proposal to copy original spawn/refill behavior; successor must keep its own frozen finite identity model." }, "implementation": { "production_files": [ "addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c" ], "methods": [ "TryPlan ordinary availability branch", "CompatibleStock(recipient,bool launcherMagazine)", "LauncherStock(recipient) compatibility wrapper retained" ], "contract": [ "Use same existing bounded96stock x32original members scan for ordinary small arms (mode=false) and launchers(mode=true).", "Retain unspent original identity, actual truck custody, original sampler attribution and CanFight guards. Use existing Compatible predicate with unchanged well/type/ammo rules.", "Run before reservations, radio orders, replay/cooldown/trip mutations. No stock identity commitment merely from this read.", "Delivered snapshot remains sole demand/position input; own original carrier weapon compatibility uses existing launcher precedent and does not read enemy/player positions.", "Retain rifle\u2192mounted\u2192launcher\u2192mine priority among supportable requests, all combat/quiet/capture/ownership guards, shared spent ledger, normal deadlines and capacity/native proof.", "No new stocks, forces, schema, extra replenishment or native callbacks. A compatibility preflight remains advisory; later physical checks stay mandatory." ], "estimated_scope": "One production file, existing planning test plus optional existing pool test; no new registered program required." }, "existing_test_route": { "primary": "tests/test_infantry_resupply_planning.py executes actual TryPlan/Stock/LauncherStock; extend Compatible double to honor both modes and actor+item compatibility rather than force launcher=true. Execute same actual bounded scan.", "regressions": [ "Frozen incompatible-only stock: ordinary TryPlan false; no HQ claim/token/trip/replay/cooldown/order/state change. Baseline should compile and assertion-fail.", "Compatible later stock after long incompatible prefix: true without prefix starvation; preserve96x32 bound.", "All incompatible, spent, absent/looted, no living attributable carrier: false.", "Same frozen cargo can serve original compatible squad; changing its compatibility alone changes admission.", "Launcher tests unchanged after helper generalization; same mode semantics.", "Optional actual PlanResupplyTask/pool control: impossible small-arms request no longer hides compatible lower-priority request." ], "secondary": [ "tests/test_infantry_supply_pool.py", "tests/test_infantry_resupply_coordinator.py", "tests/test_infantry_ammo_transfer.py if present" ], "negative_control": "Remove ordinary compatible-stock gate and confirm runtime failure at no-reservation assertion." }, "limits": [ "No native/fullsuite/target edits. Source apply-check passed. Independent test author owns actual-method red/green.", "No claim of autonomous rendezvous/transfer qualification.", "Worst-case compatible scan grows ordinary planning to at most3072 actor-magazine checks per attempted recipient, matching existing launcher bound. Real frame cost unmeasured; do not add speculative cache or truncate prefixes.", "Existing aggregate small-arms demand can still mask a depleted individual or include compatible weapons held by another nondepleted member; per-weapon demand is a separate schema feature and is outside this fix." ], "documentation_context": "docs/ai-feature-migration.json historical missing/partial entries are stale; post_audit_updates and docs/infantry-resupply.md show already implemented finite infantry, mounted, mine and launcher supply. This proposal repairs actual current ordinary admission rather than re-proposing missing launchers or pistols.", "sha256": { "addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c": "b01fa948f204d49acbfbdfc5fa641b1d914e0eb91081e92a93816ae52ae88b1e", "addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryAmmoTransfer.c": "99fa26beb0c0869d0cd694500f3bfc0705c2c1cf674dea90d98fb93a59570ef7", "addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c": "d873b5b689e918f8c907918d673304a184ac2e4a4cb6face527b37a67821ee9f", "tests/test_infantry_resupply_planning.py": "9929ee0f5a3272c348ee329355b6ba67fdcb745fc9ce1f377f6c989eae91bf9f", "tests/test_infantry_supply_pool.py": "6fc0053337bbb889021c6eba608796ef946ff4d30a1b01cf678927293218d9d2" }, "artifacts": { "patch": "/tmp/erri-resupply-source-0826/fix.patch", "manifest": "/tmp/erri-resupply-source-0826/source-manifest.json", "tests": "/tmp/erri-resupply-tests-0826" } }