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:
@@ -0,0 +1,13 @@
|
||||
check: /tmp/err-policy-59xtcv14/check.cpp:358: int main(): Assertion `d->Detail.find(fault==0?"item=absent;":"item=present;")!=string::npos' failed.
|
||||
PASS: actual mounted hierarchy sampling, ownership exclusion, deduplication, completeness/caps, quarter threshold and detached validation; no runtime policy or ammunition mutation
|
||||
Traceback (most recent call last):
|
||||
File "/tmp/erri-mounted-slot-diagnostic/tests/test_hq_mounted_ammo_sampler.py", line 300, in <module>
|
||||
run('#define WORKBENCH\n'+program.replace('int main(){','int main(){'+cases))
|
||||
~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/jakub/devel/escapistsrereintroduced/tests/policy_harness.py", line 14, in run
|
||||
subprocess.run([str(p/'check')],check=True)
|
||||
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/usr/lib/python3.14/subprocess.py", line 578, in run
|
||||
raise CalledProcessError(retcode, process.args,
|
||||
output=stdout, stderr=stderr)
|
||||
subprocess.CalledProcessError: Command '['/tmp/err-policy-59xtcv14/check']' died with <Signals.SIGABRT: 6>.
|
||||
@@ -0,0 +1,153 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_HQMountedAmmoSampler.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_HQMountedAmmoSampler.c
|
||||
@@ -40,6 +40,51 @@
|
||||
string Detail;
|
||||
string FirstPrefab;
|
||||
int FirstPurpose = -1;
|
||||
+ // Called before Reject, once per reason in this explicit diagnostic sample.
|
||||
+ // These labels describe sampled relationships; they never authorize a weapon.
|
||||
+ void SlotEvidence(int reason, IEntity entity, WeaponSlotComponent mount, InventoryStorageSlot binding, InventoryItemComponent item, array<IEntity> allowed)
|
||||
+ {
|
||||
+ if ((Reasons & reason) != 0) return;
|
||||
+ if (reason == 64) Detail += "mount-slot-evidence:";
|
||||
+ else Detail += "zero-muzzle-slot-evidence:";
|
||||
+ if (item) Detail += "item=present;";
|
||||
+ else Detail += "item=absent;";
|
||||
+ InventoryStorageSlot parent = null;
|
||||
+ if (item) parent = item.GetParentSlot();
|
||||
+ if (!parent) Detail += "parent=null;";
|
||||
+ else if (parent == binding) Detail += "parent=same-binding;";
|
||||
+ else Detail += "parent=different-binding;";
|
||||
+ if (!binding) Detail += "binding=null;";
|
||||
+ else
|
||||
+ {
|
||||
+ if (binding.GetAttachedEntity() == entity) Detail += "binding-attached=exact;";
|
||||
+ else Detail += "binding-attached=other-or-null;";
|
||||
+ if (binding.GetParentContainer() == mount) Detail += "binding-container=exact-mount;";
|
||||
+ else Detail += "binding-container=other-or-null;";
|
||||
+ }
|
||||
+ IEntity owner = null;
|
||||
+ if (mount) owner = mount.GetOwner();
|
||||
+ if (owner && allowed.Contains(owner)) Detail += "mount-owner=allowed;";
|
||||
+ else Detail += "mount-owner=absent-or-foreign;";
|
||||
+ if (owner && owner.GetPrefabData()) Detail += "mount-prefab=" + owner.GetPrefabData().GetPrefabName() + ";";
|
||||
+ if (!parent) return;
|
||||
+ if (parent.GetAttachedEntity() == entity) Detail += "parent-attached=exact;";
|
||||
+ else Detail += "parent-attached=other-or-null;";
|
||||
+ WeaponSlotComponent parentMount = WeaponSlotComponent.Cast(parent.GetParentContainer());
|
||||
+ if (parent.GetParentContainer() == mount && mount) Detail += "parent-container=exact-mount;";
|
||||
+ else if (parentMount) Detail += "parent-container=other-mount;";
|
||||
+ else if (!parent.GetParentContainer()) Detail += "parent-container=null;";
|
||||
+ else Detail += "parent-container=non-mount;";
|
||||
+ if (!parentMount) return;
|
||||
+ IEntity parentOwner = parentMount.GetOwner();
|
||||
+ if (parentOwner && allowed.Contains(parentOwner)) Detail += "parent-mount-owner=allowed;";
|
||||
+ else Detail += "parent-mount-owner=absent-or-foreign;";
|
||||
+ if (parentOwner && parentOwner.GetPrefabData()) Detail += "parent-mount-prefab=" + parentOwner.GetPrefabData().GetPrefabName() + ";";
|
||||
+ if (parentMount.GetSlotInfo() == parent) Detail += "parent-mount-slot=exact;";
|
||||
+ else Detail += "parent-mount-slot=other-or-null;";
|
||||
+ if (parentMount.GetWeaponEntity() == entity) Detail += "parent-mount-weapon=exact;";
|
||||
+ else Detail += "parent-mount-weapon=other-or-null;";
|
||||
+ }
|
||||
void Reject(int reason, string detail, IEntity entity, int purpose = -1)
|
||||
{
|
||||
if ((Reasons & reason) == 0) Detail += detail + ";";
|
||||
@@ -104,7 +149,11 @@
|
||||
if (!mountedItem || mountedItem.GetParentSlot() != binding)
|
||||
{
|
||||
#ifdef WORKBENCH
|
||||
- if (s_Diagnostic) s_Diagnostic.Reject(64, "mount-item-slot-mismatch", mountedEntity);
|
||||
+ if (s_Diagnostic)
|
||||
+ {
|
||||
+ s_Diagnostic.SlotEvidence(64, mountedEntity, mount, binding, mountedItem, allowed);
|
||||
+ s_Diagnostic.Reject(64, "mount-item-slot-mismatch", mountedEntity);
|
||||
+ }
|
||||
#endif
|
||||
result.Complete = false; return;
|
||||
}
|
||||
@@ -272,7 +321,23 @@
|
||||
if (muzzles.IsEmpty())
|
||||
{
|
||||
if (NonFiringPlaceholder(weapon, allowed)) result.Weapons--;
|
||||
- else result.Complete = false;
|
||||
+ else
|
||||
+ {
|
||||
+#ifdef WORKBENCH
|
||||
+ if (s_Diagnostic)
|
||||
+ {
|
||||
+ IEntity owner = weapon.GetOwner();
|
||||
+ InventoryItemComponent item = InventoryItemComponent.Cast(owner.FindComponent(InventoryItemComponent));
|
||||
+ WeaponSlotComponent mount = null;
|
||||
+ InventoryStorageSlot binding = null;
|
||||
+ if (item && item.GetParentSlot()) mount = WeaponSlotComponent.Cast(item.GetParentSlot().GetParentContainer());
|
||||
+ if (mount) binding = mount.GetSlotInfo();
|
||||
+ s_Diagnostic.SlotEvidence(4096, owner, mount, binding, item, allowed);
|
||||
+ s_Diagnostic.Reject(4096, "zero-muzzle-not-proven-placeholder", owner);
|
||||
+ }
|
||||
+#endif
|
||||
+ result.Complete = false;
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
if (muzzles.Count() > 8) { result.Complete = false; continue; }
|
||||
--- a/tests/test_hq_mounted_ammo_sampler.py
|
||||
+++ b/tests/test_hq_mounted_ammo_sampler.py
|
||||
@@ -15,6 +15,8 @@
|
||||
code=code.replace('InventoryItemComponent.Cast(entity.FindComponent(InventoryItemComponent))','entity->item')
|
||||
code=code.replace('InventoryItemComponent.Cast(owner.FindComponent(InventoryItemComponent))','owner->item').replace('ResourceName resource', 'string resource')
|
||||
code=code.replace('WeaponSlotComponent.Cast(slot.GetParentContainer())','slot->mount').replace('BaseMuzzleComponent.Cast(slot.GetParentContainer())','slot->muzzle')
|
||||
+code=code.replace('WeaponSlotComponent.Cast(parent.GetParentContainer())','parent->mount').replace('WeaponSlotComponent.Cast(item.GetParentSlot().GetParentContainer())','item->GetParentSlot()->mount')
|
||||
+code=code.replace('parent.GetParentContainer()', 'parent->Container()')
|
||||
code=code.replace('EStoragePurpose.','EStoragePurpose::').replace('GetParentSlot().','GetParentSlot()->')
|
||||
code=code.replace('ChimeraCharacter.Cast(entity) != nullptr','entity->character').replace('ChimeraCharacter.Cast(entity) != null','entity->character')
|
||||
code=code.replace('ChimeraCharacter.Cast(root)','root->character').replace('ChimeraCharacter.Cast(entity)','entity->character')
|
||||
@@ -22,10 +24,11 @@
|
||||
code=re.sub(r'\bERR_HQMountedAmmoDiagnostic (?=\w)', 'ERR_HQMountedAmmoDiagnostic* ',code)
|
||||
code=code.replace('s_Diagnostic.', 's_Diagnostic->').replace('GetPrefabData().', 'GetPrefabData()->')
|
||||
code=re.sub(r'\bERR_HQMountedAmmoSnapshot (?=\w)','ERR_HQMountedAmmoSnapshot* ',code)
|
||||
-code=code.replace('array<','Array<').replace('foreach (','for (').replace('null','nullptr')
|
||||
+code=code.replace('array<','Array<').replace('foreach (','for (')
|
||||
+code=re.sub(r'"[^"]*"|\bnull\b',lambda m:m.group() if m.group().startswith(chr(34)) else 'nullptr',code)
|
||||
code=code.replace('Array<IEntity> allowed, Array<BaseWeaponComponent> weapons,','Array<IEntity>& allowed, Array<BaseWeaponComponent>& weapons,')
|
||||
code=code.replace('Array<IEntity> allowed, Array<BaseWeaponComponent> weapons)', 'Array<IEntity>& allowed, Array<BaseWeaponComponent>& weapons)')
|
||||
-for name in ('copy','result','weapon','root','entity','child','part','manager','mounted','muzzle','magazine','item','storage','mount','mountedEntity','mountedItem','owner'):
|
||||
+for name in ('copy','result','weapon','root','entity','child','part','manager','mounted','muzzle','magazine','item','storage','mount','mountedEntity','mountedItem','owner','parent','binding','parentMount','parentOwner'):
|
||||
code=re.sub(r'\b'+name+r'\.',name+'->',code)
|
||||
code=re.sub(r'\b(bool|int) (\w+);',r'\1 \2=0;',code).replace('\n}\n','\n};\n')
|
||||
program=(r'''
|
||||
@@ -41,7 +44,7 @@
|
||||
struct Entity;struct Weapon;struct Muzzle;struct Magazine;struct Manager;struct Mount;
|
||||
struct EStoragePurpose{static const int PURPOSE_UNSET=0,PURPOSE_DEPOSIT=1,PURPOSE_WEAPON_PROXY=2,PURPOSE_ATTACHMENT_PROXY=4,PURPOSE_ANY=127;};
|
||||
struct Storage{int purpose=EStoragePurpose::PURPOSE_DEPOSIT;int GetPurpose(){return purpose;}};
|
||||
-struct Slot{Mount* mount=nullptr;Muzzle* muzzle=nullptr;Storage* storage=nullptr;Storage* GetStorage(){return storage;}};
|
||||
+struct Slot{Mount* mount=nullptr;Muzzle* muzzle=nullptr;Storage* storage=nullptr;Entity* attached=nullptr;Entity* GetAttachedEntity(){return attached;}void* Container(){return mount?static_cast<void*>(mount):muzzle?static_cast<void*>(muzzle):static_cast<void*>(storage);}Storage* GetStorage(){return storage;}};
|
||||
struct Item{Slot* slot=nullptr;Slot* GetParentSlot(){return slot;}};
|
||||
using InventoryStorageSlot=Slot*;using WeaponSlotComponent=Mount*;
|
||||
using InventoryItemComponent=Item*;using BaseInventoryStorageComponent=Storage*;
|
||||
@@ -259,6 +262,26 @@
|
||||
# WORKBENCH records are opt-in. Re-run every original geometry/count assertion
|
||||
# in that build too, plus exact failure witnesses from the same traversal.
|
||||
cases=r'''
|
||||
+ // Exact reason64 distinguishes absent item, null slot and differing slot,
|
||||
+ // while actual Inspect remains incomplete and retains the same ammunition.
|
||||
+ for(int fault=0;fault<3;fault++){
|
||||
+ Rig r;Mount mount;Item item;Slot binding,other;Storage storage;storage.purpose=EStoragePurpose::PURPOSE_ATTACHMENT_PROXY;other.storage=&storage;
|
||||
+ mount.owner=&r.root;mount.weapon=&r.gun;mount.slot=&binding;binding.mount=&mount;binding.attached=&r.gun;
|
||||
+ r.manager.weapons={&mount};r.gun.item=fault==0?nullptr:&item;
|
||||
+ if(fault==2)item.slot=&other;
|
||||
+ other.mount=&mount;other.attached=&r.gun;
|
||||
+ ERR_HQMountedAmmoSampler::BeginDiagnostic();auto snap=r.Inspect();auto*d=ERR_HQMountedAmmoSampler::EndDiagnostic();
|
||||
+ assert(!snap->Complete&&snap->Weapons==1&&snap->Rounds==25&&(d->Reasons&64));
|
||||
+ assert(d->Detail.find(fault==0?"item=absent;":"item=present;")!=string::npos);
|
||||
+ assert(d->Detail.find(fault==2?"parent=different-binding;":"parent=null;")!=string::npos);
|
||||
+ assert(d->Detail.find("binding-attached=exact;")!=string::npos&&d->Detail.find("binding-container=exact-mount;")!=string::npos);
|
||||
+ assert(d->Detail.find("mount-owner=allowed;")!=string::npos&&d->Detail.find("mount-prefab=fixture;")!=string::npos);
|
||||
+ if(fault==2)assert(d->Detail.find("parent-mount-slot=other-or-null;")!=string::npos);
|
||||
+ }
|
||||
+ {Rig r;r.weapon.muzzles={};ERR_HQMountedAmmoSampler::BeginDiagnostic();auto snap=r.Inspect();auto*d=ERR_HQMountedAmmoSampler::EndDiagnostic();
|
||||
+ assert(!snap->Complete&&snap->Weapons==1&&snap->Rounds==0&&(d->Reasons&4096));
|
||||
+ assert(d->Detail.find("zero-muzzle-not-proven-placeholder;")!=string::npos&&d->Detail.find("zero-muzzle-slot-evidence:item=absent;parent=null;")!=string::npos);}
|
||||
+''' + r'''
|
||||
{Rig r;ERR_HQMountedAmmoSampler::BeginDiagnostic();auto snap=r.Inspect();auto*d=ERR_HQMountedAmmoSampler::EndDiagnostic();assert(snap->Complete&&d->Reasons==0&&d->Nodes==4&&d->Allowed==3&&d->Managers==1);assert(!ERR_HQMountedAmmoSampler::EndDiagnostic());}
|
||||
{Entity root;root.child=&root;ERR_HQMountedAmmoSampler::BeginDiagnostic();auto snap=ERR_HQMountedAmmoSampler::Inspect(&root);auto*d=ERR_HQMountedAmmoSampler::EndDiagnostic();assert(!snap->Complete&&d->Reasons==4&&d->Nodes==1&&d->Allowed==1&&root.reads==1);}
|
||||
{Entity root;std::vector<Entity> children(128);root.child=&children[0];for(int i=0;i<127;i++)children[i].sibling=&children[i+1];ERR_HQMountedAmmoSampler::BeginDiagnostic();auto snap=ERR_HQMountedAmmoSampler::Inspect(&root);auto*d=ERR_HQMountedAmmoSampler::EndDiagnostic();assert(!snap->Complete&&d->Reasons==1024&&d->Nodes==129&&d->Allowed==128&&d->Structural==129&&d->Cargo==0&&children[127].reads==0);}
|
||||
@@ -0,0 +1,2 @@
|
||||
PASS: actual mounted hierarchy sampling, ownership exclusion, deduplication, completeness/caps, quarter threshold and detached validation; no runtime policy or ammunition mutation
|
||||
PASS: WORKBENCH opt-in diagnostics distinguish cycles/cap/storage/manager/mount failures without repeated native traversal
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"complete": true,
|
||||
"approved": true,
|
||||
"blockers": [],
|
||||
"manifest_sha256": "e2e66871228b47738075e6d5faf1657c3c1c10fdbed2850de3c2a8d13b6883cf",
|
||||
"patch_sha256": "442d71268cbdb2d3bb50fbe73bcda0203ab74e8fdd9c4469f840b2bb4413a378",
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQMountedAmmoSampler.c": {
|
||||
"baseline_sha256": "2f0db77ba999586e4290e440d112f1002da17ab5fd20bb4f5b7ff6df99f58a81",
|
||||
"proposal_sha256": "e8e36110e126de921d7635b8c319f923a48d84f700fa78e018bb40136d4819d1",
|
||||
"index_sha256": "88ea0fc0e13d7e3c22c7ce8b652816d1d137e4e6e37a72f48f0bdf515b936ae7"
|
||||
},
|
||||
"tests/test_hq_mounted_ammo_sampler.py": {
|
||||
"baseline_sha256": "a4d098adcd3d1f1156d00cf0753268f286cd63640bdae5aed81828f74a8b4633",
|
||||
"proposal_sha256": "f4adb94e5e688ff3843ef240c7a4232308979f232a53fe7a6a1d94d02591b960",
|
||||
"index_sha256": "b1c630909e5227d0f7bd0d69d7927403fcb0f33e7297d5fa52f96001720f8442"
|
||||
}
|
||||
},
|
||||
"scope": "Read-only source/test/log review, no compiler or native run. WORKBENCH class and s_Diagnostic gate only. SlotEvidence records once per reason, no additional loops, no state mutation or changed acceptance/count/caps. Original return and Complete=false preserved.",
|
||||
"api": "InventoryStorageSlot inherits GetAttachedEntity; GetParentContainer returns component; WeaponSlot GetOwner/GetSlotInfo/GetWeaponEntity and InventoryItem.GetParentSlot signatures match installed SDK. Null item/slot/mount guarded. allowed array is the established nonnull local collection.",
|
||||
"tests": "Actual whole-sampler tests add absent item/null parent/different parent distinction and zero-muzzle rejected-placeholder witness while preserving existing count assertions. Retained default and WORKBENCH green logs, baseline runtime red, and adapter failure logs hash-verified.",
|
||||
"limits": [
|
||||
"No native compile or observed reason64 binding state yet.",
|
||||
"First occurrence per reason cannot attribute every failing entity; labels are sampled evidence, not authorization.",
|
||||
"Zero-muzzle branch cannot rediscover missing reverse mount; records missing relation honestly."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Prefabs/Weapons/Core/Armament_Empty.et": {
|
||||
"archive": "/home/jakub/.local/share/Steam/steamapps/compatdata/1874880/pfx/drive_c/users/steamuser/Documents/My Games/ArmaReforger/addons/WCS_Armaments_629B2BA37EFFD577/data.pak",
|
||||
"sha256": "73b35bd524e30fe09f147f0dc5f197d49c341b46c660ec1ce402f143dc943731",
|
||||
"same_as_prior_extracted_source": true,
|
||||
"bytes": 1068
|
||||
},
|
||||
"Prefabs/Vehicles/Tracked/BMP1/VehParts/Turret/BMP1_Turret_Base.et": {
|
||||
"archive": "/home/jakub/.local/share/Steam/steamapps/compatdata/1874880/pfx/drive_c/users/steamuser/Documents/My Games/ArmaReforger/addons/BMP-1IFV_5E524E4FEECCA92B/data.pak",
|
||||
"sha256": "2fc39d7c2fc4bebe027efa5607ea71dd7dd0021daffb43f65332bf2698a52a4b",
|
||||
"same_as_prior_extracted_source": true,
|
||||
"bytes": 16134
|
||||
},
|
||||
"guid_identity": {
|
||||
"database": "/home/jakub/.local/share/Steam/steamapps/compatdata/1874880/pfx/drive_c/users/steamuser/Documents/My Games/ArmaReforger/addons/WCS_Armaments_629B2BA37EFFD577/resourceDatabase.rdb",
|
||||
"database_sha256": "7f38b7ed578b0b47864648a7b70288fe49dae4cc2556d5754377a1c28b2b6532",
|
||||
"exact_record_count": 1,
|
||||
"offset": 80834,
|
||||
"guid": "52120E4BA120661B"
|
||||
},
|
||||
"sdk_hashes": {
|
||||
"/tmp/erri-vanilla-stock/scripts/Game/generated/Weapon/WeaponSlotComponent.c": "f59ed140912e7ece862b1730af57cb8dcf2c65dbf40a27bba34eb83fa0d3bc58",
|
||||
"/tmp/erri-vanilla-stock/scripts/Game/generated/Components/InventorySystem/InventoryItemComponent.c": "3d812681816be5d34a578f33e208d7802b22a899be008073bf437b7a8ecb2251",
|
||||
"/tmp/erri-vanilla-stock/scripts/Game/generated/InventorySystem/InventoryStorageSlot.c": "45e584eb11f53e1b7374f375d57cdc58c8e757a7922c06cf5db9328ca3294cb5",
|
||||
"/tmp/erri-vanilla-stock/scripts/Game/generated/EntitySlotInfo.c": "90e41e28a14bc677d829f38faff01ad9f0568d3ec4850c496568c379f8301e50"
|
||||
},
|
||||
"findings": [
|
||||
"Exact standalone GenericEntity declares InventoryItemComponent with Enabled 0, WeaponComponent and no muzzle component; no inherited base prefab.",
|
||||
"Exact BMP turret slot index3 declares AttachType InventoryStorageSlot Gun and this WeaponTemplate.",
|
||||
"SDK WeaponSlotComponent exposes GetSlotInfo and GetWeaponEntity; InventoryStorageSlot exposes GetParentContainer and inherits EntitySlotInfo.GetAttachedEntity. SDK EntitySlotInfo.GetSlotInfo(entity) recognizes structural attachment through parent WeaponSlotComponent and GetAttachedEntity equality without requiring InventoryItemComponent.GetParentSlot.",
|
||||
"InventoryItemComponent.GetParentSlot explicitly returns null if none. Native construction and consequences of Enabled 0 are not specified in available script; a reciprocal inventory-item slot is not promised for this disabled component.",
|
||||
"Current reason64 conflates absent InventoryItemComponent with nonmatching/null parent slot. It follows successful allowed mounted entity, mount slot, and parent-container checks, but does not log which item-state branch failed."
|
||||
],
|
||||
"policy_candidate": "Only if native diagnostics establish the exact empty control structural binding: consider omission of an exact allowlisted zero-muzzle control via bounded structural slot proof (same allowed hierarchy, mount.GetWeaponEntity()==entity, mount.GetSlotInfo()==slot, slot.GetParentContainer()==mount, slot.GetAttachedEntity()==entity, exact physical weapon owner). Never relax inventory custody for real weapons/cargo or accept unknown/armed resources. Handle conflicting nonnull inventory binding fail-closed. This is a future candidate, not an approved implemented fix.",
|
||||
"next_observation": "Extend existing opt-in reason64 diagnostic to separate component missing / null parent slot / different parent slot, and record slot.GetAttachedEntity equality plus zero-muzzle count for exact prefab. No extra gameplay state mutation or repeated native run requested by this review.",
|
||||
"limits": [
|
||||
"Read-only source and installed archive/RDB examination only; no native or compiler execution.",
|
||||
"Enabled 0 supports a plausible explanation but is not runtime proof that null parent slot is expected; no source-only fix recommended."
|
||||
],
|
||||
"required_regressions_if_policy_adopted": [
|
||||
"Actual whole sampler: exact known zero-muzzle control with observed missing reverse inventory binding and full structural slot proof is omitted; real guns and ammunition remain counted exactly once.",
|
||||
"Refuse wrong GUID/path, nonzero muzzle list being omitted, unknown zero-muzzle resource, foreign hierarchy, missing/mismatched mount slot or parent container, different attached entity, and conflicting nonnull inventory parent slot.",
|
||||
"Manager and direct hierarchy duplicate discovery of the same control remains deduplicated without poisoning completeness; known controls alone produce zero armed weapons and cannot satisfy the armed BMP fixture.",
|
||||
"Retain existing real-weapon reciprocal custody, cargo/crew exclusion, node/weapon/muzzle bounds and fail-closed unknown behavior."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"files": {
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQMountedAmmoSampler.c": {
|
||||
"baseline_sha256": "2f0db77ba999586e4290e440d112f1002da17ab5fd20bb4f5b7ff6df99f58a81",
|
||||
"proposal_sha256": "e8e36110e126de921d7635b8c319f923a48d84f700fa78e018bb40136d4819d1",
|
||||
"index_sha256": "88ea0fc0e13d7e3c22c7ce8b652816d1d137e4e6e37a72f48f0bdf515b936ae7"
|
||||
},
|
||||
"tests/test_hq_mounted_ammo_sampler.py": {
|
||||
"baseline_sha256": "a4d098adcd3d1f1156d00cf0753268f286cd63640bdae5aed81828f74a8b4633",
|
||||
"proposal_sha256": "f4adb94e5e688ff3843ef240c7a4232308979f232a53fe7a6a1d94d02591b960",
|
||||
"index_sha256": "b1c630909e5227d0f7bd0d69d7927403fcb0f33e7297d5fa52f96001720f8442"
|
||||
}
|
||||
},
|
||||
"patch_sha256": "442d71268cbdb2d3bb50fbe73bcda0203ab74e8fdd9c4469f840b2bb4413a378",
|
||||
"production_non_workbench_token_equivalent": true,
|
||||
"normalization": "Remove WORKBENCH sections, comments, whitespace and redundant braces around the single existing else assignment. All remaining tokens exactly match.",
|
||||
"tests": {
|
||||
"green_exit": 0,
|
||||
"baseline_exit": 1,
|
||||
"logs": {
|
||||
"fixture-failure.log": "53be342eb93454c82e26847fa799077ecce5e2daa4869ee89ec9a27d64b3af50",
|
||||
"baseline-red.log": "5719ad13bf68d29feb26bc053851949d086c1e2c22d48a879af1edda2e422c83",
|
||||
"adapter-string-failure.log": "715655dfd277f7414804c7b1ee06863da9660d1c3fc15aa06a94af01e56404c5",
|
||||
"adapter-failure.log": "d5b8d71945dfac7e85487ac9a5847976fbd986350112226b5097515c62d93dbf",
|
||||
"green.log": "427e7758df3b8746673da188ab74c12b409011eb4f4024b98fb709b7b5aea0a4"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user