Capture current mission, AI, map and administration development

Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
2026-10-13 22:52:53 +02:00
parent a951a96edc
commit 6a667d8deb
8104 changed files with 2124945 additions and 2061 deletions
+245
View File
@@ -0,0 +1,245 @@
"""Execute native mounted probe proof/termination methods; inspect read-only setup boundaries."""
import re, ast, os
from pathlib import Path
from policy_harness import ROOT, body, run
ROOT=Path(os.environ.get('ERR_NATIVE_SWAP_ROOT',ROOT))
p=Path(os.environ.get('ERR_NATIVE_MOUNTED_AMMO_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeMountedAmmoProbe.c'))
s=p.read_text();smoke=Path(os.environ.get('ERR_NATIVE_SMOKE_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c')).read_text()
runner=Path(os.environ.get('ERR_NATIVE_MOUNTED_RUNNER',ROOT/'tools/headless_workbench.py')).read_text()
assert s.startswith('#ifdef WORKBENCH') and s.rstrip().endswith('#endif')
for forbidden in ('Spawn(', 'SpawnEntity', 'TrySpawn', '.Ingest(', '.Advance(', '.Dispatch(', '.BindVehicle(', '.Sample(',
'.SetOrigin(', '.SetAmmoCount(', '.Kill(', '.SetHealth(', 'NextStatus =', 'PendingStatus =', 'Uplink =', 'new ERR_HQStatusReport'):
assert forbidden not in s,forbidden
assert 'checked=1 original convoy, deployed=%1 configured=%2' in s
assert 'if (!task || (m_ProofTask && task != m_ProofTask)) continue' in s
assert 'now + 180000' in s and 'now > m_Deadline' in s
assert s.index('Capture(hq, task.Vehicles[slot], now)') < s.index('if (!m_FleetReady) m_FleetReady = Fleet(hq)')
for evidence in ('cargoWeapons >= 8 && sample.Complete && sample.Weapons == 0', 'sample.Magazines == 0', 'sample.Capacity == 0',
'cargo.Count() <= 128', 'sample.Weapons > 0 && sample.Magazines > 0', 'Original(vehicle,',
'record.SourceId != unit.StatusSampler.InitialSourceId()', 'unit.StatusSampler.InitialMember(slot)',
'vehicle.Members.Count() > 32', 'm_Units.Count() && i < 256'):
assert evidence in s,evidence
start=smoke.split('if (m_ERRTestMountedAmmo)\n\t\t\t{',1)[1].split('\n\t\t\tif (m_ERRTestConvoy)',1)[0]
assert start.index('if (!ERR_Check(UnlockPrison(') < start.index('new ERR_NativeMountedAmmoProbe(this, now)')
assert start.index('mountedObserverDamage.EnableDamageHandling(false)') < start.index('UnlockPrison(')
assert 'm_ERRSmokeStep = 3000' in start and 'm_ERRMountedAmmo.Stop()' in smoke
assert 'm_ERRSmokeStep == 3001' in smoke and 'm_ERRMountedAmmo.Tick(ERR_HQ.Cast(Command()), now)' in smoke
# Execute only the selector condition AST, never the process-launching runner.
node=next(n for n in ast.parse(runner).body if isinstance(n,ast.If) and "mounted-ammo" in ast.unparse(n.test) and "mounted_swap_eligibility" not in ast.unparse(n.test) and "mounted_courier" not in ast.unparse(n.test))
condition=compile(ast.Expression(node.test),'<selector>','eval')
from types import SimpleNamespace
for project,rounds,timeout,bad in [('chat',1,360,False),('chat',1,359,True),('core',1,360,True),('chat',2,360,True)]:
assert eval(condition,{'a':SimpleNamespace(smoke='mounted-ammo',project=project,rounds=rounds,timeout=timeout)})==bad
code='\n'.join(body(p,x) for x in ('protected bool Same(', 'int Tick(', 'protected bool CheckTarget(', 'protected void Forget(', 'void Stop('))
code=code.replace('string.Empty','string{}').replace('protected ','').replace('null','nullptr').replace('ERR_GameMode.Get()', 'ERR_GameMode::Get()').replace('ERR_Actors.Alive(', 'ERR_Actors::Alive(')
for t in ('ERR_HQMountedAmmoSnapshot','ERR_HQ','ERR_ConvoyTask','ERR_HQWatchEntry'):
code=re.sub(r'\b'+t+r' (?=\w)',t+'* ',code)
for var in ('a','b','hq','m_Mode','task','m_Queued','delivered','m_Unit','m_Route','m_ProofTask','m_SwapProbe','m_BMPVehicle'):
code=re.sub(r'\b'+var+r'\.',var+'->',code)
for call in ('Convoys()','SupplyConvoys()','Watch()'):code=code.replace(call+'.',call+'->')
run(r'''
#include <cassert>
#include <string>
#include <vector>
using string=std::string;
struct ERR_HQMountedAmmoSnapshot{bool Complete=true;int Weapons=1,Muzzles=1,Magazines=1,Rounds=80,Capacity=100,Chambers=1,LowMagazines=0;};
struct Report{string SourceId="source";int MessageId=7,Strength=3,Count=3,Fit=3;float ObservedAt=1000;ERR_HQMountedAmmoSnapshot* MountedAmmo=nullptr;};
struct ERR_HQWatchEntry:Report{float LastDeliveredAt=2000;};
struct Root{bool alive=true;};struct ERR_Actors{static bool Alive(Root* r){return r&&r->alive;}};
struct Route{int MessageId=7;string Payload="original";};struct Unit{int Group=1;Report* PendingStatus=nullptr;Route* Uplink=nullptr;};
struct ERR_GameMode{bool active=true;static inline ERR_GameMode* current=nullptr;static ERR_GameMode* Get(){return current;}bool Active(){return active;}};
template<class T>struct Arr:std::vector<T>{int Count(){return this->size();}void Clear(){this->clear();}};
struct Escort{Root* Entity=nullptr;};struct ERR_ConvoyTask{bool Stopped=false;Arr<Escort*> Vehicles;};struct Pool{ERR_ConvoyTask* task=nullptr;int count=3;int Count(){return count;}ERR_ConvoyTask* At(int){return task;}};
struct Supply{int target=3;int Target(){return target;}string Status(){return "fixture production status";}};struct Watch{ERR_HQWatchEntry* entry=nullptr;ERR_HQWatchEntry* Find(string){return entry;}};
struct ERR_HQ{Pool pool;Supply supply;struct Watch watch;Unit* unit=nullptr;
Pool* Convoys(){return &pool;}Supply* SupplyConvoys(){return &supply;}struct Watch* Watch(){return &watch;}Unit* ERR_MountedFixtureUnit(int){return unit;}};
template<class... T>void PrintFormat(T...){}
struct SwapProbe{int result=1,calls=0,stops=0;int Tick(ERR_GameMode*,ERR_HQ*,ERR_ConvoyTask*){calls++;return result;}void Stop(){stops++;}};
struct Probe{bool m_BMP=false,original=true;Escort*m_BMPVehicle=nullptr;bool Original(Escort*,Unit*){return original;}bool BMPReady(Escort*,ERR_HQMountedAmmoSnapshot*s){return s&&s->Complete&&s->Weapons>0&&s->Magazines>0&&s->Rounds+s->Chambers>0;}bool m_MineStock=false,mineProof=true;int mineChecks=0;void*m_MineBatch=nullptr,*m_MineTruck=nullptr,*m_MineInventory=nullptr;Arr<int>m_Mines,m_PrimaryCargo;bool Mines(ERR_ConvoyTask*,bool){mineChecks++;return !m_MineStock||mineProof;}bool m_SwapEligibility=false;SwapProbe* m_SwapProbe=nullptr;ERR_ConvoyTask* candidate=nullptr;ERR_ConvoyTask* Candidate(ERR_HQ*){return candidate;}bool m_Stopped=false,m_Failed=false,m_FleetReady=false,fleet=true;float m_Deadline=180000,m_NextLog=0;
ERR_ConvoyTask* m_ProofTask=nullptr;ERR_GameMode* m_Mode=nullptr;Report* m_Queued=nullptr;ERR_HQMountedAmmoSnapshot* m_Payload=nullptr;Route* m_Route=nullptr;
int captures=0;string m_RoutePayload="original";Unit* m_Unit=nullptr;Root* m_Root=nullptr;
bool Check(bool b,string){if(!b)m_Failed=true;return b;}bool Fleet(ERR_HQ*){return fleet;}void Capture(ERR_HQ*,Escort*,float){captures++;}
'''+code+r'''
};
struct Setup{ERR_GameMode mode;ERR_HQ hq;Probe p;Root root;Unit unit;Route route;Report queued;ERR_HQWatchEntry delivered;
ERR_HQMountedAmmoSnapshot payload,original,received;
Setup(){ERR_GameMode::current=&mode;p.m_Mode=&mode;p.m_Queued=&queued;p.m_Payload=&payload;p.m_Route=&route;p.m_Unit=&unit;p.m_Root=&root;
unit.PendingStatus=&queued;unit.Uplink=&route;queued.MountedAmmo=&original;delivered.MountedAmmo=&received;hq.watch.entry=&delivered;hq.unit=&unit;}
};
int main(){
// BMP delivery cannot succeed through a different slot/root, lost ownership or incomplete payload.
for(int fault=0;fault<6;fault++){Setup s;ERR_ConvoyTask task;Escort bmp,other;Root replacement;
task.Vehicles.resize(6);bmp.Entity=&s.root;task.Vehicles[4]=&bmp;s.p.m_BMP=true;s.p.m_BMPVehicle=&bmp;s.p.m_ProofTask=&task;s.hq.pool.task=&task;
if(fault==1)task.Vehicles[4]=&other;if(fault==2)bmp.Entity=&replacement;if(fault==3)s.p.original=false;
if(fault==4){s.payload.Complete=false;s.original.Complete=false;s.received.Complete=false;}
if(fault==5){s.payload.Rounds=0;s.payload.Chambers=0;s.original=s.payload;s.received=s.payload;}
assert(s.p.Tick(&s.hq,3000)==(fault==0?1:-1));assert(s.p.captures==3); // exactly slot4 per observed task, never other slots
}
{Setup s;s.p.m_MineStock=true;s.p.mineProof=false;assert(s.p.Tick(&s.hq,3000)==-1&&s.p.mineChecks==1);}
{Setup s;s.p.m_MineStock=true;s.p.m_Mines.push_back(1);s.p.m_PrimaryCargo.push_back(2);s.p.m_MineBatch=&s;s.p.Stop();assert(s.p.m_Mines.empty()&&s.p.m_PrimaryCargo.empty()&&!s.p.m_MineBatch);}
{Setup s;SwapProbe dry;ERR_ConvoyTask task;s.p.m_SwapEligibility=true;s.p.m_SwapProbe=&dry;s.p.candidate=&task;
s.hq.watch.entry=nullptr;s.p.m_Queued=nullptr;assert(s.p.Tick(&s.hq,3000)==1&&dry.calls==1&&s.p.captures==0);
assert(!s.p.m_FleetReady&&s.p.m_ProofTask==&task);s.p.Stop();assert(dry.stops==1);}
{Setup s;SwapProbe dry;s.p.m_SwapEligibility=true;s.p.m_SwapProbe=&dry;
assert(s.p.Tick(&s.hq,3000)==0&&dry.calls==0&&s.p.captures==0);assert(s.p.Tick(&s.hq,180001)==-1&&dry.calls==0);}
{Setup s;assert(s.p.Tick(&s.hq,3000)==1&&!s.p.m_Failed);}
for(int field=0;field<8;field++){Setup s;if(field==0)s.received.Complete=false;if(field==1)s.received.Weapons++;
if(field==2)s.received.Muzzles++;if(field==3)s.received.Magazines++;if(field==4)s.received.Rounds++;
if(field==5)s.received.Capacity++;if(field==6)s.received.Chambers++;if(field==7)s.received.LowMagazines++;
assert(s.p.Tick(&s.hq,3000)==-1&&s.p.m_Failed);}
for(int fault=0;fault<12;fault++){Setup s;
if(fault==0)s.delivered.MountedAmmo=&s.original;if(fault==1)s.delivered.MountedAmmo=&s.payload;
if(fault==2)s.delivered.ObservedAt=999;if(fault==3)s.delivered.LastDeliveredAt=999;
if(fault==4)s.delivered.LastDeliveredAt=3001;if(fault==5)s.delivered.LastDeliveredAt=122000;
if(fault==6)s.delivered.Count--;if(fault==7)s.delivered.Fit--;if(fault==8)s.route.Payload="changed";
if(fault==9)s.route.MessageId++;if(fault==10)s.root.alive=false;if(fault==11)s.hq.unit=nullptr;
assert(s.p.Tick(&s.hq,3000)==-1);}
{Setup s;s.delivered.MessageId=6;assert(s.p.Tick(&s.hq,3000)==0);s.delivered.MessageId=8;assert(s.p.Tick(&s.hq,3000)==-1);}
{Setup s;s.p.fleet=false;assert(s.p.Tick(&s.hq,3000)==0);assert(s.p.Tick(&s.hq,180001)==-1);assert(s.p.m_Deadline==180000);}
{Setup s;s.hq.watch.entry=nullptr;s.unit.PendingStatus=nullptr;s.unit.Uplink=nullptr;assert(s.p.Tick(&s.hq,3000)==0);
assert(!s.p.m_Queued&&!s.p.m_Stopped&&s.p.m_Deadline==180000);}
{Setup s;s.p.m_Queued=nullptr;assert(s.p.Tick(&s.hq,3000)==0);}
{Setup s;s.hq.supply.target=2;assert(s.p.Tick(&s.hq,3000)==-1);}
{Setup s;s.hq.pool.count=4;assert(s.p.Tick(&s.hq,3000)==-1);}
{Setup s;s.mode.active=false;assert(s.p.Tick(&s.hq,3000)==-1);}
{Setup s;s.p.Stop();s.p.Stop();assert(!s.p.m_Queued&&!s.p.m_Payload&&!s.p.m_Route&&!s.p.m_Root&&!s.p.m_Unit);assert(s.p.Tick(&s.hq,3000)==-1);}
}
'''.replace(';if(', ';\n if('))
print('PASS: actual bounded native mounted proof/detached payload/deadline/cleanup methods, production-only setup and isolated runner selector')
candidate=body(p,'protected ERR_SupplyConvoyTask Candidate(').replace('protected ','').replace('null','nullptr')
candidate=candidate.replace('ERR_SupplyConvoyTask.Cast(hq.Convoys().At(i))','hq->Convoys()->At(i)')
candidate=candidate.replace('ERR_HQ hq','ERR_HQ* hq').replace('ERR_SupplyConvoyTask ', 'ERR_SupplyConvoyTask* ')
candidate=candidate.replace('foreach (','for (').replace('hq.Convoys().','hq->Convoys()->')
for var in ('task','pending','vehicle'):candidate=candidate.replace(var+'.',var+'->')
candidate=candidate.replace('bool ownsRoot;', 'bool ownsRoot=false;').replace('m_MineBatch.','m_MineBatch->')
run(r'''
#include <cassert>
#include <vector>
template<class T>struct Arr:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}void Clear(){this->clear();}};
struct Vehicle{int Entity=0;};using ERR_ConvoyVehicle=Vehicle*;
struct Cargo{bool Finished=true;};using ERR_ConvoyCargoCallback=Cargo*;
struct MineBatch{bool Complete(){return true;}};
struct ERR_SupplyConvoyTask{MineBatch*MineStock=nullptr;bool Stopped=false,Ready=true,MagazinesIssued=true,Receipt=true;Arr<Vehicle*> Vehicles;Arr<struct Cargo*> Cargo;
ERR_SupplyConvoyTask(){Vehicles.resize(6);}};
struct Pool{Arr<ERR_SupplyConvoyTask*> tasks;int reads=0;int Count(){return tasks.Count();}ERR_SupplyConvoyTask* At(int i){reads++;return tasks[i];}};
struct ERR_HQ{Pool pool;Pool* Convoys(){return &pool;}};
struct Probe{bool m_MineStock=false;ERR_SupplyConvoyTask*m_ProofTask=nullptr;MineBatch*m_MineBatch=nullptr;bool Check(bool yes,const char*){return yes;}bool m_Queued=false;int m_Root=42;
'''+candidate+r'''
};
int main(){
ERR_HQ hq;Probe p;ERR_SupplyConvoyTask first,second,third,fourth;Vehicle owned;owned.Entity=42;
assert(p.Candidate(&hq)==nullptr);
hq.pool.tasks={&first};assert(p.Candidate(&hq)==&first); // one actual convoy sufficient
hq.pool.tasks={&first,&second};first.Ready=false;assert(p.Candidate(&hq)==&second);
first.Ready=true;p.m_Queued=true;second.Vehicles[3]=&owned;assert(p.Candidate(&hq)==&second); // exact captured sender's task
second.Vehicles[3]=nullptr;assert(p.Candidate(&hq)==nullptr);
p.m_Queued=false;hq.pool.tasks={&first};
for(int failure=0;failure<7;failure++){
ERR_SupplyConvoyTask t;Cargo pending;hq.pool.tasks={&t};
if(failure==0)t.Stopped=true;
if(failure==1)t.MagazinesIssued=false;
if(failure==2)t.Receipt=false;
if(failure==3)t.Vehicles.resize(5);
if(failure==4){pending.Finished=false;t.Cargo={&pending};}
if(failure==5)t.Cargo={nullptr};
if(failure==6)t.Cargo.resize(129,&pending);
assert(p.Candidate(&hq)==nullptr);
}
first.Ready=false;second.Ready=false;third.Ready=false;hq.pool.tasks={&first,&second,&third,&fourth};hq.pool.reads=0;
assert(p.Candidate(&hq)==nullptr&&hq.pool.reads==3); // no fourth candidate traversal
}
''')
print('PASS: actual one-existing-convoy candidate readiness, sender-root identity, incomplete cargo refusal and fixed three-candidate bound')
# Execute the exact Capture and BMPReady methods; native identity/roster/watch
# boundaries are explicit doubles, while the snapshot validator has its own full suite.
selected=[]
if 'protected bool BMPReady(' in s: selected.append(body(p,'protected bool BMPReady('))
selected.append(body(p,'protected void Capture('))
capture='\n'.join(selected).replace('protected ','').replace('null','nullptr')
for ns in ('ERR_ConvoyResources','ERR_HQWatchRules'):
capture=capture.replace(ns+'.',ns+'::')
for t in ('ERR_ConvoyVehicle','ERR_HQMountedAmmoSnapshot','ERR_HQ','ERR_HQUnit','ERR_HQStatusReport','ERR_HQWatchEntry'):
capture=re.sub(r'\b'+t+r' (?=\w)',t+'* ',capture)
for v in ('vehicle','sample','hq','unit','report','before','m_Route','m_Payload'):
capture=re.sub(r'\b'+v+r'\.',v+'->',capture)
for x in ('Entity','MountedAmmo','StatusSampler','Uplink'):
capture=capture.replace('.'+x+'.','.'+x+'->').replace('->'+x+'.','->'+x+'->')
for x in ('GetPrefabData()','Watch()'):
capture=capture.replace(x+'.',x+'->')
capture=capture.replace('unit->Uplink->Nodes.Count()', 'int(unit->Uplink->Nodes.size())')
run(r'''
#include <cassert>
#include <string>
#include <vector>
struct string:std::string{using std::string::string;string(const std::string&s):std::string(s){}bool Contains(const char*s){return find(s)!=npos;}};
struct Prefab{string name="bmp";string GetPrefabName(){return name;}};
struct Entity{Prefab prefab;Prefab*GetPrefabData(){return &prefab;}};
struct ERR_ConvoyResources{static string VehiclePrefab(int slot){assert(slot==4);return "bmp";}};
struct ERR_HQMountedAmmoSnapshot{bool Complete=true,valid=true;int Weapons=3,Magazines=3,Rounds=80,Chambers=1;
bool Valid(){return valid;}ERR_HQMountedAmmoSnapshot*Snapshot(){return new ERR_HQMountedAmmoSnapshot(*this);}};
struct ERR_ConvoyVehicle{struct Entity*Entity=nullptr;bool Registered=true;int Group=1;};
struct ERR_HQStatusReport{ERR_HQMountedAmmoSnapshot*MountedAmmo=nullptr;int MessageId=7;string SourceId="source";};
struct ERR_HQWatchEntry{int MessageId=6;};
struct Sampler{string InitialSourceId(){return "source";}};
struct Route{int MessageId=7,Cursor=0;std::vector<int>Nodes={1,2};string Payload="mounted ammunition=original";};
struct ERR_HQUnit{ERR_HQStatusReport*PendingStatus=nullptr;Route*Uplink=nullptr;Sampler*StatusSampler=nullptr;};
struct Watch{ERR_HQWatchEntry*entry=nullptr;ERR_HQWatchEntry*Find(string){return entry;}};
struct ERR_HQ{ERR_HQUnit*unit=nullptr;struct Watch watch;ERR_HQUnit*ERR_MountedFixtureUnit(int){return unit;}struct Watch*Watch(){return &watch;}};
struct ERR_HQWatchRules{static bool Valid(ERR_HQStatusReport*,float){return true;}};
struct Probe{bool m_BMP=true,original=true,failed=false;ERR_ConvoyVehicle*m_BMPVehicle=nullptr;ERR_HQStatusReport*m_Queued=nullptr;ERR_HQUnit*m_Unit=nullptr;Entity*m_Root=nullptr;ERR_HQMountedAmmoSnapshot*m_Payload=nullptr;Route*m_Route=nullptr;string m_RoutePayload;
bool Original(ERR_ConvoyVehicle*,ERR_HQUnit*){return original;}bool Check(bool x,const char*){if(!x)failed=true;return x;}
bool Same(ERR_HQMountedAmmoSnapshot*a,ERR_HQMountedAmmoSnapshot*b){return a->Complete==b->Complete&&a->Weapons==b->Weapons&&a->Magazines==b->Magazines&&a->Rounds==b->Rounds&&a->Chambers==b->Chambers;}
'''+capture+r'''
};
struct Setup{Probe p;Entity root;ERR_ConvoyVehicle vehicle;ERR_HQ hq;ERR_HQUnit unit;Sampler sampler;Route route;ERR_HQStatusReport report;ERR_HQMountedAmmoSnapshot sample;
Setup(){vehicle.Entity=&root;hq.unit=&unit;unit.PendingStatus=&report;unit.Uplink=&route;unit.StatusSampler=&sampler;report.MountedAmmo=&sample;}};
int main(){
{Setup s;s.root.prefab.name="uaz";s.p.Capture(&s.hq,&s.vehicle,1000);assert(!s.p.m_Queued&&!s.p.m_Payload);}
for(int bad=0;bad<6;bad++){Setup s;if(bad==0)s.sample.Complete=false;if(bad==1)s.sample.valid=false;
if(bad==2)s.sample.Weapons=0;if(bad==3)s.sample.Magazines=0;if(bad==4){s.sample.Rounds=0;s.sample.Chambers=0;}if(bad==5)s.p.original=false;
s.p.Capture(&s.hq,&s.vehicle,1000);assert(!s.p.m_Queued&&!s.p.m_BMPVehicle);}
{Setup s;s.p.Capture(&s.hq,&s.vehicle,1000);assert(s.p.m_Queued==&s.report&&s.p.m_BMPVehicle==&s.vehicle&&s.p.m_Root==&s.root);
assert(s.p.m_Payload!=&s.sample&&s.p.m_Payload->Complete&&s.p.m_Route==&s.route&&!s.p.failed);
s.sample.Rounds=0;assert(s.p.m_Payload->Rounds==80);}
{Setup s;s.p.m_BMP=false;s.root.prefab.name="uaz";s.sample.Complete=false;s.p.Capture(&s.hq,&s.vehicle,1000);assert(s.p.m_Queued==&s.report&&!s.p.m_BMPVehicle);}
}
'''.replace(';if(', ';\n if('))
node=next(n for n in ast.parse(runner).body if isinstance(n,ast.If) and ast.unparse(n.test).startswith('a.mounted_bmp and'))
condition=compile(ast.Expression(node.test),'<bmp-selector>','eval')
for field in [None,'smoke','project','rounds','timeout','mine_stock','mounted_courier','mounted_swap_eligibility']:
values=dict(mounted_bmp=True,smoke='mounted-ammo',project='chat',rounds=1,timeout=360,mine_stock=False,mounted_courier=False,mounted_swap_eligibility=False)
if field:values[field]={'smoke':'convoy','project':'core','rounds':2,'timeout':359}.get(field,True)
assert eval(condition,{'a':SimpleNamespace(**values)})==(field is not None)
assert "if a.mounted_bmp: command += ['-errMountedBMP', '1']" in runner
print('PASS: actual BMP capture requires complete armed exact original resource; pinned delivery/slot checks and isolated CLI flag')
# WORKBENCH isolation changes only unrelated services before the real unlock.
assert start.index('!mixedBMP && StartMode() == 0 && Phase() == ERR_Phase.PRISON') < start.index('bmpHQ.ERR_IsolateMountedBMP()') < start.index('UnlockPrison(')
assert all(x in start for x in ('errMineStock','errMountedSwapEligibility','errMountedCourier'))
hook_path=Path(os.environ.get('ERR_NATIVE_SMOKE_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c'))
hook=body(hook_path,'bool ERR_IsolateMountedBMP(').replace('ERR_NativeMountedAmmoProbe.','ERR_NativeMountedAmmoProbe::').replace('System.','System::').replace('ERR_GameMode.','ERR_GameMode::').replace('ERR_Phase.','ERR_Phase::')
for v in ('m_Mode','m_Hunters','m_Towns'):hook=hook.replace(v+'.',v+'->')
run(r'''
#include <cassert>
#include <string>
using string=std::string;
struct ERR_NativeMountedAmmoProbe{static inline bool enabled=true;static bool Enabled(){return enabled;}};
struct System{static inline string flag="1";static bool GetCLIParam(string key,string&out){assert(key=="errMountedBMP");out=flag;return !flag.empty();}};
struct ERR_Phase{static constexpr int PRISON=1;};
struct ERR_GameMode{int start=0,phase=1;static inline ERR_GameMode*current=nullptr;static ERR_GameMode*Get(){return current;}int StartMode(){return start;}int Phase(){return phase;}};
struct Service{int deployed=0,stops=0;int Deployed(){return deployed;}void Stop(){stops++;}};
struct HQ{ERR_GameMode*m_Mode=nullptr;Service*m_Hunters=nullptr,*m_Towns=nullptr;
'''+hook+r'''
};
int main(){for(int fault=0;fault<10;fault++){
ERR_GameMode mode,other;ERR_GameMode::current=&mode;Service hunters,towns;HQ h;h.m_Mode=&mode;h.m_Hunters=&hunters;h.m_Towns=&towns;
ERR_NativeMountedAmmoProbe::enabled=true;System::flag="1";
if(fault==1)ERR_NativeMountedAmmoProbe::enabled=false;if(fault==2)System::flag="";if(fault==3)System::flag="0";
if(fault==4)ERR_GameMode::current=&other;if(fault==5)mode.start=1;if(fault==6)mode.phase=2;
if(fault==7)hunters.deployed=1;if(fault==8)h.m_Hunters=nullptr;if(fault==9)h.m_Towns=nullptr;
assert(h.ERR_IsolateMountedBMP()==(fault==0));assert(hunters.stops==(fault==0?1:0)&&towns.stops==(fault==0?1:0));
}}
'''.replace(';if(', ';\n if('))
print('PASS: actual opt-in pre-unlock isolation refuses wrong mode/phase/flag and existing hunters; no baseline service changes')