--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c
@@ -347,6 +347,10 @@
   foreach (ERR_HQUnit unit : m_Units) if (unit.Group == group) return unit.LogisticsReservation;
   return 0;
  }
+ bool MineSupplyReady(SCR_AIGroup group, IEntity actor)
+ {
+  return Replication.IsServer() && MissionActive() && m_Equipment && m_Equipment.MineSupplyReady(group, actor);
+ }
  bool ReserveLogistics(SCR_AIGroup group, int token)
  {
   if (!Replication.IsServer() || token <= 0 || !MissionActive()) return false;
@@ -1292,6 +1296,10 @@
   // finite truck and delivered radio entries only after that scan fails.
   foreach (ERR_HQUnit mounted : m_Units)
    if (!ConvoyContact(mounted, now) && supply.TryPlanMounted(mounted, donor, m_Watch.Find(mounted.ForceSourceId), donorStatus, now)) return true;
+  // Optional finite mines are last: only a delivered known one-mine formation
+  // may top up an existing carrier; no new issue or engineer-task reset.
+  foreach (ERR_HQUnit mineRecipient : m_Units)
+   if (supply.TryPlanMines(mineRecipient, donor, m_Watch.Find(mineRecipient.ForceSourceId), donorStatus, now)) return true;
   return false;
  }
  protected void PlanConvoy(float now)
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
@@ -13,6 +13,13 @@
    && entry.AmmoState.Complete && entry.AmmoState.Members == entry.Count
    && entry.AmmoState.SmallArmsMuzzles > 0
    && entry.AmmoState.SmallArmsRounds + entry.AmmoState.SmallArmsChambers <= entry.Count * 30;
+ }
+ static bool MinePair(ERR_HQWatchEntry recipient, ERR_HQWatchEntry donor, float now)
+ {
+  return Fresh(recipient, now) && Fresh(donor, now) && recipient.SourceId != donor.SourceId
+   && recipient.AmmoState && recipient.AmmoState.Valid(recipient.Count)
+   && recipient.AmmoState.MineComplete && recipient.AmmoState.MineMembers == recipient.Count
+   && recipient.AmmoState.ReadyMines == 1 && vector.DistanceXZ(recipient.Position, donor.Position) <= 200;
  }
  static bool Pair(ERR_HQWatchEntry recipient, ERR_HQWatchEntry donor, float now)
  {
@@ -32,18 +39,25 @@
  protected ERR_HQUnit m_Donor;
  protected ref array<IEntity> m_Stock = {};
  protected ref array<IEntity> m_Spent = {};
+ protected ref array<IEntity> m_MineStock = {};
+ protected ref ERR_ConvoyMineStock m_MineBatch;
+ protected bool m_MineStockCaptured;
+ protected bool m_MineTrip;
+ protected int m_MineRecipientSlot = -1;
+ protected int m_MinesDelivered;
  protected ref array<IEntity> m_Members = {};
  protected ref array<IEntity> m_Served = {};
  protected ref map<string, int> m_Consumed = new map<string, int>();
  protected ref map<string, float> m_NextAttempt = new map<string, float>();
  protected ref ERR_HQRoute m_Order;
  protected ref ERR_InfantryAmmoTransfer m_Move;
+ protected ref ERR_InfantryMineTransfer m_MineMove;
  protected ref ERR_MountedResupply m_Mounted;
  protected IEntity m_Receiving;
  protected AIWaypoint m_MoveWaypoint;
  protected AIWaypoint m_HoldWaypoint;
  protected vector m_Rendezvous;
- protected int m_State; // 0 stock startup, 1 idle, 2 truck downlink, 3 stopped status, 4 infantry downlink, 5 transfer
+ protected int m_State; // 0 stock startup, 1 idle, 2 truck downlink, 3 stopped status, 4 infantry downlink, 5 transfer, 7 unresolved mine custody
  protected int m_Trip;
  protected int m_Token;
  protected int m_ReportId;
@@ -73,16 +87,23 @@
   return m_State;
  }
  ERR_MountedResupply Mounted() { return m_Mounted; }
- bool Unresolved() { return (m_Move && m_Move.Unresolved()) || (m_Mounted && m_Mounted.Unresolved()); }
+ bool Unresolved() { return (m_Move && m_Move.Unresolved()) || (m_MineMove && m_MineMove.Unresolved()) || (m_Mounted && m_Mounted.Unresolved()); }
  protected void PollTransfers(float now)
  {
   if (m_Mounted) m_Mounted.Tick(now);
   if (m_State <= 1 && m_Move && !m_Move.Unresolved()) m_Move = null;
+  if (m_MineMove && !m_MineMove.Unresolved() && (m_State <= 1 || m_State == 7))
+  {
+   m_MineMove = null;
+   if (m_State == 7) Finish("mine custody settled; original claims released without retry or refund");
+  }
  }
  int Delivered() { return m_Delivered; }
+ int MinesDelivered() { return m_MinesDelivered; }
  int StockCount() { return m_Stock.Count(); }
  protected void Audit(string reason)
  {
+  if (m_MineTrip) reason = "mine top-up: " + reason;
   m_Reason = reason;
   m_HQ.Journal().Write("INFANTRY SUPPLY", string.Format("convoy-slot=%1 trip=%2 state=%3 moved=%4 spent=%5/%6; %7", m_ConvoySlot, m_Trip, m_State, m_Delivered, m_Spent.Count(), m_Stock.Count(), reason), m_ReportId);
  }
@@ -163,6 +184,7 @@
   if (!m_Convoy.CargoIssued) return;
   ERR_SupplyConvoyTask supply = ERR_SupplyConvoyTask.Cast(m_Convoy);
   if (supply && !supply.MagazinesIssued) return;
+  if (supply) m_MineBatch = supply.MineStock;
   foreach (ERR_ConvoyCargoCallback operation : m_Convoy.Cargo)
    if (!operation.Finished) return;
   InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(m_Truck.Entity.FindComponent(InventoryStorageManagerComponent));
@@ -177,17 +199,28 @@
   }
   m_State = 1; Audit("truck magazine identities captured once after startup; absent/looted stock is never replaced");
  }
