Harden base progression and cleanup; validate finite physical resupply
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
"""Execute actual gate method and document pre-inventory guard; no native/MP claim."""
|
||||
from policy_harness import ROOT, body, run
|
||||
unlock = body(ROOT/'addons/core/Scripts/Game/ERR/ERR_GameMode.c', 'bool UnlockPrison(')
|
||||
recover = body(ROOT/'addons/core/Scripts/Game/ERR/ERR_DiscoveryService.c', 'protected void Recover(')
|
||||
# Run precisely the production admission prefix. Inventory is the observable
|
||||
# boundary: rejected bodies must never inspect or spend their carried documents.
|
||||
assert recover.count('InventoryStorageManagerComponent inventory') == 1
|
||||
prefix = recover[:recover.index('InventoryStorageManagerComponent inventory')]
|
||||
prefix = prefix.replace('protected void Recover(', 'void Recover(') + 'inventoryReads++;\n}'
|
||||
def cpp(s):
|
||||
for namespace in ('Replication','ERR_Actors','SCR_FactionManager','vector','ERR_Phase'):
|
||||
s=s.replace(namespace+'.', namespace+'::')
|
||||
for var in ('m_Mode','m_Roster','player'):
|
||||
s=s.replace(var+'.',var+'->')
|
||||
return s.replace('Players().','Players()->')
|
||||
run('''#include <cassert>
|
||||
struct Point {float x;};
|
||||
struct Faction {};
|
||||
struct Actor {bool alive=true;bool conscious=true;Faction* faction=nullptr;Point origin{0};Point GetOrigin(){return origin;}};
|
||||
using IEntity=Actor*;
|
||||
namespace Replication {bool server=true;bool IsServer(){return server;}}
|
||||
namespace ERR_Actors {bool Alive(IEntity p){return p&&p->alive;}bool CanFight(IEntity p){return Alive(p)&&p->conscious;}}
|
||||
namespace SCR_FactionManager {Faction* SGetFaction(IEntity p){return p?p->faction:nullptr;}}
|
||||
namespace vector {float DistanceXZ(Point a,Point b){return a.x>b.x?a.x-b.x:b.x-a.x;}}
|
||||
namespace ERR_Phase {constexpr int PRISON=1,RADIO_SEARCH=2;}
|
||||
struct Roster {IEntity actor=nullptr;bool connected=true,used=true,sameAccount=true; bool CurrentActor(IEntity p){return p&&p==actor&&connected&&used&&sameAccount;}};
|
||||
struct Mode {
|
||||
Roster* m_Roster=nullptr;Faction* faction=nullptr;int m_Phase=1, transitions=0;
|
||||
Roster* Players(){return m_Roster;}Faction* PlayerFaction(){return faction;}
|
||||
Point PrisonPosition(){return {0};}bool Transition(int phase){m_Phase=phase;transitions++;return true;}
|
||||
'''+cpp(unlock)+'''
|
||||
};
|
||||
struct Discovery {Mode* m_Mode=nullptr;int inventoryReads=0;
|
||||
'''+cpp(prefix)+'''
|
||||
};
|
||||
int main(){
|
||||
Faction friendly,foreign;Actor prisoner,other;prisoner.faction=&friendly;other.faction=&friendly;
|
||||
Roster roster;roster.actor=&prisoner;Mode mode;mode.m_Roster=&roster;mode.faction=&friendly;
|
||||
Discovery discovery;discovery.m_Mode=&mode;
|
||||
auto denyBoth=[&](Actor* p){mode.m_Phase=1;int before=discovery.inventoryReads, prior=mode.transitions;assert(!mode.UnlockPrison(p));discovery.Recover(p);assert(discovery.inventoryReads==before&&mode.transitions==prior);};
|
||||
denyBoth(nullptr);denyBoth(&other); // player-controlled replacement is not the round body
|
||||
roster.connected=false;denyBoth(&prisoner);roster.connected=true;
|
||||
roster.used=false;denyBoth(&prisoner);roster.used=true;
|
||||
roster.sameAccount=false;denyBoth(&prisoner);roster.sameAccount=true;
|
||||
prisoner.faction=&foreign;denyBoth(&prisoner);prisoner.faction=&friendly;
|
||||
mode.faction=nullptr;denyBoth(&prisoner);mode.faction=&friendly;
|
||||
mode.m_Roster=nullptr;denyBoth(&prisoner);mode.m_Roster=&roster;
|
||||
prisoner.alive=false;denyBoth(&prisoner);prisoner.alive=true;
|
||||
Replication::server=false;denyBoth(&prisoner);Replication::server=true;
|
||||
// Restoring the canonical reconnect relation requires no replacement life.
|
||||
mode.m_Phase=1;assert(mode.UnlockPrison(&prisoner));discovery.Recover(&prisoner);assert(discovery.inventoryReads==1);
|
||||
// Canonical living unconscious inventory still reveals documents, but no lock picking.
|
||||
mode.m_Phase=1;prisoner.conscious=false;assert(!mode.UnlockPrison(&prisoner));discovery.Recover(&prisoner);assert(discovery.inventoryReads==2);prisoner.conscious=true;
|
||||
prisoner.origin.x=15.01;assert(!mode.UnlockPrison(&prisoner));prisoner.origin.x=15;assert(mode.UnlockPrison(&prisoner));assert(!mode.UnlockPrison(&prisoner));
|
||||
discovery.m_Mode=nullptr;discovery.Recover(&prisoner);assert(discovery.inventoryReads==2);
|
||||
}
|
||||
''')
|
||||
print('PASS: actual gate and pre-inventory document guards reject noncanonical/faction/life/disconnect/server mismatches; canonical reconnect and unconscious carried intel preserved')
|
||||
|
||||
# Native probe safety contracts: actual engine behavior remains for the central run.
|
||||
probe=(ROOT/'addons/core/Scripts/Game/ERR/ERR_NativeProgressionIdentityProbe.c').read_text()
|
||||
assert probe.startswith('#ifdef WORKBENCH') and probe.rstrip().endswith('#endif')
|
||||
assert probe.count('life.Actor = null;') == 2
|
||||
for segment in probe.split('life.Actor = null;')[1:]:
|
||||
assert 'life.Actor = savedActor;' in segment
|
||||
injection=segment[:segment.index('life.Actor = savedActor;')]
|
||||
for forbidden in ('Check(', 'return', 'CallLater', 'Bind(', 'Disconnect(', 'SetControlledEntity', 'SetAffiliatedFaction', 'AccountId ='):
|
||||
assert forbidden not in injection, forbidden
|
||||
assert 'super.Recover(player);' in probe.split('life.Actor = null;')[2].split('life.Actor = savedActor;')[0]
|
||||
assert 'm_Spent.Contains(folder)' in probe and 'location.Knowledge() < 2' in probe
|
||||
assert 'GetParentSlot().GetStorage().Contains(folder)' in probe
|
||||
assert probe.index('if (!candidate)') < probe.index('ERR_NativeProgressionIdentityProbe.AttemptDocument();')
|
||||
assert 'm_Spent.Contains(candidate) && m_Spent.Count() > spent && target.Knowledge() > previousKnowledge' in probe
|
||||
print('PASS: WB-only native fault injection restores both body mutations before checks/returns and requires eligible held-document negative/positive proof; runtime pending')
|
||||
Reference in New Issue
Block a user