- bool TryPlan(ERR_HQUnit recipient, ERR_HQUnit donor, ERR_HQWatchEntry demand, ERR_HQWatchEntry donorStatus, float now)
- {
-  if (!Current() || m_State != 1 || m_Move || (m_Mounted && m_Mounted.Busy()) || m_Trip >= 128 || !TruckValid()) return false;
+ bool TryPlan(ERR_HQUnit recipient, ERR_HQUnit donor, ERR_HQWatchEntry demand, ERR_HQWatchEntry donorStatus, float now, bool mineTrip = false)
+ {
+  if (!Current() || m_State != 1 || m_Move || m_MineMove || (m_Mounted && m_Mounted.Busy()) || m_Trip >= 128 || !TruckValid()) return false;
   if (m_Truck.Combat.Held || m_Truck.SupplyToken > 0 || !recipient || !donor) return false;
   if (donor.Group != m_Truck.Group || recipient.HomeGuard || !Quiet(recipient) || !Quiet(donor)) return false;
   if (donor.Downlink || donor.PendingOrder || donor.PendingConvoyOrder) return false;
-  if (!ERR_InfantryResupplyRules.Pair(demand, donorStatus, now)) return false;
+  if (mineTrip)
+  {
+   if (!ERR_InfantryResupplyRules.MinePair(demand, donorStatus, now)) return false;
+  }
+  else if (!ERR_InfantryResupplyRules.Pair(demand, donorStatus, now)) return false;
   if (demand.SourceId != recipient.ForceSourceId || donorStatus.SourceId != donor.ForceSourceId) return false;
   if (demand.MessageId <= m_Consumed.Get(demand.SourceId) || now < m_NextAttempt.Get(demand.SourceId)) return false;
   bool available;
-  foreach (IEntity magazine : m_Stock) if (magazine && !m_Spent.Contains(magazine) && Contains(m_Truck.Entity, magazine)) { available = true; break; }
+  if (mineTrip)
+  {
+   if (!CaptureMines()) return false;
+   foreach (IEntity mine : m_MineStock)
+    if (ERR_InfantryMineTransfer.ReadyMine(mine) && !m_Spent.Contains(mine) && Contains(m_Truck.Entity, mine)) { available = true; break; }
+  }
+  else foreach (IEntity magazine : m_Stock) if (magazine && !m_Spent.Contains(magazine) && Contains(m_Truck.Entity, magazine)) { available = true; break; }
+  if (m_Spent.Count() >= 96) return false;
   if (!available) return false;
   m_Members.Clear();
   for (int i = 0; i < recipient.StatusSampler.InitialStrength(); i++)
@@ -202,18 +235,42 @@
   if (slot < 0) slot = 0; // Isolated legacy fixture uses the first convoy's range.
   int token = 100000 + slot * 128 + m_Trip + 1;
   if (!m_HQ.ReserveLogistics(recipient.Group, token)) { m_Recipient = null; m_Donor = null; return false; }
+  m_MineTrip = mineTrip; m_MineRecipientSlot = -1; m_Receiving = null;
   m_Trip++; m_Token = token; m_Truck.SupplyToken = token; m_ReportId = demand.MessageId; m_TripDelivered = 0; m_Served.Clear();
   m_Consumed.Set(demand.SourceId, demand.MessageId); m_NextAttempt.Set(demand.SourceId, now + 180000);
   m_Deadline = Math.Min(now + 120000, demand.ObservedAt + 180000); m_State = 2;
-  m_Order = m_HQ.Downlink(donor.Group, "INFANTRY SUPPLY HOLD", "stop existing ammo truck and report position", m_ReportId);
+  string purpose = "stop existing ammo truck and report position";
+  if (mineTrip) purpose += "; one finite PMN4 top-up for an existing carrier";
+  m_Order = m_HQ.Downlink(donor.Group, "INFANTRY SUPPLY HOLD", purpose, m_ReportId);
   if (!m_Order) Finish("truck radio downlink unavailable");
   else Audit("existing patrol reserved; truck hold awaits radio delivery");
   return true;
  }
+ // Optional mine startup must never delay normal magazine readiness. Pin the
+ // original batch during Stock(), then copy its closed exact identities once.
+ protected bool CaptureMines()
+ {
+  ERR_SupplyConvoyTask supply = ERR_SupplyConvoyTask.Cast(m_Convoy);
+  if (!supply || !m_MineBatch || supply.MineStock != m_MineBatch || !m_MineBatch.Complete()) return false;
+  if (m_MineStockCaptured) return !m_MineStock.IsEmpty();
+  m_MineStockCaptured = true;
+  int count = m_MineBatch.Count();
+  if (count < 0 || count > 2) return false;
+  for (int index = 0; index < count; index++)
+  {
+   IEntity item = m_MineBatch.At(index);
+   if (item && !m_MineStock.Contains(item)) m_MineStock.Insert(item);
+  }
+  return true;
+ }
+ bool TryPlanMines(ERR_HQUnit recipient, ERR_HQUnit donor, ERR_HQWatchEntry demand, ERR_HQWatchEntry donorStatus, float now)
+ {
+  return TryPlan(recipient, donor, demand, donorStatus, now, true);
+ }
  // Share exact frozen inventory identities and global radio replay state.
  bool TryPlanMounted(ERR_HQUnit recipient, ERR_HQUnit donor, ERR_HQWatchEntry demand, ERR_HQWatchEntry donorStatus, float now)
  {
-  if (!Current() || m_State != 1 || m_Move || m_ConvoySlot < 0 || !TruckValid(true)) return false;
+  if (!Current() || m_State != 1 || m_Move || m_MineMove || m_ConvoySlot < 0 || !TruckValid(true)) return false;
   if (m_Mounted && m_Mounted.Busy()) return false;
   if (!m_Mounted) m_Mounted = new ERR_MountedResupply(m_HQ, m_Mode, m_Convoy, m_ConvoySlot, m_Stock, m_Spent, m_Consumed, m_NextAttempt);
   return m_Mounted.Begin(recipient, donor, demand, donorStatus, now);
@@ -239,10 +296,58 @@
  {
   Audit(reason);
   if (m_Move) m_Move.Stop();
+  if (m_MineMove) m_MineMove.Stop();
   ClearWaypoints();
+  m_Order = null;
+  // A late native move must not race another truck's newer report. Retain both
+  // exact claims until this one submitted identity proves custody or deletion.
+  if (m_MineMove && m_MineMove.Unresolved()) { m_State = 7; return; }
   if (m_Recipient) m_HQ.ReleaseLogistics(m_Recipient.Group, m_Token);
   if (m_Truck && m_Truck.SupplyToken == m_Token) { m_Truck.SupplyToken = 0; m_Truck.SupplyHeld = false; }
-  m_Recipient = null; m_Donor = null; m_Order = null; m_Receiving = null; m_State = 1;
+  m_Recipient = null; m_Donor = null; m_Order = null; m_Receiving = null; m_State = 1; m_MineTrip = false; m_MineRecipientSlot = -1;
+ }
+ protected void TransferMine(float now)
+ {
+  if (m_MineMove)
+  {
+   int result = m_MineMove.Tick(now);
+   if (result == 0) return;
+   if (result < 0) { Finish("native mine transfer failed or expired; exact submitted identity stays spent"); return; }
+   m_MineMove = null; m_MinesDelivered++;
+   Finish("one exact finite PMN4 confirmed in the original carrier inventory"); return;
+  }
+  if (!m_Receiving)
+  {
+   int strength = m_Recipient.StatusSampler.InitialStrength();
+   for (int slot = 0; slot < strength && slot < 32; slot++)
+   {
+    IEntity actor = m_Recipient.StatusSampler.InitialMember(slot);
+    if (!actor || !m_Members.Contains(actor) || !m_Recipient.StatusSampler.CanAttribute(slot, actor, false)) continue;
+    if (!ERR_Actors.CanFight(actor) || vector.DistanceXZ(actor.GetOrigin(), m_Truck.Entity.GetOrigin()) > 4) continue;
+    if (!m_HQ.MineSupplyReady(m_Recipient.Group, actor)) continue;
+    if (!ERR_InfantryMineTransfer.Carrier(actor, m_Recipient.Group)) continue;
+    m_Receiving = actor; m_MineRecipientSlot = slot; break;
+   }
+   if (!m_Receiving) return;
+  }
+  if (!m_HQ.MineSupplyReady(m_Recipient.Group, m_Receiving)) return;
+  if (!m_Recipient.StatusSampler.CanAttribute(m_MineRecipientSlot, m_Receiving, false)
+   || !ERR_InfantryMineTransfer.Carrier(m_Receiving, m_Recipient.Group))
+  { Finish("original one-mine carrier lost or no longer has exactly one usable mine"); return; }
+  foreach (IEntity mine : m_MineStock)
+  {
+   if (!ERR_InfantryMineTransfer.ReadyMine(mine) || m_Spent.Contains(mine) || !Contains(m_Truck.Entity, mine)) continue;
+   ERR_FiniteMagazineReservation reservation = new ERR_FiniteMagazineReservation(m_MineStock, m_Spent, mine);
+   if (!reservation.Reserve()) continue;
+   m_MineMove = new ERR_InfantryMineTransfer(m_Mode, m_Truck.Entity, m_Truck.Group, m_Receiving, m_Recipient.Group,
+    mine, reservation, m_Recipient.StatusSampler, m_MineRecipientSlot);
+   m_MineMove.Tick(now);
+   // The leaf commits before the one native move. Only an unsubmitted refusal
+   // may release its tentative claim while the same carrier approaches/retries.
+   if (m_MineMove.Submitted()) return;
+   reservation.ReleaseUnsubmitted(); m_MineMove = null;
+   break;
+  }
  }
  protected void Transfer(float now)
  {
@@ -287,6 +392,7 @@
   m_NextTick = now + 1000;
   PollTransfers(now);
   if (m_Mounted && m_Mounted.Busy()) return;
+  if (m_State == 7) return;
   if (m_State == 0) { Stock(now); return; }
   if (m_State == 1)
   {
@@ -331,9 +437,17 @@
    if (delivered < 0 || !Waypoints()) { Finish("infantry order interrupted or native waypoint creation failed"); return; }
    m_Order = null; m_State = 5; Audit("infantry received reported rendezvous; native movement and physical transfer required");
   }
-  if (m_State == 5) Transfer(now);
- }
- string Status() { return string.Format("Infantry supply: state=%1 trips=%2 moved=%3 stock=%4 spent=%5; %6", State(), m_Trip, m_Delivered, m_Stock.Count(), m_Spent.Count(), m_Reason); }
+  if (m_State == 5)
+  {
+   if (m_MineTrip) TransferMine(now);
+   else Transfer(now);
+  }
+ }
+ string Status()
+ {
+  string detail = string.Format("Ground supply: state=%1 trips=%2 infantry moved=%3 stock=%4 spent=%5", State(), m_Trip, m_Delivered, m_Stock.Count(), m_Spent.Count());
+  return detail + string.Format("; mines moved=%1 initial=%2; %3", m_MinesDelivered, m_MineStock.Count(), m_Reason);
+ }
  void Stop()
  {
   if (m_Stopped) return;
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantrySupplyPool.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantrySupplyPool.c
@@ -66,15 +66,15 @@
  }
  string Status()
  {
-  int trucks, working, moved, stock;
+  int trucks, working, moved, stock, mines;
   foreach (ERR_InfantryResupply service : m_Services)
   {
    if (!service) continue;
    trucks++;
-   if (service.State() >= 2 && service.State() <= 6) working++;
-   moved += service.Delivered(); stock += service.StockCount();
+   if (service.State() >= 2 && service.State() <= 7) working++;
+   moved += service.Delivered(); stock += service.StockCount(); mines += service.MinesDelivered();
   }
-  return string.Format("Ground supply: %1 original trucks; %2 active trips; infantry moved=%3 original stock=%4", trucks, working, moved, stock);
+  return string.Format("Ground supply: %1 original trucks; %2 active trips; magazines moved=%3 original magazine stock=%4; mines moved=%5", trucks, working, moved, stock, mines);
  }
  void Stop()
  {
--- a/tests/test_hq_multiconvoy_supply.py
+++ b/tests/test_hq_multiconvoy_supply.py
@@ -8,7 +8,7 @@
 methods='\n'.join(body(p,s) for s in ('void PlanResupply(float now)','bool PlanResupplyTask(ERR_InfantryResupply supply, float now)'))
 methods=methods.replace('null','nullptr').replace('foreach (','for (')
 methods=methods.replace('ERR_HQUnit donor;','ERR_HQUnit donor=nullptr;')
-for name in ('m_Resupply','supply','task','unit','donor','recipient','mounted','m_Watch'):
+for name in ('m_Resupply','supply','task','unit','donor','recipient','mounted','mineRecipient','m_Watch'):
  methods=methods.replace(name+'.',name+'->')
 methods=methods.replace('task->Vehicles[1].','task->Vehicles[1]->')
 run(r'''
@@ -24,10 +24,11 @@
 struct Vehicle{int Group=0;};
 struct Task{bool Stopped=false,Ready=true;Array<Vehicle*> Vehicles;};using ERR_ConvoyTask=Task*;
 struct Supply{
- int state=1,calls=0,accepted=0,mountedCalls=0,mountedAccepted=0;bool infantry=true,mounted=false;Task*task=nullptr;Unit* recipient=nullptr;Entry* demand=nullptr;Entry* donorReport=nullptr;
+ int state=1,calls=0,accepted=0,mountedCalls=0,mountedAccepted=0;bool infantry=true,mounted=false,mines=false;int mineCalls=0,mineAccepted=0;Task*task=nullptr;Unit* recipient=nullptr;Entry* demand=nullptr;Entry* donorReport=nullptr;
  int State(){return state;}Task*Task(){return task;}
  bool TryPlan(Unit*r,Unit*,Entry*d,Entry*s,float){calls++;if(!infantry||r!=recipient||!d||!s||d!=demand||s!=donorReport)return false;accepted++;state=2;return true;}
  bool TryPlanMounted(Unit*r,Unit*,Entry*d,Entry*s,float){mountedCalls++;if(!mounted||r!=recipient||d!=demand||s!=donorReport||!d||!s)return false;mountedAccepted++;state=6;return true;}
+ bool TryPlanMines(Unit*r,Unit*,Entry*d,Entry*s,float){mineCalls++;if(!mines||r!=recipient||d!=demand||s!=donorReport||!d||!s)return false;mineAccepted++;state=2;return true;}
 };using ERR_InfantryResupply=Supply*;
 struct Pool{Array<Supply*> services;int Count(){return services.Count();}Supply*At(int i){return services[i];}};
 struct HQ{
@@ -42,6 +43,10 @@
  watch.delivered={{"a",&aStatus},{"b",&bStatus},{"recipient",&demand}};pool.services={&first,&second};hq.m_Resupply=&pool;hq.m_Watch=&watch;hq.m_Units={&da,&db,&recipient};}
 };
 int main(){
+ {Fixture f;f.first.infantry=false;f.first.mounted=false;f.first.mines=true;f.hq.PlanResupply(100);assert(f.first.mineAccepted==1&&f.first.mountedCalls>0&&f.second.calls==0);}
+ {Fixture f;f.first.mines=true;f.hq.PlanResupply(100);assert(f.first.accepted==1&&f.first.mineCalls==0);}
+ {Fixture f;f.first.infantry=false;f.first.mounted=true;f.first.mines=true;f.hq.PlanResupply(100);assert(f.first.mountedAccepted==1&&f.first.mineCalls==0);}
+
  {Fixture f;f.first.mounted=true;f.hq.PlanResupply(100);assert(f.first.accepted==1&&f.first.mountedCalls==0);}
  {Fixture f;f.first.infantry=false;f.first.mounted=true;f.hq.PlanResupply(100);assert(f.first.accepted==0&&f.first.mountedAccepted==1&&f.second.calls==0);}
  {Fixture f;f.first.infantry=false;f.first.mounted=true;f.recipient.fighting=true;f.hq.PlanResupply(100);assert(f.first.mountedAccepted==0);}
--- /dev/null
+++ b/tests/test_infantry_mine_coordinator.py
@@ -0,0 +1,77 @@
+"""Actual mine top-up selector plus the real shared finite reservation; native leaf is doubled."""
+import os,re
+from pathlib import Path
+from policy_harness import ROOT,body,run
+from test_finite_magazine_reservation import translated_reservation
+p=Path(os.environ.get('ERR_INFANTRY_RESUPPLY_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'))
+s=body(p,'protected void TransferMine(').replace('protected ','').replace('null','nullptr')
+s=s.replace('ERR_InfantryMineTransfer.', 'ERR_InfantryMineTransfer::').replace('ERR_Actors.', 'ERR_Actors::').replace('vector.DistanceXZ','Vec::DistanceXZ')
+s=s.replace('foreach (IEntity mine : m_MineStock)','for (IEntity mine : m_MineStock)')
+s=s.replace('ERR_FiniteMagazineReservation reservation', 'ERR_FiniteMagazineReservation* reservation').replace('new ERR_FiniteMagazineReservation(m_MineStock, m_Spent, mine)', 'new ERR_FiniteMagazineReservation(&m_MineStock, &m_Spent, mine)')
+for x in ['m_MineMove','m_Recipient','m_Truck','m_HQ','actor','m_Receiving','reservation']:s=s.replace(x+'.',x+'->')
+for x in ['StatusSampler','Entity']:s=s.replace(x+'.',x+'->')
+run(r'''
+#include <cassert>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cmath>
+using string=std::string;
+struct Vec{float x=0;static float DistanceXZ(Vec a,Vec b){return std::abs(a.x-b.x);}};
+struct Group{};struct Mode{};struct Entity{bool ready=false,fight=true,owned=true,grant=true;int mines=1;Vec pos;Vec GetOrigin(){return pos;}};using IEntity=Entity*;
+template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}void Insert(T v){this->push_back(v);}bool Contains(T v){return std::find(this->begin(),this->end(),v)!=this->end();}void RemoveItem(T v){this->erase(std::remove(this->begin(),this->end(),v),this->end());}};
+'''+translated_reservation()+r'''
+struct Sampler{Array<IEntity>original;int InitialStrength(){return original.Count();}IEntity InitialMember(int i){return original[i];}bool CanAttribute(int i,IEntity x,bool){return i>=0&&i<InitialStrength()&&original[i]==x&&x->owned;}};
+struct Unit{struct Group*Group;Sampler*StatusSampler;};struct Truck{IEntity Entity;struct Group*Group;};
+struct HQ{bool MineSupplyReady(Group*,IEntity x){return x&&x->grant;}};
+struct ERR_Actors{static bool CanFight(IEntity x){return x&&x->fight;}};
+struct ERR_InfantryMineTransfer{
+ static inline bool accept=true;static inline int made=0;IEntity item,actor;ERR_FiniteMagazineReservation*r;bool submitted=false;int result=0;
+ ERR_InfantryMineTransfer(Mode*,IEntity,Group*,IEntity a,Group*,IEntity i,ERR_FiniteMagazineReservation*q,Sampler*,int):item(i),actor(a),r(q){made++;}
+ static bool ReadyMine(IEntity x){return x&&x->ready;}
+ static IEntity Carrier(IEntity x,Group*){return x&&x->mines==1?x:nullptr;}
+ int Tick(float){if(accept&&!submitted){assert(r->Commit());submitted=true;}return result;}
+ bool Submitted(){return submitted;}
+};
+struct Service{
+ HQ*m_HQ;Mode*m_Mode;Unit*m_Recipient;Truck*m_Truck;IEntity m_Receiving=nullptr;int m_MineRecipientSlot=-1,m_MinesDelivered=0,finishes=0;ERR_InfantryMineTransfer*m_MineMove=nullptr;
+ Array<IEntity>m_Members,m_MineStock,m_Spent,cargo;
+ bool Contains(IEntity,IEntity x){return cargo.Contains(x);}void Finish(string){finishes++;}
+'''+s+r'''
+};
+struct Fixture{HQ h;Mode mode;Group g,d;Entity actor,other,truck,mine,second;Sampler sampler;Unit unit;Truck donor;Service s;
+ Fixture():sampler{{&actor,&other}},unit{&g,&sampler},donor{&truck,&d}{mine.ready=second.ready=true;s.m_HQ=&h;s.m_Mode=&mode;s.m_Recipient=&unit;s.m_Truck=&donor;s.m_Members={&actor,&other};s.m_MineStock={&mine,&second};s.cargo=s.m_MineStock;ERR_InfantryMineTransfer::accept=true;}
+};
+int main(){
+ // Never grant mines to zero/two-mine members or to unsettled initial grants.
+ for(int refusal=0;refusal<6;refusal++){Fixture f;f.other.mines=0;
+ if(refusal==0)f.actor.mines=0;if(refusal==1)f.actor.mines=2;if(refusal==2)f.actor.grant=false;if(refusal==3)f.actor.owned=false;if(refusal==4)f.actor.pos.x=5;if(refusal==5)f.actor.fight=false;
+ f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.empty()&&!f.s.m_Receiving);}
+ // One exact finite original identity and the same shared spent list.
+ {Fixture f;f.s.TransferMine(0);auto*leaf=f.s.m_MineMove;assert(leaf&&leaf->actor==&f.actor&&leaf->item==&f.mine&&f.s.m_Spent.Count()==1&&f.s.m_Spent[0]==&f.mine);
+ f.s.TransferMine(1000);assert(f.s.m_MineMove==leaf&&f.s.m_Spent.Count()==1);leaf->result=1;f.s.TransferMine(2000);assert(!f.s.m_MineMove&&f.s.m_MinesDelivered==1&&f.s.finishes==1&&f.s.m_Spent.Count()==1);}
+ // Preflight refusal may release only before native submission, keeping actor pinned.
+ {Fixture f;ERR_InfantryMineTransfer::accept=false;f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.empty()&&f.s.m_Receiving==&f.actor);
+ f.actor.mines=0;ERR_InfantryMineTransfer::accept=true;f.s.TransferMine(1000);assert(!f.s.m_MineMove&&f.s.finishes==1&&f.s.m_Spent.empty());}
+ {Fixture f;ERR_InfantryMineTransfer::accept=false;f.s.TransferMine(0);f.actor.grant=false;ERR_InfantryMineTransfer::accept=true;f.s.TransferMine(1000);assert(!f.s.m_MineMove&&f.s.m_Spent.empty());}
+ // Captured/absent original or already-spent cargo is unavailable; no substitute.
+ {Fixture f;f.s.cargo.clear();f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.empty());}
+ {Fixture f;f.s.m_Spent=f.s.m_MineStock;f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.Count()==2);}
+ {Fixture f;for(int i=0;i<96;i++)f.s.m_Spent.Insert(&f.truck);f.s.TransferMine(0);assert(!f.s.m_MineMove&&f.s.m_Spent.Count()==96);}
+ // Failure delegates cleanup while retaining the submitted leaf and spent item.
+ {Fixture f;f.s.TransferMine(0);auto*leaf=f.s.m_MineMove;leaf->result=-1;f.s.TransferMine(1000);assert(f.s.m_MineMove==leaf&&f.s.finishes==1&&f.s.m_Spent.Count()==1);}
+}
+'''.replace('if(refusal==0)f.actor.mines=0;if(refusal==1)f.actor.mines=2;if(refusal==2)f.actor.grant=false;if(refusal==3)f.actor.owned=false;if(refusal==4)f.actor.pos.x=5;if(refusal==5)f.actor.fight=false;', 'if(refusal==0){f.actor.mines=0;}if(refusal==1){f.actor.mines=2;}if(refusal==2){f.actor.grant=false;}if(refusal==3){f.actor.owned=false;}if(refusal==4){f.actor.pos.x=5;}if(refusal==5){f.actor.fight=false;}'))
+print('PASS: actual one-mine original carrier selection, settled startup, shared finite claims, no refund after submission')
+h=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'))
+w=body(h,'bool MineSupplyReady(').replace('SCR_AIGroup group','Group* group').replace('Replication.','Replication::').replace('m_Equipment.','m_Equipment->')
+run(r'''
+#include <cassert>
+struct Group{};struct Item{};using IEntity=Item*;
+struct Equipment{bool ready=false;Group*group=nullptr;IEntity actor=nullptr;bool MineSupplyReady(Group*g,IEntity a){return ready&&g==group&&a==actor;}};
+struct Replication{static inline bool server=true;static bool IsServer(){return server;}};
+struct HQ{Equipment*m_Equipment=nullptr;bool active=true;bool MissionActive(){return active;}
+'''+w+r'''};
+int main(){Group group,other;Item actor;Equipment e;e.group=&group;e.actor=&actor;HQ h;assert(!h.MineSupplyReady(&group,&actor));h.m_Equipment=&e;assert(!h.MineSupplyReady(&group,&actor));e.ready=true;assert(h.MineSupplyReady(&group,&actor));assert(!h.MineSupplyReady(&other,&actor));h.active=false;assert(!h.MineSupplyReady(&group,&actor));h.active=true;Replication::server=false;assert(!h.MineSupplyReady(&group,&actor));}
+''')
+print('PASS: actual HQ startup grant readiness forwarding is authoritative and fail-closed')
--- a/tests/test_infantry_resupply_coordinator.py
+++ b/tests/test_infantry_resupply_coordinator.py
@@ -13,7 +13,7 @@
  for kind in ['ERR_HQWatchEntry','Physics']:
   s=re.sub(r'\b'+kind+r' (\w+)',kind+r'* \1',s)
  # Enforce native entity/reference member access becomes C++ pointer member access.
- for name in ['entry','recipient','donor','stopped','m_HQ','m_Move','m_Mounted','m_Recipient','m_Donor','m_Truck','m_Order','physics']:
+ for name in ['entry','recipient','donor','stopped','m_HQ','m_Move','m_MineMove','m_Mounted','m_Recipient','m_Donor','m_Truck','m_Order','physics']:
   s=s.replace(name+'.',name+'->')
  for name in ['AmmoState','Group','Combat','Entity']:
   s=s.replace(name+'.',name+'->')
@@ -50,16 +50,20 @@
 struct Watch {ERR_HQWatchEntry* entry=nullptr;ERR_HQWatchEntry* Find(int){return entry;}};
 struct HQ {int token=7,releases=0,downlinks=0;struct Watch watch;Route* next=nullptr;int Journal(){return 0;}int LogisticsToken(Group*){return token;}void ReleaseLogistics(Group*,int owned){releases++;if(token==owned)token=0;}struct Watch* Watch(){return &watch;} Route* Downlink(Group*,string,string,int){downlinks++;return next;}};
 struct Service {
- HQ* m_HQ;Truck* m_Truck;Unit* m_Recipient;Unit* m_Donor;Leaf* m_Move=nullptr;Mounted*m_Mounted=nullptr;Route* m_Order=nullptr;Entity* m_Receiving=nullptr;
+ HQ* m_HQ;Truck* m_Truck;Unit* m_Recipient;Unit* m_Donor;Leaf* m_Move=nullptr;Leaf*m_MineMove=nullptr;bool m_MineTrip=false;int m_MineRecipientSlot=-1;Mounted*m_Mounted=nullptr;Route* m_Order=nullptr;Entity* m_Receiving=nullptr;
  Waypoint* m_MoveWaypoint=nullptr;Waypoint* m_HoldWaypoint=nullptr;Vec m_Rendezvous;int m_State=2,m_Token=7,m_ReportId=11;
  float m_NextTick=0,m_Deadline=200000,m_HeldAt=-1;bool m_Stopped=false,valid=true,quiet=true,roster=true,waypoints=true;int audits=0,transfers=0,waypointCalls=0,stocks=0;
- bool Current(){return !m_Stopped;}bool TruckValid(){return valid;}bool Quiet(Unit*){return quiet;}bool Roster(){return roster;}void Audit(string){audits++;}void Stock(float){stocks++;}bool Waypoints(){waypointCalls++;return waypoints;}void Transfer(float){transfers++;}
+ bool Current(){return !m_Stopped;}bool TruckValid(){return valid;}bool Quiet(Unit*){return quiet;}bool Roster(){return roster;}void Audit(string){audits++;}void Stock(float){stocks++;}bool Waypoints(){waypointCalls++;return waypoints;}void Transfer(float){transfers++;}int mineTransfers=0;void TransferMine(float){mineTransfers++;}
  METHODS
 };
 struct Fixture {Physics physics;Entity entity{&physics};Combat combat;Truck truck;Group group,donorGroup;Unit recipient{&group},donor{&donorGroup};HQ hq;Route order,next;Service s;
  Fixture(){truck.Combat=&combat;truck.Entity=&entity;s.m_HQ=&hq;s.m_Truck=&truck;s.m_Recipient=&recipient;s.m_Donor=&donor;s.m_Order=&order;hq.next=&next;}
 };
 int main(){
+ {Fixture f;Leaf leaf;f.s.m_MineMove=&leaf;f.s.m_MineTrip=true;f.truck.SupplyHeld=true;f.s.Stop();assert(f.s.m_State==7&&f.hq.token==7&&f.truck.SupplyHeld&&f.s.m_Recipient);
+ f.s.Tick(200000);assert(f.hq.token==7&&f.s.m_State==7&&f.s.transfers==0&&f.s.mineTransfers==0);leaf.unresolved=false;f.s.Tick(201000);assert(f.hq.token==0&&!f.truck.SupplyHeld&&f.s.m_State==1&&!f.s.m_MineMove);}
+ {Fixture f;f.s.m_State=5;f.s.m_MineTrip=true;f.s.Tick(0);assert(f.s.mineTransfers==1&&f.s.transfers==0);}
+
  Ammo ammo;ERR_HQWatchEntry demand,donor;demand.AmmoState=&ammo;donor.SourceId=2;donor.Position={200,500,0};
  assert(ERR_InfantryResupplyRules::Need(&demand,120000));assert(ERR_InfantryResupplyRules::Pair(&demand,&donor,120000));
  assert(!ERR_InfantryResupplyRules::Fresh(&demand,120001));assert(!ERR_InfantryResupplyRules::Fresh(nullptr,0));
@@ -119,7 +123,8 @@
 struct Service{Unit* m_Recipient;Mode* m_Mode;Array<Actor*> m_Members;bool Quiet(Unit*){return true;}
 METHOD
 };
-int main(){Group group;Actor soldier;soldier.group=&group;Agent agent{&soldier};group.agents={&agent};Sampler sampler{&group,false,1,{&soldier}};Unit unit{&group,&sampler};Mode mode;Service service{&unit,&mode,{&soldier}};assert(service.Roster());sampler.released=true;assert(!sampler.CanAttribute(0,&soldier));
+int main(){
+Group group;Actor soldier;soldier.group=&group;Agent agent{&soldier};group.agents={&agent};Sampler sampler{&group,false,1,{&soldier}};Unit unit{&group,&sampler};Mode mode;Service service{&unit,&mode,{&soldier}};assert(service.Roster());sampler.released=true;assert(!sampler.CanAttribute(0,&soldier));
 // Permanent sampler release survives returning to the physical group.
 assert(!service.Roster());sampler.released=false;assert(service.Roster());
 sampler.strength=33;assert(!service.Roster());sampler.strength=0;assert(!service.Roster());sampler.strength=1;
--- a/tests/test_infantry_resupply_planning.py
+++ b/tests/test_infantry_resupply_planning.py
@@ -13,11 +13,11 @@
  s=re.sub(r'foreach \((\w+) (\w+) : ([^)]+)\)',r'for (\1 \2 : \3)',s)
  for typ in ('InventoryStorageManagerComponent','ERR_ForceRecord','ERR_SupplyConvoyTask'):
   s=re.sub(r'\b'+typ+r' (?=\w)',typ+'* ',s)
- for name in ('ERR_ForceRules','ERR_InfantryResupplyRules','ERR_ConvoyRules','ERR_ForceKind','ERR_ConvoyResources','ERR_Inventory','ERR_Actors','SCR_FactionManager','CompartmentAccessComponent','Replication','Math'):
+ for name in ('ERR_ForceRules','ERR_InfantryResupplyRules','ERR_InfantryMineTransfer','ERR_ConvoyRules','ERR_ForceKind','ERR_ConvoyResources','ERR_Inventory','ERR_Actors','SCR_FactionManager','CompartmentAccessComponent','Replication','Math'):
   s=s.replace(name+'.',name+'::')
  s=s.replace('ERR_SupplyConvoyTask.Cast','ERR_SupplyConvoyTask::Cast').replace('FindComponent(BaseMagazineComponent)','HasMagazine()')
  s=s.replace('vector.DistanceXZ','Vec::DistanceXZ').replace('InventoryStorageManagerComponent.Cast','InventoryStorageManagerComponent::Cast').replace('FindComponent(InventoryStorageManagerComponent)','FindComponent()')
- for name in ('m_Mode','m_HQ','m_Convoy','m_Truck','m_Recipient','m_Donor','m_Move','m_Mounted','recipient','donor','demand','donorStatus','entry','operation','inventory','item','owner','record','actor','agent','unit','m_MoveWaypoint','m_HoldWaypoint','magazine','supply','m_Consumed','m_NextAttempt'):
+ for name in ('m_Mode','m_HQ','m_Convoy','m_Truck','m_Recipient','m_Donor','m_Move','m_MineMove','m_MineBatch','m_Mounted','recipient','donor','demand','donorStatus','entry','operation','inventory','item','owner','record','actor','agent','unit','m_MoveWaypoint','m_HoldWaypoint','magazine','supply','m_Consumed','m_NextAttempt'):
   s=s.replace(name+'.',name+'->')
  for name in ('Receipt','Entity','Group','Utility','StatusSampler','AmmoState','Combat','m_Perception'):
   s=s.replace(name+'.',name+'->')
@@ -25,8 +25,8 @@
  s=s.replace('ERR_SupplyConvoyTask* supply', 'Convoy* supply')
  s=s.replace('bool available;','bool available=false;').replace('bool living;','bool living=false;')
  return s
-rules='\n'.join(cpp(body(P,x)) for x in ('static bool Fresh(', 'static bool Need(', 'static bool Pair('))
-methods='\n'.join(cpp(body(P,x)) for x in ('bool Bind(', 'ERR_ConvoyTask Task(', 'protected bool ConvoyCurrent(', 'protected bool Contains(', 'protected bool TruckValid(', 'protected bool Quiet(', 'protected bool Roster(', 'protected void Stock(', 'bool TryPlan(', 'protected void ClearWaypoints(', 'protected void Finish(', 'void Stop('))
+rules='\n'.join(cpp(body(P,x)) for x in ('static bool Fresh(', 'static bool Need(', 'static bool Pair(', 'static bool MinePair('))
+methods='\n'.join(cpp(body(P,x)) for x in ('bool Bind(', 'ERR_ConvoyTask Task(', 'protected bool ConvoyCurrent(', 'protected bool Contains(', 'protected bool TruckValid(', 'protected bool Quiet(', 'protected bool Roster(', 'protected void Stock(', 'protected bool CaptureMines(', 'bool TryPlanMines(', 'bool TryPlan(', 'protected void ClearWaypoints(', 'protected void Finish(', 'void Stop('))
 reserve=cpp(body(H,'bool ReserveLogistics('))+cpp(body(H,'void ReleaseLogistics('))
 unique=cpp(body(I,'static int AppendUnique('))+cpp(body(I,'static int Items('))
 run(r'''
@@ -48,7 +48,7 @@
 struct InventoryStorageManagerComponent{Array<IEntity>items;void GetItems(Array<IEntity>& out){out=items;}static auto Cast(InventoryStorageManagerComponent* p){return p;}};
 struct Prefab{string name="magazine";string GetPrefabName(){return name;}};
 struct Group;using SCR_AIGroup=Group*;
-struct Entity{Prefab prefab;bool magazine=true,hasPrefab=true,alive=true,player=false,fight=true,aboard=false,captured=false,released=false;int faction=1;Group* group=nullptr;InventoryStorageManagerComponent* inventory=nullptr;bool HasMagazine(){return magazine;}Prefab* GetPrefabData(){return hasPrefab?&prefab:nullptr;}InventoryStorageManagerComponent* FindComponent(){return inventory;}};
+struct Entity{Prefab prefab;bool readyMine=false,magazine=true,hasPrefab=true,alive=true,player=false,fight=true,aboard=false,captured=false,released=false;int faction=1;Group* group=nullptr;InventoryStorageManagerComponent* inventory=nullptr;bool HasMagazine(){return magazine;}Prefab* GetPrefabData(){return hasPrefab?&prefab:nullptr;}InventoryStorageManagerComponent* FindComponent(){return inventory;}};
 struct Agent{IEntity actor;IEntity GetControlledEntity(){return actor;}};using AIAgent=Agent*;
 struct Waypoint{};
 struct Group{Array<AIAgent>agents;bool slave=false;int players=0,faction=1;bool IsSlave(){return slave;}int GetPlayerCount(bool){return players;}int GetFaction(){return faction;}void GetAgents(Array<AIAgent>& out){out=agents;}void RemoveWaypoint(Waypoint*){}};
@@ -58,7 +58,7 @@
 struct ERR_Inventory{
 '''+unique+r'''
 };
-struct Ammo{bool Complete=true;int Members=2,SmallArmsMuzzles=2,SmallArmsRounds=60,SmallArmsChambers=0;bool Valid(int n){return Members==n;}};
+struct Ammo{bool MineComplete=true;int MineMembers=2,ReadyMines=1;bool Complete=true;int Members=2,SmallArmsMuzzles=2,SmallArmsRounds=60,SmallArmsChambers=0;bool Valid(int n){return Members==n;}};
 struct Entry{bool Closed=false;int Count=2,Fit=2,MessageId=1;float ObservedAt=0;Vec Position;string SourceId;Ammo* AmmoState=nullptr;};using ERR_HQWatchEntry=Entry*;
 struct ERR_InfantryResupplyRules{
 '''+rules+r'''
@@ -75,19 +75,21 @@
 struct Truck{int Index=1,SupplyToken=0;bool Registered=true,Released=false,Arrived=false,SupplyHeld=false,crew=true;struct Entity* Entity=nullptr;struct Group* Group=nullptr;struct Combat* Combat=nullptr;bool CrewValid(Mode*){return crew;}};
 struct Receipt{bool Consumed=true;Array<int>Records={1,2,3,4,5,6};};
 struct Cargo{bool Finished=true;};using ERR_ConvoyCargoCallback=Cargo*;
-struct Convoy{bool supply=false,MagazinesIssued=true,CargoIssued=true,Stopped=false,Ready=true;struct Receipt* Receipt=nullptr;Array<Truck*>Vehicles;Array<struct Cargo*>Cargo;float Deadline=30000;};
+struct MineBatch{bool complete=true;Array<IEntity>items;bool Complete(){return complete;}int Count(){return items.Count();}IEntity At(int i){return items[i];}};
+struct Convoy{MineBatch*MineStock=nullptr;bool supply=false,MagazinesIssued=true,CargoIssued=true,Stopped=false,Ready=true;struct Receipt* Receipt=nullptr;Array<Truck*>Vehicles;Array<struct Cargo*>Cargo;float Deadline=30000;};
 using ERR_ConvoyTask=Convoy*;
 struct ConvoyService{Array<Convoy*>tasks;int Count(){return tasks.Count();}Convoy* At(int index){return index>=0&&index<Count()?tasks[index]:nullptr;}};
 struct ERR_SupplyConvoyTask:Convoy{static Convoy* Cast(Convoy* task){return task&&task->supply?task:nullptr;}};
 struct ERR_ConvoyRules{static bool Captured(Entity* e,Group*){return e->captured;}};
 struct ERR_ConvoyResources{static string Magazine(){return "magazine";}};
-struct Route{};struct Leaf{void Stop(){}};struct Mounted{bool busy=false;bool Busy(){return busy;}void Stop(){}};
+struct ERR_InfantryMineTransfer{static bool ReadyMine(IEntity x){return x&&x->readyMine;}};
+struct Route{};struct Leaf{bool unresolved=false;void Stop(){}bool Unresolved(){return unresolved;}};struct Mounted{bool busy=false;bool Busy(){return busy;}void Stop(){}};
 struct HQ{Mode* m_Mode;Array<ERR_HQUnit>m_Units;Convoy* convoy=nullptr;ConvoyService convoys;ConvoyService* Convoys(){return &convoys;}Route route;bool active=true,routeAvailable=true;int downlinks=0;bool MissionActive(){return active;}Convoy* ConvoyTask(){return convoy;}
  Route* Downlink(Group*,string,string,int){downlinks++;return routeAvailable?&route:nullptr;}
 '''+reserve+r'''
 };
-struct Service{HQ* m_HQ;Mode* m_Mode;Convoy* m_Convoy=nullptr;Truck* m_Truck=nullptr;Unit* m_Recipient=nullptr;Unit* m_Donor=nullptr;Leaf* m_Move=nullptr;Mounted*m_Mounted=nullptr;Route* m_Order=nullptr;IEntity m_Receiving=nullptr;
- Array<IEntity>m_Stock,m_Spent,m_Members,m_Served;Map<int>*m_Consumed=new Map<int>();Map<float>*m_NextAttempt=new Map<float>();int m_ConvoySlot=-1;float m_NextTick=0;int m_State=0,m_Trip=0,m_Token=0,m_ReportId=0,m_TripDelivered=0;float m_Deadline=0,m_StockDeadline=-1;bool m_Stopped=false;
+struct Service{HQ* m_HQ;Mode* m_Mode;Convoy* m_Convoy=nullptr;Truck* m_Truck=nullptr;Unit* m_Recipient=nullptr;Unit* m_Donor=nullptr;Leaf* m_Move=nullptr;Leaf*m_MineMove=nullptr;MineBatch*m_MineBatch=nullptr;bool m_MineTrip=false,m_MineStockCaptured=false;int m_MineRecipientSlot=-1;Mounted*m_Mounted=nullptr;Route* m_Order=nullptr;IEntity m_Receiving=nullptr;
+ Array<IEntity>m_Stock,m_MineStock,m_Spent,m_Members,m_Served;Map<int>*m_Consumed=new Map<int>();Map<float>*m_NextAttempt=new Map<float>();int m_ConvoySlot=-1;float m_NextTick=0;int m_State=0,m_Trip=0,m_Token=0,m_ReportId=0,m_TripDelivered=0;float m_Deadline=0,m_StockDeadline=-1;bool m_Stopped=false;
  Waypoint* m_MoveWaypoint=nullptr;Waypoint* m_HoldWaypoint=nullptr;string reason;bool Current(){return !m_Stopped&&Replication::IsServer()&&m_HQ->active;}void Audit(string why){reason=why;}
 '''+methods+r'''
 };
@@ -177,6 +179,21 @@
  {Fixture f;for(int i=48;i<96;i++)f.inventory.items.Insert(&f.items[i]);f.items[0].prefab.name="NATO_556_STANAG";
  f.items[96].magazine=false;f.inventory.items.Insert(&f.items[96]);f.s.Stock(0);
  assert(!f.s.m_Stopped&&f.s.m_State==1&&f.s.m_Stock.Count()==96&&f.s.m_Stock.Contains(&f.items[0])&&!f.s.m_Stock.Contains(&f.items[96]));}
+ // Mine demand is a detached known-one report, never a grant to zero or unknown.
+ {Fixture f;MineBatch batch;f.convoy.supply=true;f.convoy.MineStock=&batch;f.items[48].readyMine=true;batch.items={&f.items[48]};f.inventory.items.Insert(&f.items[48]);f.s.Stock(0);
+ for(int n: {0,2,3}){f.ammo.ReadyMines=n;assert(!f.s.TryPlanMines(&f.recipient,&f.donor,&f.demand,&f.donorStatus,0));}
+ f.ammo.ReadyMines=1;f.ammo.MineComplete=false;assert(!f.s.TryPlanMines(&f.recipient,&f.donor,&f.demand,&f.donorStatus,0));f.ammo.MineComplete=true;
+ batch.complete=false;assert(!f.s.TryPlanMines(&f.recipient,&f.donor,&f.demand,&f.donorStatus,0));batch.complete=true;
+ assert(f.s.TryPlanMines(&f.recipient,&f.donor,&f.demand,&f.donorStatus,0));assert(f.s.m_MineTrip&&f.s.m_MineStock.Count()==1);}
+ // A submitted unknown mine retains the real HQ claim across a newer delivered
+ // report and expired shared cooldown; a second truck cannot race the same actor.
+ {Fixture first,second;Leaf leaf;leaf.unresolved=true;first.s.Stock(0);assert(first.Plan());first.s.m_MineMove=&leaf;first.s.m_MineTrip=true;first.s.Finish("unknown native move");
+ assert(first.s.m_State==7&&first.recipient.LogisticsReservation==100001&&first.truck.SupplyToken==100001);
+ second.s.Stock(0);second.s.m_HQ=&first.hq;first.hq.convoy=&second.convoy;first.hq.convoys.tasks={&second.convoy};second.s.m_Consumed=first.s.m_Consumed;second.s.m_NextAttempt=first.s.m_NextAttempt;
+ first.Refresh(180001,2);second.donorStatus.ObservedAt=180001;
+ assert(!second.s.TryPlan(&first.recipient,&second.donor,&first.demand,&second.donorStatus,180001));assert(first.recipient.LogisticsReservation==100001);
+ leaf.unresolved=false;first.s.Finish("settled");assert(first.recipient.LogisticsReservation==0);
+ assert(second.s.TryPlan(&first.recipient,&second.donor,&first.demand,&second.donorStatus,180001));}
  // Removed stock is unavailable; a different magazine added after capture does not replace its identity.
  {Fixture f;f.s.Stock(0);f.inventory.items={&f.items[48]};assert(!f.Plan());f.Unchanged();f.inventory.items.Insert(&f.items[0]);assert(f.Plan());assert(f.s.m_Stock.Count()==48&&!f.s.m_Stock.Contains(&f.items[48]));}
  {Fixture f;f.s.Stock(0);f.s.m_Spent=f.s.m_Stock;assert(!f.Plan());f.Unchanged();}
--- a/tests/test_infantry_supply_pool.py
+++ b/tests/test_infantry_supply_pool.py
@@ -14,7 +14,7 @@
         source = source.replace(name + '.', name + '::')
     for name in ('m_HQ', 'm_Mode', 'service', 'retained', 'convoys'):
         source = source.replace(name + '.', name + '->')
-    source = source.replace('int trucks, working, moved, stock;', 'int trucks=0, working=0, moved=0, stock=0;')
+    source = source.replace('int trucks, working, moved, stock, mines;', 'int trucks=0, working=0, moved=0, stock=0, mines=0;')
     source = source.replace('string.Format', 'Format')
     return source
 
@@ -35,7 +35,7 @@
 struct Replication{static inline bool server=true;static bool IsServer(){return server;}};
 struct ERR_ForceRules{static bool Finite(float value){return std::isfinite(value);}};
 struct Math{static int Min(int a,int b){return a<b?a:b;}};
-string Format(string,int trucks,int working,int moved,int stock){return std::to_string(trucks)+":"+std::to_string(working)+":"+std::to_string(moved)+":"+std::to_string(stock);}
+string Format(string,int trucks,int working,int moved,int stock,int mines){return std::to_string(trucks)+":"+std::to_string(working)+":"+std::to_string(moved)+":"+std::to_string(stock)+":"+std::to_string(mines);}
 struct ERR_GameMode{bool active=true;static inline ERR_GameMode* current=nullptr;static ERR_GameMode* Get(){return current;}bool Active(){return active;}};
 struct ERR_ConvoyTask{};
 struct ERR_ConvoyService{Array<ERR_ConvoyTask*>tasks;int reads=0;int Count(){return tasks.Count();}ERR_ConvoyTask* At(int index){reads++;assert(index>=0&&index<tasks.Count());return tasks[index];}};
@@ -48,7 +48,7 @@
  ERR_ConvoyTask* Task(){return task;}
  void Tick(float){polls++;if(!stopped)ticks++;}
  void Stop(){stopCalls++;stopped=true;}
- int State(){return state;}int Delivered(){return moved;}int StockCount(){return stock;}
+ int mines=0;int MinesDelivered(){return mines;}int State(){return state;}int Delivered(){return moved;}int StockCount(){return stock;}
 };
 struct Pool{
  ERR_HQ* m_HQ=nullptr;ERR_GameMode* m_Mode=nullptr;Array<ERR_InfantryResupply*>m_Services;
@@ -78,7 +78,8 @@
  // Delivered demand consumption/cooldown state has exact shared identity across trucks.
  assert(a->consumed==b->consumed&&a->next==b->next);a->consumed->Set("patrol",17);a->next->Set("patrol",180000);
  assert(b->consumed->Get("patrol")==17&&b->next->Get("patrol")==180000);
- a->state=3;a->moved=2;b->moved=4;b->stock=8;assert(f.pool.Status()=="2:1:6:56");
+ a->state=3;a->moved=2;b->moved=4;b->stock=8;assert(f.pool.Status()=="2:1:6:56:0");
+ b->state=7;b->mines=1;assert(f.pool.Status()=="2:2:6:56:1");
  f.pool.Stop();assert(a->stopped&&b->stopped&&a->stopCalls==1&&b->stopCalls==1);f.pool.Stop();f.Add(1);f.pool.Tick(3000);
  assert(f.pool.Count()==2&&a->ticks==2&&b->ticks==2&&a->stopCalls==1&&b->stopCalls==1);}
  // Stopped and detached originals still receive bounded proof polls, never new work.
--- a/tests/test_mounted_supply_integration.py
+++ b/tests/test_mounted_supply_integration.py
@@ -6,7 +6,7 @@
 H=Path(os.environ.get('ERR_HQ_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c'))
 methods='\n'.join(body(S,x) for x in ('int State()', 'ERR_MountedResupply Mounted()', 'bool Unresolved()', 'protected void PollTransfers(', 'bool TryPlanMounted('))
 methods=methods.replace('protected ','').replace('null','nullptr').replace('ERR_MountedResupply Mounted()', 'ERR_MountedResupply* Mounted()')
-for n in ('m_Move','m_Mounted'):methods=methods.replace(n+'.',n+'->')
+for n in ('m_Move','m_MineMove','m_Mounted'):methods=methods.replace(n+'.',n+'->')
 for n in ('ERR_HQUnit','ERR_HQWatchEntry'):methods=re.sub(r'\b'+n+r' (\w+)',n+r'* \1',methods)
 run(r'''
 #include <cassert>
@@ -23,14 +23,15 @@
  bool Busy(){return busy;}bool Unresolved(){return unresolved;}void Tick(float){ticks++;}
 };
 struct Service{HQ*m_HQ=nullptr;Mode*m_Mode=nullptr;Convoy*m_Convoy=nullptr;int m_ConvoySlot=0,m_State=1;
- Stock*m_Stock=nullptr,*m_Spent=nullptr;Consumed*m_Consumed=nullptr;Cooldown*m_NextAttempt=nullptr;Leaf*m_Move=nullptr;ERR_MountedResupply*m_Mounted=nullptr;
- bool current=true,valid=true,arrived=false;bool Current(){return current;}bool TruckValid(bool allowArrived=false){return valid&&(!arrived||allowArrived);}
+ Stock*m_Stock=nullptr,*m_Spent=nullptr;Consumed*m_Consumed=nullptr;Cooldown*m_NextAttempt=nullptr;Leaf*m_Move=nullptr,*m_MineMove=nullptr;ERR_MountedResupply*m_Mounted=nullptr;
+ void Finish(const char*){m_State=1;}bool current=true,valid=true,arrived=false;bool Current(){return current;}bool TruckValid(bool allowArrived=false){return valid&&(!arrived||allowArrived);}
 '''+methods+r'''
 };
 int main(){
  HQ h;Mode m;Convoy c;Stock stock,spent;Consumed consumed;Cooldown next;ERR_HQUnit d,r;ERR_HQWatchEntry demand,status;
  Service s;s.m_HQ=&h;s.m_Mode=&m;s.m_Convoy=&c;s.m_Stock=&stock;s.m_Spent=&spent;s.m_Consumed=&consumed;s.m_NextAttempt=&next;s.m_ConvoySlot=7;
  s.m_State=0;assert(!s.TryPlanMounted(&r,&d,&demand,&status,0)&&!s.Mounted());s.m_State=1;
+ Leaf mine;s.m_MineMove=&mine;assert(!s.TryPlanMounted(&r,&d,&demand,&status,0)&&!s.Mounted()&&s.Unresolved());mine.unresolved=false;s.PollTransfers(0);assert(!s.m_MineMove);
  Leaf foot;s.m_Move=&foot;assert(!s.TryPlanMounted(&r,&d,&demand,&status,0)&&!s.Mounted()&&s.Unresolved());
  foot.unresolved=false;s.PollTransfers(0);assert(!s.m_Move);s.arrived=true;
  assert(s.TryPlanMounted(&r,&d,&demand,&status,0));auto*mounted=s.Mounted();
