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
@@ -0,0 +1,141 @@
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c
@@ -12,6 +12,7 @@
ref ERR_SiteDefinition Definition;
ERR_LocationComponent Location;
IEntity Container;
+ ref array<IEntity> DepotMagazines = {}; // Exact authored startup identities; never refreshed from live inventory.
SCR_AIGroup Group;
ref ERR_SiteRuntime Responders;
string ExpectedGuardFaction;
@@ -56,6 +57,30 @@
{
if (index < 0 || index >= m_Sites.Count()) return null;
return m_Sites[index];
+ }
+ // Optional ground loading consumes only retained original camp magazines.
+ int DepotMagazineCount(ERR_SiteRuntime site)
+ {
+ if (!Replication.IsServer() || m_Stopped || m_State != ERR_PrepareResult.READY || !site || !m_Sites.Contains(site)) return 0;
+ if (!site.Definition || site.Definition.Kind != ERR_LocationKind.OUTPOST || site.Definition.RevealOnEscape) return 0;
+ if (!site.Container || !Owns(site.Container) || !site.Responders || !site.Responders.Group) return 0;
+ if (site.DepotMagazines.Count() > 96) return 0;
+ return site.DepotMagazines.Count();
+ }
+ void DepotStock(ERR_SiteRuntime site, out array<IEntity> items)
+ {
+ items = {};
+ int count = DepotMagazineCount(site);
+ for (int i = 0; i < count; i++) items.Insert(site.DepotMagazines[i]);
+ }
+ IEntity DepotMagazine(ERR_SiteRuntime site, int index)
+ {
+ if (index < 0 || index >= DepotMagazineCount(site)) return null;
+ return site.DepotMagazines[index];
+ }
+ bool DepotOriginal(ERR_SiteRuntime site, IEntity item)
+ {
+ return item && DepotMagazineCount(site) > 0 && site.DepotMagazines.Contains(item);
}
bool Owns(IEntity entity) { return entity && m_Entities.Contains(entity); }
// Snapshot only nearby mission-owned objects. Distant sites must not block
@@ -389,6 +414,8 @@
document.SetTarget(stock.TargetId);
}
ERR_StockPlacement placement = new ERR_StockPlacement();
+ if (spec.Kind == ERR_LocationKind.OUTPOST && !spec.RevealOnEscape && stock.TargetId.IsEmpty()
+ && item.FindComponent(BaseMagazineComponent) && site.DepotMagazines.Count() < 96) site.DepotMagazines.Insert(item);
placement.Item = item;
placement.Inventory = inventory;
m_Placements.Insert(placement);
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
@@ -102,6 +102,36 @@
int Delivered() { return m_Delivered; }
int MinesDelivered() { return m_MinesDelivered; }
int StockCount() { return m_Stock.Count(); }
+ // Admission uses the existing array object so an already-created mounted
+ // coordinator observes this exact finite addition without a replacement ledger.
+ protected int m_DepotImports;
+ bool DepotCurrent()
+ {
+ return Current() && m_State == 1 && !m_Move && !m_MineMove && !Unresolved()
+ && (!m_Mounted || !m_Mounted.Busy()) && TruckValid(true);
+ }
+ bool DepotAvailable() { return DepotCurrent() && m_Stock.Count() < 96 && m_Spent.Count() < 96; }
+ bool DepotNeeded()
+ {
+ if (!DepotAvailable()) return false;
+ int committed;
+ foreach (IEntity item : m_Spent)
+ if (item && m_Stock.Contains(item)) committed++;
+ return committed > m_DepotImports;
+ }
+ ERR_ConvoyVehicle DepotTruck()
+ {
+ if (!DepotCurrent()) return null;
+ return m_Truck;
+ }
+ bool AdmitDepot(ERR_GroundDepotLoading job, IEntity item)
+ {
+ if (!job || !DepotAvailable() || !item || m_Stock.Contains(item) || m_Spent.Contains(item)) return false;
+ if (!job.DeliveredTo(this, item) || !Contains(m_Truck.Entity, item)) return false;
+ m_Stock.Insert(item); m_DepotImports++; Audit("one exact finite camp magazine admitted after proved physical courier delivery");
+ return true;
+ }
+
protected void Audit(string reason)
{
if (m_MineTrip) reason = "mine top-up: " + reason;
--- a/tools/check.py
+++ b/tools/check.py
@@ -15,6 +15,10 @@
subprocess.run([sys.executable,str(ROOT/'tests/test_prison_ai.py')],check=True)
subprocess.run([sys.executable,str(ROOT/'tests/test_native_player_death_fixture.py')],check=True)
subprocess.run([sys.executable,str(ROOT/'tests/test_hq_planner_budget.py')],check=True)
+ subprocess.run([sys.executable,str(ROOT/'tests/test_ground_depot_loading.py')],check=True)
+ subprocess.run([sys.executable,str(ROOT/'tests/test_ground_depot_lifecycle.py')],check=True)
+ subprocess.run([sys.executable,str(ROOT/'tests/test_ground_depot_transfer.py')],check=True)
+ subprocess.run([sys.executable,str(ROOT/'tests/test_ground_depot_provenance.py')],check=True)
ids={};graph={};resources={};paths={};owners={}
for p in sorted((ROOT/'addons').glob('*/addon.gproj')):
text=p.read_text();g=re.search(r'GUID "([A-F0-9]{16})"',text)[1]
--- a/docs/current-status.md
+++ b/docs/current-status.md
@@ -1,4 +1,8 @@
# Current development status
+
+**2 October 2026 — finite camp-to-truck ammunition loading:** HQ can assign one available original camp responder to carry one exact original cache magazine to a nearby original ammunition truck after delivered radio orders. Recorded finite magazine expenditure gates admission; separate pickup/delivery proof, unchanged rounds, original identities and bounded reservations prevent refill or replay. Existing tactical/logistics work retains priority. [Behavior and limits](ground-depot-loading.md).
+
+The full **277-program regression suite passed** before native compilation. The first native run exposed getter formatting and a helper-name conflict; its [failed evidence](evidence/native-2026-10-02-ground-depot-compile/report.json) is retained. After those behavior-preserving corrections, all four relevant programs passed again. The [corrected hidden/muted normal route](evidence/native-2026-10-02-ground-depot-integration/report.json) completes **63 assertions and one round**, with zero script/runtime failures and thirteen retained installed-resource errors. Cleanup and unchanged source/external inputs are confirmed. This qualifies compilation and normal-loop integration only. [Independent review, mutation evidence and preservation](evidence/ground-depot-loading-2026-10-02/review.json). The existing playtest package predates this feature. Original missions, inherited changes and that package remain preserved. Physical loading, human play, real multiplayer, comparative FPS and clean release remain unfinished.
**2 October 2026 — HQ planning removes repeated force counts:** the final pursuit selection pass now counts global commitments once after cleanup/retasking/investigation and increments only for a newly queued order. Separate hunting/global limits, orders and reservations are preserved. A controlled 64-belief/128-unit no-dispatch regression reduces the repeated count scans from over 10,000 unit visits to 128; this measures that subpass only, **not FPS**.
--- a/docs/infantry-resupply.md
+++ b/docs/infantry-resupply.md
@@ -78,3 +78,7 @@
Each trip still transfers at most one exact identity from the original finite convoy mine snapshot through the shared spent ledger. Existing report freshness, priority, cooldown, callback proof and uncertain-operation quarantine are unchanged. This replenishes carried stock only: it does not reset `EngineerMineAttempted`, authorize repeated mine laying, spawn replacement stock or refund submitted items.
Six focused actual-method programs passed independently: startup designation and settings changes, original equipment membership, known-zero versus unknown inventory, pinned modes through retries, delivered-report admission, and existing callback/quarantine behavior. The old planning method compiled and failed the new designated-zero admission assertion. All **272 registered regression programs pass across a resumed run**: the initial `native_package` stop exhausted the per-user `/tmp` quota; verified relocation of completed task snapshots recovered space, and that program plus the remaining suite passed with the existing canonical `/tmp` guards. The infrastructure failure is preserved. The [hidden/muted frozen-source normal route](evidence/native-2026-10-02-zero-mine-integration/report.json) compiles this increment and passes **63 assertions and one round**, with zero script/runtime failures and thirteen retained installed-resource errors. Cleanup and unchanged inputs are confirmed. This proves compilation/base-loop integration, not actual zero-stock transfer. [Review and preservation](evidence/zero-mine-resupply-2026-10-02/review.json). Actual walking mine delivery, repeated placement and multiplayer remain unqualified; earlier native evidence retains its original source scope.
+
+### Authored camp imports (2 October 2026)
+
+The historical one-time truck snapshot above now has one narrow extension: [proved finite camp deliveries](ground-depot-loading.md) can append an original startup camp magazine after two separately acknowledged native moves. Existing stock/spent entries and the lifetime 96-identity limit remain intact; arbitrary later deposits and returned empty magazines remain excluded. Admission requires conservative known finite-magazine commitments beyond prior imports, not merely unused truck capacity. Autonomous physical loading remains unqualified.
--- a/docs/ai-feature-migration.json
+++ b/docs/ai-feature-migration.json
@@ -2562,6 +2562,15 @@
"evidence": "Six focused actual-method programs independently pass, with compiled old-planning assertion failure. All272 registered programs pass across a resumed canonical-/tmp run after verified quota recovery; initial infrastructure failure preserved. Current frozen-source normal route63 assertions/one round/zero script failures;13 installed-resource errors retained, cleanup confirmed. Compilation/base-loop integration only; physical zero-stock transfer remains unqualified.",
"remaining": "Physical walking mine transfer for this increment, per-actor full need manifests, repeated placement and true multiplayer qualification.",
"detail": "docs/infantry-resupply.md#designated-engineer-zero-stock-replacement-2-october-2026"
+ },
+ {
+ "id": "resupply",
+ "updated_on": "2026-10-02",
+ "status": "partial",
+ "implementation": "Bounded opportunistic camp-to-original-truck loading through one existing mobile responder, delivered radio hold/new stopped report/porter order, two isolated native callback+custody proofs, retained exact original identities and finite shared allowance. Admission requires prior committed magazine expenditure beyond imports. No generated stock, actors or native retries.",
+ "evidence": "277 programs passed initial integration, four relevant programs rerun after behavior-preserving native compile fixes. Failed compile retained; corrected frozen normal route63 assertions/one round/zero script failures/13 retained resource errors. Cleanup and unchanged inputs confirmed.",
+ "remaining": "Native autonomous depot walking/access/two-leg delivery, multiplayer, full logistics parity and release qualification.",
+ "detail": "docs/ground-depot-loading.md"
}
]
}
@@ -0,0 +1,13 @@
{
"scope": "Only multiline GroundSupplyCount/GroundSupplyAt/DepotTruck and Managed renamed StorageManaged",
"tests": {
"test_ground_depot_loading.py": "PASS against isolated overlay with source overrides",
"test_ground_depot_lifecycle.py": "PASS against isolated overlay with source overrides",
"test_ground_depot_provenance.py": "PASS against isolated overlay with source overrides",
"test_ground_depot_transfer.py": "PASS against isolated overlay with source overrides"
},
"test_changes": "none required; full leaf translated dynamically",
"native": "not run",
"target": "unchanged",
"apply_check": "PASS"
}
@@ -0,0 +1,73 @@
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c
@@ -2,8 +2,16 @@
modded class ERR_HQ
{
protected ref ERR_GroundDepotLoading m_GroundDepot;
- int GroundSupplyCount() { if (!m_Resupply) return 0; return m_Resupply.Count(); }
- ERR_InfantryResupply GroundSupplyAt(int index) { if (!m_Resupply) return null; return m_Resupply.At(index); }
+ int GroundSupplyCount()
+ {
+ if (!m_Resupply) return 0;
+ return m_Resupply.Count();
+ }
+ ERR_InfantryResupply GroundSupplyAt(int index)
+ {
+ if (!m_Resupply) return null;
+ return m_Resupply.At(index);
+ }
ERR_HQUnit GroundUnit(SCR_AIGroup group)
{
if (!group) return null;
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
@@ -119,7 +119,11 @@
if (item && m_Stock.Contains(item)) committed++;
return committed > m_DepotImports;
}
- ERR_ConvoyVehicle DepotTruck() { if (!DepotCurrent()) return null; return m_Truck; }
+ ERR_ConvoyVehicle DepotTruck()
+ {
+ if (!DepotCurrent()) return null;
+ return m_Truck;
+ }
bool AdmitDepot(ERR_GroundDepotLoading job, IEntity item)
{
if (!job || !DepotAvailable() || !item || m_Stock.Contains(item) || m_Spent.Contains(item)) return false;
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c
@@ -60,7 +60,7 @@
if (!success) m_Ack = -1;
else if (m_Ack == 0) m_Ack = 1;
}
- protected bool Managed(InventoryStorageManagerComponent inventory, BaseInventoryStorageComponent storage, IEntity owner)
+ protected bool StorageManaged(InventoryStorageManagerComponent inventory, BaseInventoryStorageComponent storage, IEntity owner)
{
if (!inventory || !storage || !owner || inventory.GetOwner() != owner) return false;
if (!ERR_InfantryAmmoTransfer.StoredUnder(storage.GetOwner(), owner)) return false;
@@ -83,14 +83,14 @@
}
protected bool OriginalProof()
{
- return m_FromSlot && m_FromSlot.GetStorage() == m_FromStorage && Managed(m_Source, m_FromStorage, m_From)
+ return m_FromSlot && m_FromSlot.GetStorage() == m_FromStorage && StorageManaged(m_Source, m_FromStorage, m_From)
&& Slot(m_FromSlot) && m_Destination && m_Destination.GetOwner() == m_To
&& Contains(m_Source) == 1 && Contains(m_Destination) == 0;
}
bool PhysicalProof()
{
if (!m_Item || !m_Source || !m_From || m_Source.GetOwner() != m_From) return false;
- if (!Managed(m_Destination, m_ToStorage, m_To) || Contains(m_Source) != 0 || Contains(m_Destination) != 1) return false;
+ if (!StorageManaged(m_Destination, m_ToStorage, m_To) || Contains(m_Source) != 0 || Contains(m_Destination) != 1) return false;
InventoryItemComponent item = InventoryItemComponent.Cast(m_Item.FindComponent(InventoryItemComponent));
return item && item.GetParentSlot() && item.GetParentSlot().GetStorage() == m_ToStorage && Slot(item.GetParentSlot());
}
@@ -118,7 +118,7 @@
{
if (!m_Reservation || !OriginalProof()) { Stop(); return m_State; }
m_ToStorage = m_Destination.FindStorageForItem(m_Item, EStoragePurpose.PURPOSE_DEPOSIT);
- if (!Managed(m_Destination, m_ToStorage, m_To) || !m_Source.CanMoveItemToStorage(m_Item, m_ToStorage, -1)) { Stop(); return m_State; }
+ if (!StorageManaged(m_Destination, m_ToStorage, m_To) || !m_Source.CanMoveItemToStorage(m_Item, m_ToStorage, -1)) { Stop(); return m_State; }
if (!m_Delivery && !m_Reservation.Commit()) { Stop(); return m_State; }
if (!m_Reservation.CommittedFor(m_Item)) { Stop(); return m_State; }
if (m_Delivery && !m_Owner.ClaimDelivery(this)) { Stop(); return m_State; }
@@ -0,0 +1,18 @@
[
{
"test": "test_ground_depot_loading.py",
"exit_code": 0
},
{
"test": "test_ground_depot_lifecycle.py",
"exit_code": 0
},
{
"test": "test_ground_depot_transfer.py",
"exit_code": 0
},
{
"test": "test_ground_depot_provenance.py",
"exit_code": 0
}
]
@@ -0,0 +1,57 @@
Ground depot finite loading proposal
Apply fix.patch (five production source paths, two new tests) and independently
reviewed .build/ground-depot-leaf-review-0303/tests.patch (two distinct tests).
No tracked source, index, native process or original reference was changed here.
Working/index preimages and hashes are under baseline/. New paths have null
preimages. source-hashes.json records this proposal. git apply --check passed.
Production contract:
- SiteService retains only exact startup-created OUTPOST magazine identities,
excludes escape-opening sites and objective-target stock, exposes detached
lists only after successful readiness; it never adopts later cache deposits.
- One retained HQ controller, one concurrent job, at most96 admitted attempts.
An existing idle original mobile responder carries one compatible unchanged
original magazine through two independent native inventory moves.
- Existing infantry/mounted/mine/mortar work runs first. Target admission also
needs known committed original-magazine expenditure beyond prior depot
imports. Unknown/deleted spent identities and mine expenditure do not qualify.
This is conservative attempt-ledger depletion, not an asserted live empty truck.
- Fresh delivered truck position plus a NEW post-hold delivered status is used
for dispatch. Cache coordinates are own fixed authored knowledge. No players
queried for task destination, no movement/inventory teleport, no generated stock.
- Original actor/roster/cache/inventory/task/receipt/crew/root and exact tokens
are revalidated. Authored storage anchors, distance/LOS, actual managers and
CanMove capacity gate both once-only native calls. Rounds/capacity stay fixed;
used/loaded magazines cannot be removed.
- Source attempt ledger is global to this one controller and DISTINCT from truck
outgoing spent. Pickup commits before native call. Second leg retains the same
committed handle and a one-shot claim. Separate callbacks cannot cross-ack.
- Destination imports append to the exact existing stock array; lifetime96
includes spent/deleted entries. No eviction, replacement array, refund or refill.
Continuation validity has no capacity/depletion gate, including95->96 import.
- Return completion requires near camp and >=6m actual porter/truck separation.
Deadline180s is fixed and additionally bounded by original report age.
- SupplyHeld pauses the entire six-vehicle column. Failed submitted unknown work
retains both group/truck claims and leaf callback after deadline/Stop; no late
proof can resume movement or admit new stock. Exact callback/custody proof or
deletion settles uncertainty. Owner-guarded stopped polling only removes own
timer and stops on HQ/mode replacement; destructor removes it.
Validation:
- test_ground_depot_loading.py executes actual Plan/Tick/Abort/Stop and
TransferValid/ClaimDelivery/DeliveredTo plus actual AdmitDepot. Native leaves,
movement/access and wider original identity validation are boundary doubles;
a structural check ensures Valid depends on DepotCurrent, not admission gates.
- test_ground_depot_lifecycle.py executes actual HQ Tick/Stop/poll methods.
- Independent test_ground_depot_transfer.py executes actual full native-move
leaf with callbacks and custody doubles, including inline Stop resurrection
red-before/green-after and inline owner revocation.
- Independent test_ground_depot_provenance.py executes actual startup capture,
detached accessors, admission/current/depletion predicates and reservation.
Not qualified by these model tests: native script compilation, exact ordinary
cache/vehicle action anchors, navigation/physical approach reliability, network
inventory callbacks or native successful end-to-end delivery. No engine was run.
This is opportunistic existing camp stock/team access, not a guaranteed warehouse.
Existing source camps may be exhausted, busy, far away or physically inaccessible.
@@ -0,0 +1,133 @@
{
"status": "Final corrected target review completed; source-only approval and focused independent tests passed.",
"findings": [
{
"source": "ERR_HQ.c:354-365",
"constraint": "ReserveLogistics checks Eligible/radio/Assignment/PendingOrder/Downlink/Waypoint but not explicit HomeGuard/Task/PendingTask. Depot admission must require original mobile responder, no stale or pending task, same original physical roster and no combat."
},
{
"source": "ERR_HQ.c:1564-1570",
"constraint": "PlanResupply and Assign run before mortar Tick. New lower-priority depot admission should run after existing planners/maintenance, not steal idle mortar crew before its due delivered request is admitted."
},
{
"source": "ERR_HQ.c:1581-1613; ERR_InfantrySupplyPool.c:30-43",
"constraint": "Only retained m_Resupply pool is polled after HQ Stop. New accepted-unknown depot moves must participate in that Unresolved/Stop/Tick path or exact equivalent; no new operations after Stop, original mode+command guards retained."
},
{
"source": "ERR_InfantryResupply.c:429-450",
"constraint": "Use original delivered truck report for planning; after hold delivery verify physical stop and request fresh status, then require ObservedAt>=HeldAt before selecting reported rendezvous. Never replace report coordinates with current truck origin at HQ planning."
},
{
"source": "ERR_SupplyConvoyColumn.c:146-168",
"constraint": "SupplyHeld on one vehicle causes whole-column hold. Fixed deadline and exact-token cleanup are gameplay-critical; unknown accepted inventory work may legitimately keep quarantine."
},
{
"source": "ERR_HQ.c:382-387",
"constraint": "ReserveMountedLogistics requires two original CONVOY groups and narrow mounted token range, unsuitable for camp porter. Foot group and exact original truck claim must be atomic without weakening existing mounted eligibility."
},
{
"source": "ERR_InfantryResupply.c:40-41,199,289; ERR_FiniteMagazineReservation.c:16-53",
"constraint": "All trucks share source depot claim; keep depot spent/attempted separate from truck outgoing spent. Proven successful import appends once to same m_Stock array shared by mounted controller, never replaces array or resets old m_Spent; retain original96 caps."
},
{
"source": "ERR_InfantryResupply.c:205,284-290",
"constraint": "Idle State alone is insufficient: reject every unresolved native leaf, active mounted controller, m_Move/m_MineMove, SupplyToken, pending combat/downlink; physical transfer admission can continue after stopped mode only for cleanup proof."
}
],
"required_adversarial_tests": [
"Fresh old report plus moving truck does not use live position; no porter movement before post-hold delivered status",
"Existing mortar/infantry/mounted claims beat depot admission; foreign replacement token never cleared",
"Two truck attempts cannot claim one source identity; late callback does not refund/retry/import twice",
"Stop retains strong callbacks and registered polling until exact custody/deletion proof; restart command mismatch cannot start or mutate new-round work",
"Successful second leg only appends original proved item to existing shared stock and preserves all prior spent identities"
],
"draft_review": {
"status": "Initial complete controller/HQ draft read; one concrete doctrine blocker reported to author/root; focused tests pending author readiness.",
"files": [
{
"path": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-0303/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotLoading.c",
"sha256": "fc27216bed042510f7d91955ce6ed838dbdc68503ca026ddcca455806885b42a"
},
{
"path": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-0303/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c",
"sha256": "82618a670efd20f35a332d7a96d1c55ef5d4889ef4e07c78985be6b2d1df5f48"
},
{
"path": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-0303/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c",
"sha256": "e934bce13da4136369be0dd993363760747d3514d935e468b77aaea163c4795f"
},
{
"path": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-0303/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c",
"sha256": "5bdbe583e4c44fc1c32f447f705ee51eceb2497da33a7a1d8c44dfafcca4485a"
}
],
"blocker": "DepotAvailable checks idle/caps only, allowing initially full trucks to consume camp stock until96. Add admission-only known-depletion demand; do not put deficit into maintenance Valid that becomes false immediately after successful import.",
"verified_source_boundaries": [
"Post-super admission gives existing planners/maintenance priority",
"Pre-super Stop and own guarded terminal poll retain callback leaves; exact strong unit refs permit cleanup after base roster clear",
"Distinct300001..300096 token range; exact-token release refuses foreign replacement claims",
"Truck hold is delivered before stop; subsequent fresh status ObservedAt>=HeldAt gates porter downlink",
"Magazine !IsUsed is revalidated by both leaves before native submission",
"Shared source attempted identities and distinct target outgoing stock/spent; target array append preserves mounted shared reference"
],
"limits": "No native compile/walking/storage delivery/replication proof. Doctrine blocker fix and actual-method final tests not yet reviewed."
},
"final_review": {
"status": "Approved bounded source integration; no remaining concrete blocker found. Native walking/loading and multiplayer not qualified by this review.",
"target_matches_proposal_manifest": true,
"hashes": {
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c": "9bd0824995d3e08cdb2745f1cb539ddd27e422509814188ea6ab2ba56631e7cd",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c": "5786e9858b10700c3c11682116534cf2c71576d3ba84341d960dfb194b75c2c1",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotLoading.c": "36da884a833e7a29743308490a3ce5ae299f7a451d87205a227163892aca4ed0",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c": "4a440b3bd9ea52d6bc9ee82061d072ff679e635e58fcc47c04ce52a0b6dc4e8b",
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c": "bcd7530f9a47eeac9e80a031773b27d0f866c4766bafe5f8957570d4e062a8d0",
"tests/test_ground_depot_lifecycle.py": "927a6f15560e177c838322e18ef555ce7db3acde0651d1a43353a2c6e805f3a8",
"tests/test_ground_depot_loading.py": "61b31dc3c2a6cf6bf0aef67fe3ec92b4b2d51ee93fe47e7cc8dc77f2235747af"
},
"independent_tests": [
{
"test": "test_ground_depot_loading.py",
"exit_code": 0,
"log": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-review-0303/test_ground_depot_loading.py.log",
"log_sha256": "b03dfce8159ad1dc55a66bf9a35c54c57c91e1f066865e18c3070ecdfca5f50d"
},
{
"test": "test_ground_depot_lifecycle.py",
"exit_code": 0,
"log": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-review-0303/test_ground_depot_lifecycle.py.log",
"log_sha256": "bd1d802374adb3a8f79548092031c42afa35f851b3219519a6f9b54aa77bfa9d"
}
],
"verified_corrections": [
"DepotNeeded admission requires prior nonnull original-stock commitments exceeding depot imports; initially full stock and mine-only spent entries cannot trigger loading. Plan and atomic ReserveGroundDepot both enforce it.",
"DepotCurrent is separate from capacity/depletion: 95-to96 successful import can retain return/clearance phase; target m_Stock array and prior m_Spent preserved.",
"Native-return path rechecks sticky leaf cancellation and current owner authorization before successful result; used/loaded magazines rejected before either native submission.",
"Successful return requires within5m cache and at least6m truck separation. Deadline/ownership/combat aborts remain bounded exceptional release paths, not guaranteed clearance.",
"Post-super planning preserves existing service priority; radio hold then physically stopped post-HeldAt delivered report then porter downlink; no live player knowledge.",
"Original source/task/root/roster pinned; global source reservation, disjoint token namespace and exact-token release; stopped callback polling guarded by current mode/Command and own queued callback removal."
],
"doctrine_limit": "Known depletion is conservative finite-ledger commitment, not evidence that ammunition was fired. Deleted formerly spent identities no longer increase demand; this may suppress replenishment and does not fabricate new demand.",
"native_limit": "No engine or UI operation performed. Actual-method C++ harnesses do not establish Enforce refcount behavior, native move acceptance, path reach, departure safety on exceptional cancellation or remote replication."
},
"compile_delta_review": {
"status": "Approved narrowly scoped native compile correction; no behavioral guard/state/custody change.",
"patch": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-compile-fix-0303/fix.patch",
"patch_sha256": "766b00225558d9d2cf38f104a7eccdc9d00e8fa78d07828b18e462ef7c181d09",
"verified": "All three changed production files exactly match prior reviewed proposal after whitespace normalization and only Managed-to-StorageManaged helper/call-site rename.",
"changed_production_hashes": {
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c": "8748325b0810ea053b28d0ed4c00a75fceae1c0d1cd3b30efb4dafdc397632ac",
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c": "966068555a6724e620a2c377b98d8dc02f141466c5cdd44636f86cb1cfe9ac78",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c": "1946db0615130b0039b42ec80db12d9cc89b1b3ca5a7eca7d9112eb69c3bdcea"
},
"current_all_reviewed_file_hashes": {
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c": "9bd0824995d3e08cdb2745f1cb539ddd27e422509814188ea6ab2ba56631e7cd",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c": "8748325b0810ea053b28d0ed4c00a75fceae1c0d1cd3b30efb4dafdc397632ac",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotLoading.c": "36da884a833e7a29743308490a3ce5ae299f7a451d87205a227163892aca4ed0",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c": "1946db0615130b0039b42ec80db12d9cc89b1b3ca5a7eca7d9112eb69c3bdcea",
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c": "966068555a6724e620a2c377b98d8dc02f141466c5cdd44636f86cb1cfe9ac78",
"tests/test_ground_depot_lifecycle.py": "927a6f15560e177c838322e18ef555ce7db3acde0651d1a43353a2c6e805f3a8",
"tests/test_ground_depot_loading.py": "61b31dc3c2a6cf6bf0aef67fe3ec92b4b2d51ee93fe47e7cc8dc77f2235747af"
},
"test_boundary": "No redundant tests rerun by reviewer; root rerunning focused tests, author reported four passes. Prior approval regression evidence remains retained. Native initial compile failure archived by root, no new native proof inferred."
}
}
@@ -0,0 +1,170 @@
--- /dev/null
+++ b/tests/test_ground_depot_transfer.py
@@ -0,0 +1,81 @@
+"""Execute complete actual finite two-leg transfer with native inventory boundaries."""
+import os,re
+from pathlib import Path
+from policy_harness import ROOT,run
+from test_finite_magazine_reservation import translated_reservation
+p=Path(os.environ.get('ERR_GROUND_DEPOT_TRANSFER_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c'))
+s=p.read_text();code=s[s.index('class ERR_GroundDepotTransfer\n'):]
+code=re.sub(r'//[^\n]*','',code).replace('protected ','').replace('ref ','').replace('class ','struct ').replace('void ERR_GroundDepotTransfer(','ERR_GroundDepotTransfer(').replace('array<','Array<').replace('null','nullptr')
+for kind,field in {'InventoryStorageManagerComponent':'inventory','InventoryItemComponent':'item','BaseMagazineComponent':'magazine','DamageManagerComponent':'damage'}.items():
+ code=re.sub(kind+r'\.Cast\(([^;\n]*?)\.FindComponent\('+kind+r'\)\)',lambda m:m[1]+'.'+field,code)
+ code=code.replace('.FindComponent('+kind+')','.'+field)
+for name in ('EStoragePurpose','ERR_ForceRules','ERR_InfantryAmmoTransfer'):code=code.replace(name+'.',name+'::')
+for name in ('m_Owner','m_From','m_To','m_Item','m_Source','m_Destination','m_FromSlot','m_FromStorage','m_ToStorage','m_Reservation','m_Callback','source','destination','item','inventoryItem','magazine','damage','inventory','storage','slot'):
+ code=re.sub(r'\b'+name+r'\.',name+'->',code)
+code=code.replace(').',')->').replace('ERR_FiniteMagazineReservation ', 'ERR_FiniteMagazineReservation* ').replace('ERR_GroundDepotCallback ', 'ERR_GroundDepotCallback* ')
+code=re.sub(r'\b(bool|int|IEntity|ERR_GroundDepotLoading|InventoryStorageManagerComponent|InventoryStorageSlot|BaseInventoryStorageComponent|ERR_FiniteMagazineReservation\*|ERR_GroundDepotCallback\*) (\w+);',r'\1 \2{};',code)
+code=code.replace('\n}\n','\n};\n')
+callbacks=[]
+for n in ('OnComplete','OnAllComplete','OnFailed','OnAllFailed'):
+ b=re.search('protected override void '+n+r'\(\) (\{[^\n]+\})',s)[1]
+ callbacks.append('void ERR_GroundDepotCallback::'+n+'() '+b.replace('Transfer.','Transfer->'))
+pre=r'''
+#include <cassert>
+#include <cmath>
+#include <vector>
+#include <algorithm>
+#include <functional>
+#include <limits>
+template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}bool Contains(T x){return std::find(this->begin(),this->end(),x)!=this->end();}void Insert(T x){this->push_back(x);}void RemoveItem(T x){this->erase(std::remove(this->begin(),this->end(),x),this->end());}};
+struct Entity;struct Inventory;struct Slot;struct Storage;struct Magazine;struct Owner;
+using IEntity=Entity*;using InventoryStorageManagerComponent=Inventory*;using InventoryStorageSlot=Slot*;using BaseInventoryStorageComponent=Storage*;using BaseMagazineComponent=Magazine*;using ERR_GroundDepotLoading=Owner*;
+struct Item{Slot*slot=nullptr;Slot*GetParentSlot(){return slot;}};using InventoryItemComponent=Item*;
+struct Damage{bool destroyed=false;bool IsDestroyed(){return destroyed;}};using DamageManagerComponent=Damage*;
+struct Entity{Entity*parent=nullptr;Item*item=nullptr;Magazine*magazine=nullptr;Damage*damage=nullptr;Inventory*inventory=nullptr;};
+struct Slot{Storage*storage=nullptr;IEntity attached=nullptr;Storage*GetStorage(){return storage;}IEntity GetAttachedEntity(){return attached;}};
+struct Storage{IEntity owner=nullptr;IEntity GetOwner(){return owner;}};
+struct Magazine{bool used=false,well=true;int rounds=30,capacity=30;bool IsUsed(){return used;}bool GetMagazineWell(){return well;}int GetAmmoCount(){return rounds;}int GetMaxAmmoCount(){return capacity;}};
+struct ERR_ForceRules{static bool Finite(float x){return std::isfinite(x);}};
+struct ERR_InfantryAmmoTransfer{static bool StoredUnder(IEntity e,IEntity root){for(int i=0;e&&i<16;i++,e=e->parent)if(e==root)return true;return false;}};
+struct EStoragePurpose{static const int PURPOSE_DEPOSIT=1;};
+struct ScriptedInventoryOperationCallback{virtual void OnComplete(){}virtual void OnAllComplete(){}virtual void OnFailed(){}virtual void OnAllFailed(){}virtual ~ScriptedInventoryOperationCallback()=default;};
+struct ERR_GroundDepotTransfer;
+struct ERR_GroundDepotCallback:ScriptedInventoryOperationCallback{ERR_GroundDepotTransfer*Transfer=nullptr;void OnComplete()override;void OnAllComplete()override;void OnFailed()override;void OnAllFailed()override;};
+struct Owner{bool valid=true,claimed=false;int claims=0;bool TransferValid(ERR_GroundDepotTransfer*){return valid;}bool ClaimDelivery(ERR_GroundDepotTransfer*){claims++;if(claimed)return false;claimed=true;return true;}};
+struct Inventory{IEntity owner=nullptr;Array<IEntity>items;Array<Storage*>storages;Storage*selected=nullptr;bool allow=true,accept=true;int calls=0,ack=0;ScriptedInventoryOperationCallback*last=nullptr;std::function<void()>effect;
+ IEntity GetOwner(){return owner;}void GetItems(Array<IEntity>&a,int){a=items;}void GetStorages(Array<Storage*>&a,int){a=storages;}Storage*FindStorageForItem(IEntity,int){return selected;}
+ bool CanMoveItemToStorage(IEntity,Storage*,int){return allow;}
+ bool TryMoveItemToStorage(IEntity,Storage*,int,ScriptedInventoryOperationCallback*cb){calls++;last=cb;if(effect)effect();if(ack==1)cb->OnComplete();if(ack==-1)cb->OnFailed();return accept;}};
+'''
+main=r'''
+struct Fixture{Owner owner;Entity cache,porter,truck,mag,foreign;Inventory source,carry,cargo;Storage cs,ps,ts;Slot cslot,pslot,tslot;Item item;Magazine magazine;Damage damage;Array<IEntity>original,spent;ERR_FiniteMagazineReservation reservation;
+ Fixture():reservation(&original,&spent,&mag){cache.inventory=&source;porter.inventory=&carry;truck.inventory=&cargo;source.owner=&cache;carry.owner=&porter;cargo.owner=&truck;cs.owner=&cache;ps.owner=&porter;ts.owner=&truck;source.storages={&cs};carry.storages={&ps};cargo.storages={&ts};carry.selected=&ps;cargo.selected=&ts;cslot.storage=&cs;pslot.storage=&ps;tslot.storage=&ts;cslot.attached=&mag;item.slot=&cslot;mag.item=&item;mag.magazine=&magazine;mag.damage=&damage;source.items={&mag};original={&mag};assert(reservation.Reserve());}
+ ERR_GroundDepotTransfer Pickup(){return {&owner,&cache,&porter,&mag,&reservation,false};}
+ ERR_GroundDepotTransfer Delivery(){return {&owner,&porter,&truck,&mag,&reservation,true};}
+ void Pick(){source.items.clear();carry.items={&mag};cslot.attached=nullptr;pslot.attached=&mag;item.slot=&pslot;}
+ void Deliver(){carry.items.clear();cargo.items={&mag};pslot.attached=nullptr;tslot.attached=&mag;item.slot=&tslot;}
+};
+int main(){
+ {Fixture f;auto a=f.Pickup();a.Acknowledge(true);assert(a.m_Ack==0);assert(a.Tick(0)==0&&a.Submitted()&&a.Unresolved());assert(f.reservation.CommittedFor(&f.mag));f.source.last->OnComplete();assert(a.Tick(1)==0);f.Pick();assert(a.Tick(2)==1&&a.Confirmed()&&!a.Unresolved());auto b=f.Delivery();assert(b.Tick(3)==0&&f.owner.claims==1);f.source.last->OnAllComplete();assert(b.Tick(4)==0);f.Deliver();assert(b.Tick(5)==0);f.carry.last->OnAllComplete();assert(b.Tick(6)==1&&b.Confirmed()&&!b.Unresolved());assert(f.source.calls==1&&f.carry.calls==1&&f.spent.Count()==1);}
+ {Fixture f;f.source.ack=1;f.source.accept=false;f.source.effect=[&]{assert(f.reservation.CommittedFor(&f.mag));assert(!f.reservation.ReleaseUnsubmitted());f.Pick();};auto a=f.Pickup();assert(a.Tick(0)==1&&!a.Unresolved());}
+ {Fixture f;f.source.accept=false;auto a=f.Pickup();assert(a.Tick(0)==-1&&a.Unresolved());a.Stop();f.Pick();f.source.last->OnComplete();assert(!a.Unresolved()&&!a.Confirmed()&&a.Tick(1)==-1);}
+ {Fixture f;auto a=f.Pickup();a.Tick(0);a.Stop();f.Pick();f.source.last->OnComplete();assert(!a.Unresolved()&&!a.Confirmed()&&a.Tick(1)==-1);}
+ {Fixture f;auto a=f.Pickup();f.source.ack=1;f.source.effect=[&]{a.Stop();f.Pick();};assert(a.Tick(0)==-1&&!a.Confirmed()&&!a.Unresolved());}
+ {Fixture f;auto a=f.Pickup();f.source.ack=1;f.source.effect=[&]{f.owner.valid=false;f.Pick();};assert(a.Tick(0)==-1&&!a.Confirmed()&&!a.Unresolved());}
+ {Fixture f;auto a=f.Pickup();a.Tick(0);f.source.last->OnComplete();f.source.last->OnFailed();assert(a.Tick(1)==-1&&!a.Unresolved());f.source.last->OnAllComplete();assert(a.Tick(2)==-1);}
+ {Fixture f;auto a=f.Pickup();a.Tick(0);f.item.slot=nullptr;f.source.last->OnFailed();assert(a.Tick(1)==-1&&a.Unresolved());}
+ {Fixture f;auto a=f.Pickup();a.Tick(0);assert(a.Tick(8000)==-1&&a.Unresolved());assert(f.source.calls==1&&!f.reservation.ReleaseUnsubmitted());}
+ {Fixture f;auto a=f.Pickup();a.Tick(10);assert(a.Tick(9)==-1&&a.Unresolved());}
+ {Fixture f;auto a=f.Pickup();a.Stop();assert(a.Tick(0)==-1&&!a.Submitted()&&f.reservation.ReleaseUnsubmitted());}
+ {Fixture f;auto a=f.Pickup();a.Tick(0);a.m_Item=nullptr;assert(a.Tick(1)==-1&&!a.Unresolved()&&f.spent.Count()==1);}
+ {Fixture f;auto a=f.Pickup();a.Tick(0);f.damage.destroyed=true;assert(a.Tick(1)==-1&&a.Unresolved());}
+ for(int bad=0;bad<15;bad++){Fixture f;auto a=f.Pickup();switch(bad){case0:break;}
+ if(bad==0)f.magazine.used=true;if(bad==1)f.magazine.rounds=0;if(bad==2)f.magazine.capacity=100001;if(bad==3)f.damage.destroyed=true;if(bad==4)f.owner.valid=false;if(bad==5)f.source.allow=false;if(bad==6)f.carry.selected=nullptr;if(bad==7)f.cslot.attached=&f.foreign;if(bad==8)f.item.slot=&f.pslot;if(bad==9)f.source.items.clear();if(bad==10)f.carry.items={&f.mag};if(bad==11)f.carry.storages.clear();if(bad==12)f.carry.owner=&f.foreign;if(bad==13)f.source.items.resize(129,&f.mag);if(bad==14)f.source.storages.resize(65,&f.cs);
+ assert(a.Tick(0)==-1&&!a.Submitted()&&f.source.calls==0&&f.reservation.ReleaseUnsubmitted());}
+ {Fixture f;auto a=f.Pickup();a.Tick(0);f.magazine.rounds--;assert(a.Tick(1)==-1&&a.Unresolved());}
+ {Fixture f;f.Pick();assert(f.reservation.Commit());auto a=f.Delivery();a.Tick(0);auto b=f.Delivery();assert(b.Tick(1)==-1&&!b.Submitted()&&f.carry.calls==1);}
+}
+'''.replace('switch(bad){case0:break;}','')
+main=main.replace(';if(bad', ';\n if(bad')
+run(pre+translated_reservation()+code+'\n'.join(callbacks)+main)
+print('PASS: actual full depot leaf, exact custody, isolated callbacks, finite reservation, false/unknown and Stop quarantine, once-only delivery and caps; native movement unqualified')
--- /dev/null
+++ b/tests/test_ground_depot_provenance.py
@@ -0,0 +1,83 @@
+"""Actual authored-stock capture/access and exact post-delivery stock admission."""
+import os,re
+from pathlib import Path
+from policy_harness import ROOT,body,run
+from test_finite_magazine_reservation import translated_reservation
+B=Path(os.environ.get('ERR_GROUND_DEPOT_ROOT',ROOT))
+S=Path(os.environ.get('ERR_SITE_SERVICE_SOURCE',B/'addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c'))
+I=B/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'
+L=B/'addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotLoading.c'
+source=S.read_text();start=source.index(' if (spec.Kind == ERR_LocationKind.OUTPOST');capture=source[start:source.index(' placement.Item = item;',start)]
+access='\n'.join(body(S,k) for k in ('int DepotMagazineCount(', 'void DepotStock(', 'IEntity DepotMagazine(', 'bool DepotOriginal('))
+admit='\n'.join(body(I,k) for k in ('bool DepotCurrent(', 'bool DepotAvailable(', 'bool DepotNeeded(', 'bool AdmitDepot('))
+delivered=body(L,'bool DeliveredTo(')
+def adapt(s):
+ s=s.replace('array<IEntity>','Array<IEntity>').replace('out Array<IEntity> items','Array<IEntity>& items').replace('ERR_SiteRuntime site','Site* site').replace('ERR_GroundDepotLoading job','Loading* job').replace('ERR_InfantryResupply service','Service* service')
+ for name in ('site','spec','stock','item','m_Stock','m_Spent','m_Mounted','m_Truck','job','m_Move','m_Reservation'):
+ if name not in ('m_Stock','m_Spent'): s=s.replace(name+'.',name+'->')
+ s=s.replace('site->Definition.', 'site->Definition->').replace('site->Responders.', 'site->Responders->')
+ s=s.replace('stock->TargetId.IsEmpty()','stock->TargetId.empty()').replace('item->FindComponent(BaseMagazineComponent)','item->magazine')
+ s=s.replace('foreach (IEntity item : m_Spent)', 'for (IEntity item : m_Spent)').replace('int committed;', 'int committed=0;')
+ s=s.replace('Replication.IsServer()','server').replace('ERR_PrepareResult.READY','1').replace('ERR_LocationKind.OUTPOST','3').replace('null','nullptr')
+ return s
+run(r'''
+#include <cassert>
+#include <vector>
+#include <algorithm>
+#include <string>
+using string=std::string;bool server=true;
+template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}bool Contains(T x){return std::find(this->begin(),this->end(),x)!=this->end();}void Insert(T x){this->push_back(x);}void RemoveItem(T x){this->erase(std::remove(this->begin(),this->end(),x),this->end());}};
+struct Entity{bool magazine=true;};using IEntity=Entity*;
+struct Def{int Kind=3;bool RevealOnEscape=false;};struct Stock{string TargetId;};
+struct Responders{bool Group=true;};struct Site{Def* Definition=nullptr;IEntity Container=nullptr;struct Responders* Responders=nullptr;Array<IEntity>DepotMagazines;};
+struct Sites{bool m_Stopped=false;int m_State=0;Array<Site*>m_Sites;Array<IEntity>m_Entities;bool Owns(IEntity x){return m_Entities.Contains(x);}
+''' + adapt(access)+ '\nvoid Capture(Def* spec,Stock* stock,Site* site,IEntity item){'+adapt(capture)+r'''}
+};
+''' + translated_reservation()+r'''
+struct Service;
+struct Proof{bool done=true,delivery=true;bool Confirmed(){return done;}bool Delivery(){return delivery;}};
+struct Loading{bool m_Imported=false,valid=true;int m_State=5;Service* m_Service=nullptr;IEntity m_Item=nullptr;Proof* m_Move=nullptr;ERR_FiniteMagazineReservation* m_Reservation=nullptr;bool Valid(){return valid;}bool DeliveredTo(Service*,IEntity);};
+struct Mounted{bool busy=false;bool Busy(){return busy;}};
+struct Truck{IEntity Entity=nullptr;};
+struct Service{bool current=true,truckValid=true,unresolved=false,m_Move=false,m_MineMove=false;int m_State=1,audits=0,m_DepotImports=0;Array<IEntity>m_Stock,m_Spent,cargo;Mounted* m_Mounted=nullptr;Truck* m_Truck=nullptr;bool Current(){return current;}bool Unresolved(){return unresolved;}bool TruckValid(bool endpoint){assert(endpoint);return truckValid;}bool Contains(IEntity,IEntity item){return cargo.Contains(item);}void Audit(string){audits++;}
+''' + adapt(admit)+r'''};
+''' + adapt(delivered).replace('bool DeliveredTo(', 'bool Loading::DeliveredTo(')+r'''
+struct F{Entity cache,item,foreign,truck;Def def;Stock stock;Responders responders;Site site;Sites sites;Array<IEntity>original,spent;ERR_FiniteMagazineReservation reservation;Service service;Loading job;Proof proof;Truck vehicle;Mounted mounted;
+ F():reservation(&original,&spent,&item){site.Definition=&def;site.Container=&cache;site.Responders=&responders;sites.m_Sites={&site};sites.m_Entities={&cache};sites.Capture(&def,&stock,&site,&item);original={&item};assert(reservation.Reserve()&&reservation.Commit());job.m_Reservation=&reservation;job.m_Move=&proof;job.m_Item=&item;job.m_Service=&service;vehicle.Entity=&truck;service.m_Truck=&vehicle;service.m_Mounted=&mounted;service.cargo={&item};}
+};
+int main(){
+ {F f;Array<IEntity>out;f.sites.DepotStock(&f.site,out);assert(out.empty());f.sites.m_State=1;f.sites.DepotStock(&f.site,out);assert(out.Count()==1&&out[0]==&f.item);out[0]=&f.foreign;out.clear();assert(f.sites.DepotOriginal(&f.site,&f.item)&&!f.sites.DepotOriginal(&f.site,&f.foreign));assert(f.sites.DepotMagazine(&f.site,-1)==nullptr&&f.sites.DepotMagazine(&f.site,1)==nullptr);f.sites.m_Stopped=true;assert(!f.sites.DepotOriginal(&f.site,&f.item));}
+ for(int kind=0;kind<6;kind++){F f;f.site.DepotMagazines.clear();if(kind==0)f.def.RevealOnEscape=true;if(kind==1)f.def.Kind=4;if(kind==2)f.stock.TargetId="radio";if(kind==3)f.item.magazine=false;if(kind==4)f.site.DepotMagazines.resize(96,&f.foreign);f.sites.Capture(&f.def,&f.stock,&f.site,&f.item);assert(f.site.DepotMagazines.Contains(&f.item)==(kind==5));}
+ for(int bad=0;bad<7;bad++){F f;f.sites.m_State=1;if(bad==0)server=false;if(bad==1)f.sites.m_Sites.clear();if(bad==2)f.site.Container=nullptr;if(bad==3)f.sites.m_Entities.clear();if(bad==4)f.site.Responders=nullptr;if(bad==5)f.responders.Group=false;if(bad==6)f.site.DepotMagazines.resize(97,&f.item);assert(f.sites.DepotMagazineCount(&f.site)==0);server=true;}
+ {F f;assert(f.service.AdmitDepot(&f.job,&f.item));assert(f.service.m_Stock.Count()==1&&f.service.m_Stock[0]==&f.item&&f.service.audits==1);assert(!f.service.AdmitDepot(&f.job,&f.item));ERR_FiniteMagazineReservation outgoing(&f.service.m_Stock,&f.service.m_Spent,&f.item);assert(outgoing.Reserve()&&outgoing.Commit());assert(f.spent.Count()==1&&f.service.m_Spent.Count()==1);assert(!f.service.AdmitDepot(&f.job,&f.item));}
+ // Deleted identities and mine-only spent entries cannot create magazine demand.
+ {F f;f.service.m_Stock={nullptr};f.service.m_Spent={nullptr,&f.foreign};assert(!f.service.DepotNeeded());f.service.m_Stock.Insert(&f.foreign);assert(f.service.DepotNeeded());f.service.m_DepotImports=1;assert(!f.service.DepotNeeded());Entity another;f.service.m_Stock.Insert(&another);f.service.m_Spent.Insert(&another);assert(f.service.DepotNeeded());}
+ // Final lifetime slot can complete delivery and departure; admission then closes.
+ {F f;f.service.m_Stock.resize(95,&f.foreign);f.service.m_Spent={&f.foreign};assert(f.service.DepotNeeded());assert(f.service.AdmitDepot(&f.job,&f.item));assert(f.service.m_Stock.Count()==96&&f.service.m_DepotImports==1);assert(f.service.DepotCurrent()&&!f.service.DepotAvailable()&&!f.service.DepotNeeded());}
+ for(int bad=0;bad<21;bad++){F f;
+ if(bad==0)f.service.current=false;
+ if(bad==1)f.service.m_State=7;
+ if(bad==2)f.service.m_Move=true;
+ if(bad==3)f.service.m_MineMove=true;
+ if(bad==4)f.service.unresolved=true;
+ if(bad==5)f.mounted.busy=true;
+ if(bad==6)f.service.truckValid=false;
+ if(bad==7)f.service.m_Stock.resize(96,&f.foreign);
+ if(bad==8)f.service.m_Spent.resize(96,&f.foreign);
+ if(bad==9)f.service.m_Spent={&f.item};
+ if(bad==10)f.service.cargo.clear();
+ if(bad==11)f.job.m_Imported=true;
+ if(bad==12)f.job.m_State=7;
+ if(bad==13)f.job.m_Service=nullptr;
+ if(bad==14)f.job.m_Item=&f.foreign;
+ if(bad==15)f.proof.done=false;
+ if(bad==16)f.proof.delivery=false;
+ if(bad==17)f.job.m_Move=nullptr;
+ if(bad==18)f.job.m_Reservation=nullptr;
+ if(bad==19)f.job.valid=false;
+ if(bad==20)f.spent.clear();
+ int before=f.service.m_Stock.Count();assert(!f.service.AdmitDepot(&f.job,&f.item));assert(f.service.m_Stock.Count()==before&&f.service.audits==0);}
+ {F f;f.job.m_State=7;f.proof.done=true;assert(!f.service.AdmitDepot(&f.job,&f.item));f.job.m_State=5;f.job.valid=false;assert(!f.service.AdmitDepot(&f.job,&f.item));}
+}
+''')
+print('PASS: actual authored identity capture, READY-only detached provenance, same shared stock admission, completed exact two-leg proof, lifetime caps and Stop no late adoption')
@@ -0,0 +1 @@
PASS: actual full depot leaf, exact custody, isolated callbacks, finite reservation, false/unknown and Stop quarantine, once-only delivery and caps; native movement unqualified
@@ -0,0 +1,12 @@
check: /home/jakub/devel/escapistsrereintroduced/.build/death-diagnostic-2153/test-tmp/err-policy-t9j0t_66/check.cpp:222: int main(): Assertion `a.Tick(0)==-1&&!a.Confirmed()&&!a.Unresolved()' failed.
Traceback (most recent call last):
File "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-leaf-review-0303/tests/test_ground_depot_transfer.py", line 79, in <module>
run(pre+translated_reservation()+code+'\n'.join(callbacks)+main)
~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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 '['/home/jakub/devel/escapistsrereintroduced/.build/death-diagnostic-2153/test-tmp/err-policy-t9j0t_66/check']' died with <Signals.SIGABRT: 6>.
@@ -0,0 +1,41 @@
Test audio routed to silent output and muted (stream 681134)
{
"stopped_unix": 1790904556.4923153,
"console_sha256": "bd5f706ecaa00459efe35784a09df31aec776e29bfa653651012b9ac26cf0677",
"end_source_sha256": "80b4e0cf085d364119fdf17599dc1e9c7a233705818bad564dfadac04e3f0381",
"source_unchanged_after_run": true,
"source_provenance": "launch_snapshot",
"launch_id": "be996c78-339a-4854-9bd6-c194bc54d188",
"launch_source_manifest": "launch-source-sha256.json",
"launch_source_metadata": "launch-source.json",
"launch_source_sha256": "80b4e0cf085d364119fdf17599dc1e9c7a233705818bad564dfadac04e3f0381",
"external_addons_unchanged_after_run": true,
"external_addon_count": 7,
"external_addon_inputs": "external-addons-inputs.json",
"started_unix": 1790904545.9913135,
"result": "test-failed",
"result_before_cleanup": "test-failed",
"cleanup_confirmed": true,
"cleanup_report": {
"cleanup_confirmed": true,
"idle_verified": true,
"errors": [],
"orphan_cleanup": {
"attempted": true,
"report": {
"scope": "/tmp/erri-headless-compat/pfx",
"candidates": [],
"term_sent": [],
"kill_sent": [],
"cleared": true
}
}
},
"runner_error": null,
"session": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-profile-0303/logs/logs_2026-10-02_03-29-07",
"rounds_required": 1,
"project": "chat",
"display": "headless Gamescope 1280x720/30Hz",
"dedicated_server": false,
"audio": "silent sink and per-test-stream mute"
}
@@ -0,0 +1,64 @@
Test audio routed to silent output and muted (stream 681312)
{
"stopped_unix": 1790904918.21118,
"console_sha256": "65d3cb9f6024eb40606eb87a97aed155c8166ebefa526689e04cb5b7cae9411c",
"end_source_sha256": "3f720acc2def64f4ee90d6ec140b5743efc6e4a804fc29f941d238d0cd6c95c6",
"source_unchanged_after_run": true,
"source_provenance": "launch_snapshot",
"launch_id": "66a615ef-76fe-4a4c-be16-f500b471bc95",
"launch_source_manifest": "launch-source-sha256.json",
"launch_source_metadata": "launch-source.json",
"launch_source_sha256": "3f720acc2def64f4ee90d6ec140b5743efc6e4a804fc29f941d238d0cd6c95c6",
"external_addons_unchanged_after_run": true,
"external_addon_count": 7,
"external_addon_inputs": "external-addons-inputs.json",
"started_unix": 1790904720.2393904,
"result": "smoke-completed",
"result_before_cleanup": "smoke-completed",
"cleanup_confirmed": true,
"cleanup_report": {
"cleanup_confirmed": true,
"idle_verified": true,
"errors": [],
"orphan_cleanup": {
"attempted": true,
"report": {
"scope": "/tmp/erri-headless-compat/pfx",
"candidates": [],
"term_sent": [],
"kill_sent": [],
"cleared": true
}
}
},
"runner_error": null,
"session": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-fixed-profile-0303/logs/logs_2026-10-02_03-32-01",
"rounds_required": 1,
"project": "chat",
"display": "headless Gamescope 1280x720/30Hz",
"dedicated_server": false,
"audio": "silent sink and per-test-stream mute"
}
{
"log": "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-fixed-profile-0303/logs/logs_2026-10-02_03-32-01/console.log",
"smoke_completions": 1,
"assertions_passed": 63,
"script_or_runtime_failures": [],
"engine_errors": [
"03:32:03.686 RESOURCES (E): Wrong GUID/name for resource @\"{0AFDD005CD669892}Language/rhs_localization.st\" in property \"StringTableSource\"",
"03:32:03.687 RESOURCES (E): Wrong GUID/name for resource @\"{41FA2A08B6971D4C}Language/wcs_armament_localization.st\" in property \"StringTableSource\"",
"03:32:03.687 RESOURCES (E): Wrong GUID/name for resource @\"{84270E09F7A4A7A0}Language/wcs_spacecore_localization.st\" in property \"StringTableSource\"",
"03:32:03.687 RESOURCES (E): Wrong GUID/name for resource @\"{E50E557B468C7073}Language/wcs_bmp1_localization.st\" in property \"StringTableSource\"",
"03:32:42.551 WORLD (E): Unknown keyword/data 'Parent' at offset 35955(0x8c73)",
"03:32:42.551 WORLD (E): Unknown keyword/data 'Parent' at offset 36915(0x9033)",
"03:32:42.552 WORLD (E): Unknown keyword/data 'Parent' at offset 42646(0xa696)",
"03:32:42.552 WORLD (E): Unknown keyword/data 'Parent' at offset 43645(0xaa7d)",
"03:32:42.552 WORLD (E): Unknown keyword/data 'Parent' at offset 44617(0xae49)",
"03:32:42.552 WORLD (E): Unknown keyword/data 'Parent' at offset 45590(0xb216)",
"03:32:42.648 WORLD (E): Unknown keyword/data 'SlidingTrackMaterial' at offset 19441(0x4bf1)",
"03:32:48.716 WORLD (E): Unknown keyword/data 'm_HardLandingVelocity' at offset 133(0x85)",
"03:32:48.716 WORLD (E): Unknown keyword/data 'm_DeathLandingVelocity' at offset 163(0xa3)"
],
"missing_end_screen": [],
"scope": "scripted local Workbench integration only; no multiplayer, piloting or FPS claim"
}
@@ -0,0 +1,9 @@
{
"addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c": "9bd0824995d3e08cdb2745f1cb539ddd27e422509814188ea6ab2ba56631e7cd",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c": "5786e9858b10700c3c11682116534cf2c71576d3ba84341d960dfb194b75c2c1",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotLoading.c": "36da884a833e7a29743308490a3ce5ae299f7a451d87205a227163892aca4ed0",
"addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c": "4a440b3bd9ea52d6bc9ee82061d072ff679e635e58fcc47c04ce52a0b6dc4e8b",
"addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c": "bcd7530f9a47eeac9e80a031773b27d0f866c4766bafe5f8957570d4e062a8d0",
"tests/test_ground_depot_lifecycle.py": "927a6f15560e177c838322e18ef555ce7db3acde0651d1a43353a2c6e805f3a8",
"tests/test_ground_depot_loading.py": "61b31dc3c2a6cf6bf0aef67fe3ec92b4b2d51ee93fe47e7cc8dc77f2235747af"
}
@@ -0,0 +1,800 @@
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_SiteService.c
@@ -12,6 +12,7 @@
ref ERR_SiteDefinition Definition;
ERR_LocationComponent Location;
IEntity Container;
+ ref array<IEntity> DepotMagazines = {}; // Exact authored startup identities; never refreshed from live inventory.
SCR_AIGroup Group;
ref ERR_SiteRuntime Responders;
string ExpectedGuardFaction;
@@ -56,6 +57,30 @@
{
if (index < 0 || index >= m_Sites.Count()) return null;
return m_Sites[index];
+ }
+ // Optional ground loading consumes only retained original camp magazines.
+ int DepotMagazineCount(ERR_SiteRuntime site)
+ {
+ if (!Replication.IsServer() || m_Stopped || m_State != ERR_PrepareResult.READY || !site || !m_Sites.Contains(site)) return 0;
+ if (!site.Definition || site.Definition.Kind != ERR_LocationKind.OUTPOST || site.Definition.RevealOnEscape) return 0;
+ if (!site.Container || !Owns(site.Container) || !site.Responders || !site.Responders.Group) return 0;
+ if (site.DepotMagazines.Count() > 96) return 0;
+ return site.DepotMagazines.Count();
+ }
+ void DepotStock(ERR_SiteRuntime site, out array<IEntity> items)
+ {
+ items = {};
+ int count = DepotMagazineCount(site);
+ for (int i = 0; i < count; i++) items.Insert(site.DepotMagazines[i]);
+ }
+ IEntity DepotMagazine(ERR_SiteRuntime site, int index)
+ {
+ if (index < 0 || index >= DepotMagazineCount(site)) return null;
+ return site.DepotMagazines[index];
+ }
+ bool DepotOriginal(ERR_SiteRuntime site, IEntity item)
+ {
+ return item && DepotMagazineCount(site) > 0 && site.DepotMagazines.Contains(item);
}
bool Owns(IEntity entity) { return entity && m_Entities.Contains(entity); }
// Snapshot only nearby mission-owned objects. Distant sites must not block
@@ -389,6 +414,8 @@
document.SetTarget(stock.TargetId);
}
ERR_StockPlacement placement = new ERR_StockPlacement();
+ if (spec.Kind == ERR_LocationKind.OUTPOST && !spec.RevealOnEscape && stock.TargetId.IsEmpty()
+ && item.FindComponent(BaseMagazineComponent) && site.DepotMagazines.Count() < 96) site.DepotMagazines.Insert(item);
placement.Item = item;
placement.Inventory = inventory;
m_Placements.Insert(placement);
--- /dev/null
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c
@@ -0,0 +1,69 @@
+// Optional depot work runs after all existing tactical/logistics planners.
+modded class ERR_HQ
+{
+ protected ref ERR_GroundDepotLoading m_GroundDepot;
+ int GroundSupplyCount() { if (!m_Resupply) return 0; return m_Resupply.Count(); }
+ ERR_InfantryResupply GroundSupplyAt(int index) { if (!m_Resupply) return null; return m_Resupply.At(index); }
+ ERR_HQUnit GroundUnit(SCR_AIGroup group)
+ {
+ if (!group) return null;
+ foreach (ERR_HQUnit unit : m_Units) if (unit && unit.Group == group) return unit;
+ return null;
+ }
+ bool ReserveGroundDepot(ERR_HQUnit crew, ERR_HQUnit donor, ERR_InfantryResupply service, int token)
+ {
+ if (!Replication.IsServer() || m_Stopping || !m_Mode || m_Mode != ERR_GameMode.Get() || !m_Mode.Active()) return false;
+ if (m_Mode.Command() != this) return false;
+ if (token <= 300000 || token > 300096 || !crew || !donor || crew == donor || !m_Units.Contains(crew)) return false;
+ if (!service || !service.DepotNeeded() || !MountedLogisticsEligible(donor)) return false;
+ ERR_ConvoyVehicle truck = service.DepotTruck();
+ if (!truck || truck.Group != donor.Group || truck.SupplyToken > 0) return false;
+ if (crew.HomeGuard || crew.ReservedForSupport || crew.Task || crew.PendingTask || crew.PendingCheckin || crew.PendingConvoyOrder) return false;
+ if (!ReserveLogistics(crew.Group, token)) return false;
+ // Single authoritative call, no native mutation between validation and claims.
+ donor.LogisticsReservation = token; truck.SupplyToken = token;
+ return true;
+ }
+ void ReleaseGroundDepot(ERR_HQUnit crew, ERR_HQUnit donor, ERR_ConvoyVehicle truck, int token)
+ {
+ if (!Replication.IsServer() || token <= 300000 || token > 300096) return;
+ // These retained exact unit objects outlive base Stop's m_Units.Clear().
+ if (crew && crew.LogisticsReservation == token) crew.LogisticsReservation = 0;
+ if (donor && donor.LogisticsReservation == token) donor.LogisticsReservation = 0;
+ if (truck && truck.SupplyToken == token) { truck.SupplyToken = 0; truck.SupplyHeld = false; }
+ }
+ override string Status()
+ {
+ string result = super.Status();
+ if (m_GroundDepot) result += "\n" + m_GroundDepot.Status();
+ return result;
+ }
+ override void Tick(float now)
+ {
+ super.Tick(now);
+ if (!Replication.IsServer() || !m_Mode || m_Mode != ERR_GameMode.Get() || m_Mode.Command() != this) return;
+ if (m_GroundDepot) m_GroundDepot.Tick(now);
+ if (m_Stopping || !m_Mode.Active() || m_Mode.Phase() < ERR_Phase.RADIO_SEARCH) return;
+ if (!m_GroundDepot) m_GroundDepot = new ERR_GroundDepotLoading(this, m_Mode);
+ m_GroundDepot.Plan(now);
+ }
+ protected void CancelGroundDepotPoll()
+ {
+ if (GetGame() && GetGame().GetCallqueue()) GetGame().GetCallqueue().Remove(PollGroundDepot);
+ }
+ protected void PollGroundDepot()
+ {
+ CancelGroundDepotPoll();
+ if (!m_Stopping || !Replication.IsServer() || !m_Mode || m_Mode != ERR_GameMode.Get() || m_Mode.Command() != this) return;
+ if (!m_GroundDepot || !GetGame() || !GetGame().GetWorld() || !GetGame().GetCallqueue()) return;
+ m_GroundDepot.Tick(GetGame().GetWorld().GetWorldTime());
+ if (m_GroundDepot.Unresolved()) GetGame().GetCallqueue().CallLater(PollGroundDepot, 1000, false);
+ }
+ override void Stop()
+ {
+ if (m_GroundDepot) m_GroundDepot.Stop();
+ super.Stop();
+ PollGroundDepot();
+ }
+ void ~ERR_HQ() { CancelGroundDepotPoll(); }
+}
--- /dev/null
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotLoading.c
@@ -0,0 +1,352 @@
+// Native storage anchors only; no invented interaction point or remote move.
+class ERR_GroundDepotAccess
+{
+ protected IEntity m_Root;
+ protected IEntity m_Actor;
+ protected bool Filter(notnull IEntity entity)
+ {
+ return !ERR_ConvoyRules.PartOf(entity, m_Root) && !ERR_ConvoyRules.PartOf(entity, m_Actor);
+ }
+ static bool Points(IEntity root, out array<vector> points)
+ {
+ points = {};
+ if (!root) return false;
+ ActionsManagerComponent manager = ActionsManagerComponent.Cast(root.FindComponent(ActionsManagerComponent));
+ if (!manager || !manager.IsEnabled()) return false;
+ array<UserActionContext> contexts = {}; manager.GetContextList(contexts);
+ if (contexts.IsEmpty() || contexts.Count() > 128) return false;
+ foreach (UserActionContext context : contexts)
+ {
+ if (!context) return false;
+ array<BaseUserAction> actions = {}; context.GetActionsList(actions);
+ if (actions.Count() > 64) return false;
+ bool storage;
+ foreach (BaseUserAction action : actions)
+ if (action && action.GetOwner() == root && (SCR_OpenStorageAction.Cast(action) || SCR_OpenVehicleStorageAction.Cast(action))) storage = true;
+ if (!storage) continue;
+ vector transform[4];
+ if (!context.GetTransformationWorld(transform) || !ERR_ForceRules.FiniteVector(transform[3])) return false;
+ points.Insert(transform[3]);
+ }
+ return !points.IsEmpty();
+ }
+ bool Check(IEntity root, IEntity actor)
+ {
+ ChimeraCharacter character = ChimeraCharacter.Cast(actor);
+ if (!character || !GetGame() || !GetGame().GetWorld()) return false;
+ array<vector> points;
+ if (!Points(root, points)) return false;
+ vector start = character.AimingPosition();
+ if (!ERR_ForceRules.FiniteVector(start)) return false;
+ m_Root = root; m_Actor = actor;
+ foreach (vector point : points)
+ {
+ float distance = vector.Distance(start, point);
+ if (!(distance >= 0.05 && distance <= 3)) continue;
+ TraceParam trace = new TraceParam(); trace.Start = start; trace.End = point;
+ trace.Flags = TraceFlags.WORLD | TraceFlags.ENTS; trace.LayerMask = TRACE_LAYER_CAMERA;
+ if (GetGame().GetWorld().TraceMove(trace, Filter) == 1) return true;
+ }
+ return false;
+ }
+ static bool Clear(IEntity root, IEntity actor)
+ {
+ ERR_GroundDepotAccess access = new ERR_GroundDepotAccess(); return access.Check(root, actor);
+ }
+}
+
+// Opportunistic camp -> original responder -> original ammo truck. One job
+// mission-wide; no new force, warehouse, stock, native inventory retry or refill.
+class ERR_GroundDepotLoading
+{
+ protected ERR_HQ m_HQ;
+ protected ERR_GameMode m_Mode;
+ protected ref array<IEntity> m_Original = {};
+ protected ref array<IEntity> m_Spent = {};
+ protected bool m_Captured;
+ protected bool m_Stopped;
+ protected int m_Attempts;
+ protected int m_Delivered;
+ protected int m_State; // 0 idle,1 truck radio,2 stopped report,3 porter radio,4 pickup,5 delivery,6 returning,7 quarantine
+ protected int m_Token;
+ protected float m_Deadline;
+ protected float m_HeldAt = -1;
+ protected float m_NextPlan;
+ protected float m_NextTick;
+ protected float m_Last = -1;
+ protected ERR_SiteRuntime m_Site;
+ protected IEntity m_Cache;
+ protected InventoryStorageManagerComponent m_CacheInventory;
+ protected IEntity m_Worker;
+ protected SCR_AIUtilityComponent m_Utility;
+ protected int m_WorkerSlot;
+ protected ref ERR_HQUnit m_Crew;
+ protected ref ERR_HQUnit m_Donor;
+ protected ref ERR_ForceRecord m_CrewRecord;
+ protected ERR_InfantryResupply m_Service;
+ protected ERR_ConvoyTask m_Task;
+ protected ERR_ConvoyVehicle m_Truck;
+ protected IEntity m_Item;
+ protected vector m_CachePosition;
+ protected vector m_TruckPosition;
+ protected ref ERR_HQRoute m_Order;
+ protected ref SCR_AIBehaviorBase m_Action;
+ protected ref ERR_GroundDepotTransfer m_Move;
+ protected ref ERR_FiniteMagazineReservation m_Reservation;
+ protected bool m_PickedUp;
+ protected bool m_DeliveryClaimed;
+ protected bool m_Imported;
+ void ERR_GroundDepotLoading(ERR_HQ hq, ERR_GameMode mode) { m_HQ = hq; m_Mode = mode; }
+ bool Busy() { return m_State != 0; }
+ bool Unresolved() { return m_Move && m_Move.Unresolved(); }
+ string Status() { return string.Format("Ground depot: one job, state=%1; delivered=%2; attempts=%3/96; original sources=%4", m_State, m_Delivered, m_Attempts, m_Original.Count()); }
+ protected bool Active()
+ {
+ return !m_Stopped && Replication.IsServer() && m_Mode && m_Mode == ERR_GameMode.Get() && m_Mode.Active() && m_Mode.Command() == m_HQ;
+ }
+ protected void Note(string reason)
+ {
+ if (m_HQ) m_HQ.Journal().Write("GROUND DEPOT", reason, m_Token);
+ }
+ protected static bool Present(IEntity entity)
+ {
+ if (!entity) return false;
+ DamageManagerComponent damage = DamageManagerComponent.Cast(entity.FindComponent(DamageManagerComponent));
+ return !damage || !damage.IsDestroyed();
+ }
+ protected bool Stationary()
+ {
+ if (!m_Truck || !m_Truck.Entity || !m_Truck.Entity.GetPhysics()) return false;
+ Physics physics = m_Truck.Entity.GetPhysics();
+ float speed = physics.GetVelocity().Length(); float angular = physics.GetAngularVelocity().Length();
+ return speed >= 0 && speed <= 0.25 && angular >= 0 && angular <= 0.1;
+ }
+ protected bool Quiet(ERR_HQUnit unit)
+ {
+ return unit && unit.Group && unit.Utility && unit.StatusSampler && !unit.Group.IsSlave()
+ && unit.Group.GetPlayerCount(true) == 0 && unit.Group.GetFaction() == m_Mode.EnemyFaction()
+ && (!unit.Utility.m_Perception || unit.Utility.m_Perception.m_aTargets.IsEmpty());
+ }
+ protected bool WorkerValid()
+ {
+ if (!Quiet(m_Crew) || !m_Worker || !m_Utility || !m_Utility.m_AIInfo || !ERR_Actors.CanFight(m_Worker)) return false;
+ if (!m_Crew.StatusSampler.OwnsRoster(m_Crew.Group) || !m_Crew.StatusSampler.CanAttribute(m_WorkerSlot, m_Worker, false)) return false;
+ if (!ERR_EnemyEquipmentRules.Eligible(m_Mode, m_Crew.Group, m_Worker) || CompartmentAccessComponent.GetVehicleIn(m_Worker)) return false;
+ SCR_ChimeraAIAgent agent = SCR_ChimeraAIAgent.Cast(SCR_AIUtils.GetAIAgent(m_Worker));
+ return agent && agent.m_UtilityComponent == m_Utility && m_CrewRecord && m_Mode.Forces().FindGroup(m_Crew.Group) == m_CrewRecord
+ && m_CrewRecord.Physical && !m_CrewRecord.Eliminated;
+ }
+ protected bool Valid()
+ {
+ if (!Active() || !m_Service || m_Service.Task() != m_Task || !m_Service.DepotCurrent() || m_Service.DepotTruck() != m_Truck) return false;
+ if (!m_Task || !m_Task.Receipt || !m_Task.Receipt.Consumed || m_Task.Vehicles.Count() != 6 || m_Task.Vehicles[1] != m_Truck) return false;
+ ERR_SupplyConvoyTask supply = ERR_SupplyConvoyTask.Cast(m_Task);
+ if (!supply || !supply.Tactics || supply.Tactics.State() != 0 || !m_Truck.Combat || m_Truck.Combat.Held) return false;
+ if (!Quiet(m_Donor) || m_Donor.Group != m_Truck.Group || !m_HQ.ValidateBoundVehicle(m_Donor.Group, m_Truck.Entity)) return false;
+ if (!m_Site || !m_Mode.Sites() || !m_Site.Definition || m_Mode.Sites().Find(m_Site.Definition.Id) != m_Site) return false;
+ if (m_Site.Container != m_Cache || !Present(m_Cache) || m_Cache.FindComponent(InventoryStorageManagerComponent) != m_CacheInventory) return false;
+ if (!m_Site.Responders || m_Site.Responders.Group != m_Crew.Group || !m_Mode.Sites().DepotOriginal(m_Site, m_Item)) return false;
+ if (vector.Distance(m_Cache.GetOrigin(), m_CachePosition) > 2 || !WorkerValid()) return false;
+ return m_Token > 300000 && m_Truck.SupplyToken == m_Token && m_Crew.LogisticsReservation == m_Token && m_Donor.LogisticsReservation == m_Token;
+ }
+ protected void Capture()
+ {
+ if (m_Captured || !m_Mode.Sites()) return;
+ m_Captured = true;
+ for (int i = 0; i < m_Mode.Sites().Count() && i < 64; i++)
+ {
+ ERR_SiteRuntime site = m_Mode.Sites().At(i);
+ array<IEntity> originals = {}; m_Mode.Sites().DepotStock(site, originals);
+ foreach (IEntity item : originals)
+ {
+ if (m_Original.Count() >= 96) return;
+ if (item && !m_Original.Contains(item)) m_Original.Insert(item);
+ }
+ }
+ }
+ protected bool Stored(IEntity item, IEntity owner)
+ {
+ if (!item || !owner || !ERR_InfantryAmmoTransfer.StoredUnder(item, owner)) return false;
+ InventoryItemComponent carried = InventoryItemComponent.Cast(item.FindComponent(InventoryItemComponent));
+ if (!carried || !carried.GetParentSlot() || carried.GetParentSlot().GetAttachedEntity() != item) return false;
+ InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(owner.FindComponent(InventoryStorageManagerComponent));
+ if (!inventory || inventory.GetOwner() != owner) return false;
+ array<IEntity> items = {}; ERR_Inventory.Items(inventory, items);
+ return items.Count() <= 128 && items.Contains(item);
+ }
+ protected bool SelectWorker(ERR_HQUnit crew)
+ {
+ if (!Quiet(crew) || crew.HomeGuard || crew.ReservedForSupport || crew.LogisticsReservation > 0) return false;
+ if (crew.Assignment || crew.Task || crew.PendingTask || crew.PendingOrder || crew.Downlink || crew.Waypoint) return false;
+ int count = crew.StatusSampler.InitialStrength();
+ if (count < 1 || count > 32 || !crew.StatusSampler.OwnsRoster(crew.Group)) return false;
+ for (int slot = 0; slot < count; slot++)
+ {
+ IEntity actor = crew.StatusSampler.InitialMember(slot);
+ if (!actor || !crew.StatusSampler.CanAttribute(slot, actor, false) || !ERR_Actors.CanFight(actor) || CompartmentAccessComponent.GetVehicleIn(actor)) continue;
+ SCR_ChimeraAIAgent agent = SCR_ChimeraAIAgent.Cast(SCR_AIUtils.GetAIAgent(actor));
+ if (!agent || !agent.m_UtilityComponent || !agent.m_UtilityComponent.m_AIInfo) continue;
+ m_Worker = actor; m_WorkerSlot = slot; m_Utility = agent.m_UtilityComponent; return true;
+ }
+ return false;
+ }
+ void Plan(float now)
+ {
+ if (!Active() || Busy() || !ERR_ForceRules.Finite(now) || now < m_NextPlan || m_Attempts >= 96) return;
+ m_NextPlan = now + 5000; Capture();
+ for (int index = 0; index < m_HQ.GroundSupplyCount() && index < 20; index++)
+ {
+ ERR_InfantryResupply service = m_HQ.GroundSupplyAt(index);
+ if (!service || !service.DepotNeeded()) continue;
+ ERR_ConvoyVehicle truck = service.DepotTruck();
+ if (!truck || truck.SupplyToken > 0) continue;
+ ERR_HQUnit donor = m_HQ.GroundUnit(truck.Group);
+ if (!Quiet(donor)) continue;
+ ERR_HQWatchEntry report = m_HQ.Watch().Find(donor.ForceSourceId);
+ if (!ERR_InfantryResupplyRules.Fresh(report, now)) continue;
+ for (int siteIndex = 0; siteIndex < m_Mode.Sites().Count() && siteIndex < 64; siteIndex++)
+ {
+ ERR_SiteRuntime site = m_Mode.Sites().At(siteIndex);
+ if (!site || !site.Definition || m_Mode.Sites().DepotMagazineCount(site) <= 0) continue;
+ // The camp is an authored own location; only the truck position is reported.
+ if (vector.DistanceXZ(site.Definition.Position, report.Position) > 150) continue;
+ ERR_HQUnit crew = m_HQ.GroundUnit(site.Responders.Group);
+ if (!SelectWorker(crew)) continue;
+ for (int itemIndex = 0; itemIndex < m_Mode.Sites().DepotMagazineCount(site) && itemIndex < 96; itemIndex++)
+ {
+ IEntity item = m_Mode.Sites().DepotMagazine(site, itemIndex);
+ if (!m_Original.Contains(item) || m_Spent.Contains(item) || !ERR_GroundDepotTransfer.Magazine(item) || !Stored(item, site.Container)) continue;
+ // Match a real carried rifle; source camp stock cannot become arbitrary cargo.
+ if (!ERR_InfantryAmmoTransfer.Compatible(m_Worker, item)) continue;
+ int token = 300000 + m_Attempts + 1;
+ if (!m_HQ.ReserveGroundDepot(crew, donor, service, token)) continue;
+ m_Reservation = new ERR_FiniteMagazineReservation(m_Original, m_Spent, item);
+ if (!m_Reservation.Reserve()) { m_HQ.ReleaseGroundDepot(crew, donor, truck, token); continue; }
+ m_Attempts++; m_Token = token; m_Crew = crew; m_Donor = donor; m_Service = service; m_Task = service.Task(); m_Truck = truck;
+ m_Site = site; m_Cache = site.Container; m_CachePosition = m_Cache.GetOrigin(); m_Item = item;
+ m_CacheInventory = InventoryStorageManagerComponent.Cast(m_Cache.FindComponent(InventoryStorageManagerComponent));
+ m_CrewRecord = m_Mode.Forces().FindGroup(crew.Group);
+ m_PickedUp = false; m_DeliveryClaimed = false; m_Imported = false; m_HeldAt = -1;
+ m_Deadline = Math.Min(now + 180000, report.ObservedAt + 240000); m_State = 1;
+ m_Order = m_HQ.Downlink(donor.Group, "DEPOT HOLD", "hold original truck for one finite camp magazine", report.MessageId);
+ if (!m_Order) Abort("truck radio unavailable"); else Note("one original camp item reserved; awaiting truck hold radio");
+ return;
+ }
+ }
+ }
+ }
+ protected void ClearAction()
+ {
+ if (m_Action && m_Worker && m_Utility && m_Utility.m_AIInfo)
+ {
+ SCR_ChimeraAIAgent agent = SCR_ChimeraAIAgent.Cast(SCR_AIUtils.GetAIAgent(m_Worker));
+ if (agent && agent.m_UtilityComponent == m_Utility)
+ {
+ array<ref AIActionBase> actions = {}; m_Utility.GetActions(actions);
+ if (actions.Count() <= 128 && actions.Contains(m_Action)) m_Action.Complete();
+ }
+ }
+ m_Action = null;
+ }
+ protected bool Walk(vector position)
+ {
+ if (!WorkerValid() || !ERR_ForceRules.FiniteVector(position)) return false;
+ ClearAction(); m_Action = new SCR_AIMoveIndividuallyBehavior(m_Utility, null, ERR_Actors.Ground(position), 1000, 0, null, 0.5);
+ m_Utility.AddAction(m_Action); return true;
+ }
+ protected void Cleanup()
+ {
+ ClearAction();
+ if (m_Reservation) m_Reservation.ReleaseUnsubmitted();
+ if (m_HQ) m_HQ.ReleaseGroundDepot(m_Crew, m_Donor, m_Truck, m_Token);
+ m_State = 0; m_Token = 0; m_Order = null; m_Move = null; m_Reservation = null;
+ m_Crew = null; m_Donor = null; m_Service = null; m_Task = null; m_Truck = null;
+ m_Worker = null; m_Utility = null; m_Site = null; m_Cache = null; m_Item = null; m_CacheInventory = null; m_CrewRecord = null;
+ }
+ protected void Abort(string reason)
+ {
+ Note(reason); ClearAction(); m_Order = null;
+ if (m_Move) m_Move.Stop();
+ if (Unresolved()) { m_State = 7; return; }
+ Cleanup();
+ }
+ void Stop() { if (m_Stopped) return; m_Stopped = true; Abort("depot service stopped; any submitted uncertainty retains original claims"); }
+ bool TransferValid(ERR_GroundDepotTransfer operation)
+ {
+ if (!operation || operation != m_Move || operation.Item() != m_Item || !Valid() || !Stationary() || !m_Truck.SupplyHeld) return false;
+ if (operation.Delivery()) return m_PickedUp && m_State == 5 && ERR_GroundDepotAccess.Clear(m_Truck.Entity, m_Worker);
+ return !m_PickedUp && m_State == 4 && ERR_GroundDepotAccess.Clear(m_Cache, m_Worker);
+ }
+ bool ClaimDelivery(ERR_GroundDepotTransfer operation)
+ {
+ if (!TransferValid(operation) || !operation.Delivery() || m_DeliveryClaimed || !m_Reservation.CommittedFor(m_Item)) return false;
+ m_DeliveryClaimed = true; return true;
+ }
+ bool DeliveredTo(ERR_InfantryResupply service, IEntity item)
+ {
+ return !m_Imported && m_State == 5 && service == m_Service && item == m_Item && m_Move && m_Move.Delivery()
+ && m_Move.Confirmed() && m_Reservation && m_Reservation.CommittedFor(item) && Valid();
+ }
+ void Tick(float now)
+ {
+ // Terminal proof only: a late callback cannot resume walking or admit stock.
+ if (m_State == 7) { if (!Unresolved()) Cleanup(); return; }
+ if (!Busy()) return;
+ if (!ERR_ForceRules.Finite(now) || now < m_Last || now >= m_Deadline || !Valid()) { Abort("depot deadline or original ownership lost"); return; }
+ m_Last = now;
+ if (now < m_NextTick) return;
+ m_NextTick = now + 1000;
+ if (m_State == 1 || m_State == 3)
+ {
+ int result = m_Order.Advance(now, m_HQ.Journal());
+ if (result == 0) return;
+ if (result < 0) { Abort("depot radio interrupted"); return; }
+ m_Order = null;
+ if (m_State == 1) { m_Truck.SupplyHeld = true; m_Truck.ClearOrder(); m_State = 2; return; }
+ if (!Walk(m_CachePosition + "2 0 0")) { Abort("original porter cannot walk to camp cache"); return; }
+ m_State = 4; return;
+ }
+ if (m_State == 2)
+ {
+ if (!Stationary()) return;
+ if (m_HeldAt < 0) { m_HeldAt = now; m_Donor.NextStatus = now; return; }
+ ERR_HQWatchEntry report = m_HQ.Watch().Find(m_Donor.ForceSourceId);
+ if (!ERR_InfantryResupplyRules.Fresh(report, now) || report.ObservedAt < m_HeldAt) return;
+ if (vector.DistanceXZ(report.Position, m_Site.Definition.Position) > 150) { Abort("reported stopped truck outside camp service range"); return; }
+ m_TruckPosition = report.Position + "3 0 0";
+ m_Order = m_HQ.Downlink(m_Crew.Group, "DEPOT COURIER", string.Format("carry one existing magazine from camp to stopped truck at %1", m_TruckPosition), report.MessageId);
+ if (!m_Order) { Abort("porter radio unavailable"); return; }
+ m_State = 3; return;
+ }
+ if (m_State == 6)
+ {
+ if (vector.DistanceXZ(m_Worker.GetOrigin(), m_CachePosition) <= 5
+ && vector.DistanceXZ(m_Worker.GetOrigin(), m_Truck.Entity.GetOrigin()) >= 6) Cleanup();
+ return;
+ }
+ if (!Stationary()) { Abort("held truck moved during physical loading"); return; }
+ if (!m_Move)
+ {
+ IEntity source = m_Cache; IEntity destination = m_Worker;
+ bool delivery = m_State == 5;
+ if (delivery) { source = m_Worker; destination = m_Truck.Entity; }
+ IEntity access = m_Cache; if (delivery) access = m_Truck.Entity;
+ if (!ERR_GroundDepotAccess.Clear(access, m_Worker)) return;
+ m_Move = new ERR_GroundDepotTransfer(this, source, destination, m_Item, m_Reservation, delivery);
+ }
+ int moved = m_Move.Tick(now);
+ if (moved == 0) return;
+ if (moved < 0) { Abort("native depot move refused, changed or expired; no submitted retry"); return; }
+ if (m_State == 4)
+ {
+ m_PickedUp = true; m_Move = null; // Retire first-leg proof before custody changes again.
+ if (!Walk(m_TruckPosition)) { Abort("porter cannot walk to reported truck"); return; }
+ m_State = 5; return;
+ }
+ if (!m_Service.AdmitDepot(this, m_Item)) { Abort("proved physical delivery could not enter finite truck allowance"); return; }
+ m_Imported = true; m_Delivered++; m_Move = null;
+ Note("one original camp magazine physically delivered and admitted; porter returning to camp");
+ if (!Walk(m_CachePosition + "2 0 0")) { Cleanup(); return; }
+ m_State = 6;
+ }
+}
--- /dev/null
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotTransfer.c
@@ -0,0 +1,137 @@
+class ERR_GroundDepotCallback : ScriptedInventoryOperationCallback
+{
+ ERR_GroundDepotTransfer Transfer;
+ protected override void OnComplete() { if (Transfer) Transfer.Acknowledge(true); }
+ protected override void OnAllComplete() { if (Transfer) Transfer.Acknowledge(true); }
+ protected override void OnFailed() { if (Transfer) Transfer.Acknowledge(false); }
+ protected override void OnAllFailed() { if (Transfer) Transfer.Acknowledge(false); }
+}
+
+// One exact native move. Its owner retains the leaf until uncertain custody
+// settles; pickup and delivery never share callback state.
+class ERR_GroundDepotTransfer
+{
+ protected ERR_GroundDepotLoading m_Owner;
+ protected IEntity m_From;
+ protected IEntity m_To;
+ protected IEntity m_Item;
+ protected InventoryStorageManagerComponent m_Source;
+ protected InventoryStorageManagerComponent m_Destination;
+ protected InventoryStorageSlot m_FromSlot;
+ protected BaseInventoryStorageComponent m_FromStorage;
+ protected BaseInventoryStorageComponent m_ToStorage;
+ protected ref ERR_FiniteMagazineReservation m_Reservation;
+ protected ref ERR_GroundDepotCallback m_Callback;
+ protected bool m_Delivery;
+ protected bool m_Submitted;
+ protected int m_Ack;
+ protected int m_State;
+ protected int m_Rounds;
+ protected int m_Capacity;
+ protected float m_Started = -1;
+ protected float m_Last = -1;
+ void ERR_GroundDepotTransfer(ERR_GroundDepotLoading owner, IEntity source, IEntity destination, IEntity item, ERR_FiniteMagazineReservation reservation, bool delivery)
+ {
+ m_Owner = owner; m_From = source; m_To = destination; m_Item = item; m_Reservation = reservation; m_Delivery = delivery;
+ if (!source || !destination || !item) return;
+ m_Source = InventoryStorageManagerComponent.Cast(source.FindComponent(InventoryStorageManagerComponent));
+ m_Destination = InventoryStorageManagerComponent.Cast(destination.FindComponent(InventoryStorageManagerComponent));
+ InventoryItemComponent inventoryItem = InventoryItemComponent.Cast(item.FindComponent(InventoryItemComponent));
+ if (inventoryItem) m_FromSlot = inventoryItem.GetParentSlot();
+ if (m_FromSlot) m_FromStorage = m_FromSlot.GetStorage();
+ BaseMagazineComponent magazine = BaseMagazineComponent.Cast(item.FindComponent(BaseMagazineComponent));
+ if (magazine) { m_Rounds = magazine.GetAmmoCount(); m_Capacity = magazine.GetMaxAmmoCount(); }
+ }
+ static bool Magazine(IEntity item)
+ {
+ if (!item) return false;
+ DamageManagerComponent damage = DamageManagerComponent.Cast(item.FindComponent(DamageManagerComponent));
+ if (damage && damage.IsDestroyed()) return false;
+ BaseMagazineComponent magazine = BaseMagazineComponent.Cast(item.FindComponent(BaseMagazineComponent));
+ return magazine && !magazine.IsUsed() && magazine.GetMagazineWell() && magazine.GetAmmoCount() > 0
+ && magazine.GetAmmoCount() <= magazine.GetMaxAmmoCount() && magazine.GetMaxAmmoCount() <= 100000;
+ }
+ bool Submitted() { return m_Submitted; }
+ bool Delivery() { return m_Delivery; }
+ IEntity Item() { return m_Item; }
+ void Acknowledge(bool success)
+ {
+ if (!m_Submitted) return;
+ if (!success) m_Ack = -1;
+ else if (m_Ack == 0) m_Ack = 1;
+ }
+ protected bool Managed(InventoryStorageManagerComponent inventory, BaseInventoryStorageComponent storage, IEntity owner)
+ {
+ if (!inventory || !storage || !owner || inventory.GetOwner() != owner) return false;
+ if (!ERR_InfantryAmmoTransfer.StoredUnder(storage.GetOwner(), owner)) return false;
+ array<BaseInventoryStorageComponent> storages = {}; inventory.GetStorages(storages, EStoragePurpose.PURPOSE_DEPOSIT);
+ return storages.Count() <= 64 && storages.Contains(storage);
+ }
+ protected int Contains(InventoryStorageManagerComponent inventory)
+ {
+ if (!inventory || !m_Item) return -1;
+ array<IEntity> items = {}; inventory.GetItems(items, EStoragePurpose.PURPOSE_DEPOSIT);
+ if (items.Count() > 128) return -1;
+ if (items.Contains(m_Item)) return 1;
+ return 0;
+ }
+ protected bool Slot(InventoryStorageSlot slot)
+ {
+ if (!m_Item || !slot || slot.GetAttachedEntity() != m_Item) return false;
+ InventoryItemComponent item = InventoryItemComponent.Cast(m_Item.FindComponent(InventoryItemComponent));
+ return item && item.GetParentSlot() == slot;
+ }
+ protected bool OriginalProof()
+ {
+ return m_FromSlot && m_FromSlot.GetStorage() == m_FromStorage && Managed(m_Source, m_FromStorage, m_From)
+ && Slot(m_FromSlot) && m_Destination && m_Destination.GetOwner() == m_To
+ && Contains(m_Source) == 1 && Contains(m_Destination) == 0;
+ }
+ bool PhysicalProof()
+ {
+ if (!m_Item || !m_Source || !m_From || m_Source.GetOwner() != m_From) return false;
+ if (!Managed(m_Destination, m_ToStorage, m_To) || Contains(m_Source) != 0 || Contains(m_Destination) != 1) return false;
+ InventoryItemComponent item = InventoryItemComponent.Cast(m_Item.FindComponent(InventoryItemComponent));
+ return item && item.GetParentSlot() && item.GetParentSlot().GetStorage() == m_ToStorage && Slot(item.GetParentSlot());
+ }
+ bool Unresolved()
+ {
+ if (!m_Submitted || !m_Item) return false;
+ if (m_Ack == 1 && PhysicalProof()) return false;
+ if (m_Ack < 0 && OriginalProof()) return false;
+ return true;
+ }
+ void Stop() { if (m_State == 0) m_State = -1; }
+ bool Confirmed() { return m_State == 1 && m_Ack == 1 && PhysicalProof(); }
+ int Tick(float now)
+ {
+ if (m_State != 0) return m_State;
+ if (!ERR_ForceRules.Finite(now) || now < 0 || now < m_Last) { Stop(); return m_State; }
+ if (m_Started < 0) m_Started = now;
+ m_Last = now;
+ if (now - m_Started >= 8000 || !m_Owner || !m_Owner.TransferValid(this) || !Magazine(m_Item)) { Stop(); return m_State; }
+ if (!m_From || !m_To || m_From.FindComponent(InventoryStorageManagerComponent) != m_Source
+ || m_To.FindComponent(InventoryStorageManagerComponent) != m_Destination) { Stop(); return m_State; }
+ BaseMagazineComponent magazine = BaseMagazineComponent.Cast(m_Item.FindComponent(BaseMagazineComponent));
+ if (magazine.GetAmmoCount() != m_Rounds || magazine.GetMaxAmmoCount() != m_Capacity) { Stop(); return m_State; }
+ if (!m_Submitted)
+ {
+ if (!m_Reservation || !OriginalProof()) { Stop(); return m_State; }
+ m_ToStorage = m_Destination.FindStorageForItem(m_Item, EStoragePurpose.PURPOSE_DEPOSIT);
+ if (!Managed(m_Destination, m_ToStorage, m_To) || !m_Source.CanMoveItemToStorage(m_Item, m_ToStorage, -1)) { Stop(); return m_State; }
+ if (!m_Delivery && !m_Reservation.Commit()) { Stop(); return m_State; }
+ if (!m_Reservation.CommittedFor(m_Item)) { Stop(); return m_State; }
+ if (m_Delivery && !m_Owner.ClaimDelivery(this)) { Stop(); return m_State; }
+ m_Callback = new ERR_GroundDepotCallback(); m_Callback.Transfer = this;
+ m_Submitted = true;
+ bool accepted = m_Source.TryMoveItemToStorage(m_Item, m_ToStorage, -1, m_Callback);
+ if (!accepted && m_Ack != 1) { Stop(); return m_State; }
+ }
+ // Native callbacks may synchronously cancel the owner or this exact leaf.
+ if (m_State != 0) return m_State;
+ if (!m_Owner || !m_Owner.TransferValid(this)) { Stop(); return m_State; }
+ if (m_Ack < 0) { Stop(); return m_State; }
+ if (m_Ack == 1 && PhysicalProof()) m_State = 1;
+ return m_State;
+ }
+}
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c
@@ -102,6 +102,32 @@
int Delivered() { return m_Delivered; }
int MinesDelivered() { return m_MinesDelivered; }
int StockCount() { return m_Stock.Count(); }
+ // Admission uses the existing array object so an already-created mounted
+ // coordinator observes this exact finite addition without a replacement ledger.
+ protected int m_DepotImports;
+ bool DepotCurrent()
+ {
+ return Current() && m_State == 1 && !m_Move && !m_MineMove && !Unresolved()
+ && (!m_Mounted || !m_Mounted.Busy()) && TruckValid(true);
+ }
+ bool DepotAvailable() { return DepotCurrent() && m_Stock.Count() < 96 && m_Spent.Count() < 96; }
+ bool DepotNeeded()
+ {
+ if (!DepotAvailable()) return false;
+ int committed;
+ foreach (IEntity item : m_Spent)
+ if (item && m_Stock.Contains(item)) committed++;
+ return committed > m_DepotImports;
+ }
+ ERR_ConvoyVehicle DepotTruck() { if (!DepotCurrent()) return null; return m_Truck; }
+ bool AdmitDepot(ERR_GroundDepotLoading job, IEntity item)
+ {
+ if (!job || !DepotAvailable() || !item || m_Stock.Contains(item) || m_Spent.Contains(item)) return false;
+ if (!job.DeliveredTo(this, item) || !Contains(m_Truck.Entity, item)) return false;
+ m_Stock.Insert(item); m_DepotImports++; Audit("one exact finite camp magazine admitted after proved physical courier delivery");
+ return true;
+ }
+
protected void Audit(string reason)
{
if (m_MineTrip) reason = "mine top-up: " + reason;
--- /dev/null
+++ b/tests/test_ground_depot_lifecycle.py
@@ -0,0 +1,40 @@
+"""Execute actual modded HQ owner gates, priority order, Stop and terminal polling."""
+import os,re
+from pathlib import Path
+from policy_harness import ROOT,body,run
+base=Path(os.environ.get('ERR_DEPOT_ROOT',ROOT))
+p=base/'addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotHQ.c'
+def cpp(s):
+ s=s.replace('protected ','').replace('override ','').replace('super.','Base::').replace('this)', 'this)')
+ for n in ('m_Mode','m_GroundDepot'):s=s.replace(n+'.',n+'->')
+ s=s.replace('Replication.IsServer()', 'server').replace('ERR_GameMode.Get()', 'current')
+ s=s.replace('ERR_Phase.RADIO_SEARCH','2').replace('GetGame().','GetGame()->').replace('GetCallqueue().','GetCallqueue()->').replace('GetWorld().','GetWorld()->')
+ s=s.replace('Remove(PollGroundDepot)', 'Remove(0)').replace('CallLater(PollGroundDepot, 1000, false)', 'CallLater(0, 1000, false)')
+ return s
+methods='\n'.join(cpp(body(p,t)) for t in ('override void Tick(', 'override void Stop(', 'protected void CancelGroundDepotPoll(', 'protected void PollGroundDepot('))
+run(r'''
+#include <cassert>
+#include <vector>
+std::vector<int> events;bool server=true;struct HQ;
+struct Mode{HQ*owner=nullptr;bool active=true;int phase=2;bool Active(){return active;}int Phase(){return phase;}HQ*Command(){return owner;}};Mode*current=nullptr;
+struct Queue{int pending=0,calls=0;void Remove(int){pending=0;}void CallLater(int,int ms,bool repeat){assert(ms==1000&&!repeat);pending=1;calls++;}};
+struct World{float GetWorldTime(){return 500;}};struct Game{Queue queue;World world;Queue*GetCallqueue(){return &queue;}World*GetWorld(){return &world;}};Game game;Game*GetGame(){return &game;}
+struct ERR_GroundDepotLoading{static inline int created=0;bool stopped=false,unknown=false;int plans=0,ticks=0;ERR_GroundDepotLoading(HQ*,Mode*){created++;}void Tick(float){ticks++;events.push_back(3);}void Plan(float){assert(!stopped);plans++;events.push_back(4);}void Stop(){stopped=true;events.push_back(1);}bool Unresolved(){return unknown;}};
+struct Base{bool m_Stopping=false;void Tick(float){events.push_back(2);}void Stop(){events.push_back(2);m_Stopping=true;}};
+struct HQ:Base{Mode*m_Mode=nullptr;ERR_GroundDepotLoading*m_GroundDepot=nullptr;METHODS};
+struct F{HQ h;Mode mode;F(){server=true;game.queue={};current=&mode;mode.owner=&h;h.m_Mode=&mode;events.clear();}};
+int main(){
+ {F f;server=false;f.h.Tick(0);assert(!f.h.m_GroundDepot&&events==std::vector<int>{2});}
+ {F f;current=nullptr;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
+ {F f;f.mode.owner=nullptr;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
+ {F f;f.mode.active=false;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
+ {F f;f.mode.phase=1;f.h.Tick(0);assert(!f.h.m_GroundDepot);}
+ {F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;assert(d&&d->plans==1&&events==std::vector<int>({2,4}));events.clear();f.h.Tick(1);assert(f.h.m_GroundDepot==d&&events==std::vector<int>({2,3,4}));}
+ {F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;events.clear();f.h.Stop();assert(d->stopped&&events==std::vector<int>({1,2,3})&&game.queue.pending==1);int plans=d->plans;f.h.Stop();assert(game.queue.pending==1&&d->plans==plans);d->unknown=false;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->plans==plans);}
+ {F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;f.h.Stop();int ticks=d->ticks;f.mode.owner=nullptr;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->ticks==ticks);}
+ {F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;f.h.Stop();int ticks=d->ticks;server=false;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->ticks==ticks);}
+ {F f;f.h.Tick(0);auto*d=f.h.m_GroundDepot;d->unknown=true;f.h.Stop();int ticks=d->ticks;current=nullptr;f.h.PollGroundDepot();assert(game.queue.pending==0&&d->ticks==ticks);}
+}
+'''.replace('METHODS',methods))
+assert 'void ~ERR_HQ() { CancelGroundDepotPoll(); }' in p.read_text()
+print('PASS: actual depot HQ lifecycle, existing planner priority, server/mode/owner gates, idempotent polling and owner replacement')
--- /dev/null
+++ b/tests/test_ground_depot_loading.py
@@ -0,0 +1,102 @@
+"""Actual depot planner/state transitions and final finite import; native boundaries doubled."""
+import os,re
+from pathlib import Path
+from policy_harness import ROOT,body,run
+BASE=Path(os.environ.get('ERR_DEPOT_ROOT',ROOT))
+P=BASE/'addons/core/Scripts/Game/ERR/10_AI/ERR_GroundDepotLoading.c'
+S=BASE/'addons/core/Scripts/Game/ERR/10_AI/ERR_InfantryResupply.c'
+source=P.read_text()
+valid=body(P,'protected bool Valid(')
+assert 'm_Service.DepotCurrent()' in valid and 'DepotAvailable()' not in valid and 'DepotNeeded()' not in valid
+for forbidden in ('Teleport(', 'TrySpawn', 'SetAmmoCount', 'SetOrigin(', 'SetTransform('):assert forbidden not in source
+
+def cpp(s):
+ s=s.replace('protected ','').replace('ref ','').replace('null','nullptr')
+ for t in ('ERR_HQUnit','ERR_InfantryResupply','ERR_ConvoyVehicle','ERR_HQWatchEntry','ERR_SiteRuntime','ERR_GroundDepotTransfer','ERR_GroundDepotLoading','ERR_FiniteMagazineReservation'):
+ s=re.sub(r'\b'+t+r' (\w+)',t+r'* \1',s)
+ s=s.replace('ERR_FiniteMagazineReservation(m_Original, m_Spent, item)','ERR_FiniteMagazineReservation(&m_Original, &m_Spent, item)')
+ for ns in ('ERR_ForceRules','ERR_InfantryResupplyRules','ERR_GroundDepotTransfer','ERR_InfantryAmmoTransfer','ERR_GroundDepotAccess','Math'):
+ s=s.replace(ns+'.',ns+'::')
+ for n in ('m_HQ','m_Mode','m_Service','m_Move','m_Reservation','m_Order','m_Truck','m_Crew','m_Donor','m_Worker','m_Site','m_Cache','service','truck','donor','report','site','crew','operation'):
+ s=re.sub(r'\b'+n+r'\.',n+'->',s)
+ s=s.replace('Sites().','Sites()->').replace('Watch().','Watch()->').replace('Forces().','Forces()->')
+ s=s.replace('site->Responders.Group','site->Responders->Group').replace('site->Definition.Position','site->Definition->Position').replace('m_Site->Definition.Position','m_Site->Definition->Position')
+ s=s.replace('m_Truck->Entity.GetOrigin()', 'm_Truck->Entity->GetOrigin()')
+ s=s.replace('vector.DistanceXZ','Vec::DistanceXZ').replace('string.Format','Format')
+ s=s.replace('InventoryStorageManagerComponent.Cast(m_Cache->FindComponent(InventoryStorageManagerComponent))','m_Cache->inventory')
+ s=s.replace('"3 0 0"','Vec{3}').replace('"2 0 0"','Vec{2}')
+ return s
+methods='\n'.join(cpp(body(P,x)) for x in ('void Plan(', 'void Tick(', 'protected void Abort(', 'void Stop(', 'bool TransferValid(', 'bool ClaimDelivery(', 'bool DeliveredTo('))
+admit=cpp(body(S,'bool AdmitDepot(')).replace('job.','job->').replace('m_Stock.Insert(item); Audit(', 'm_Stock.Insert(item); Audit(')
+run(r'''
+#include <cassert>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cmath>
+using string=std::string;
+template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}bool Contains(T v){return std::find(this->begin(),this->end(),v)!=this->end();}void Insert(T v){this->push_back(v);}void RemoveItem(T v){this->erase(std::remove(this->begin(),this->end(),v),this->end());}};
+struct Vec{float x=0;Vec operator+(Vec b){return {x+b.x};}static float DistanceXZ(Vec a,Vec b){return std::abs(a.x-b.x);}};
+template<class...T>string Format(string s,T...){return s;}
+struct ERR_ForceRules{static bool Finite(float f){return std::isfinite(f);}};
+struct Math{static float Min(float a,float b){return std::min(a,b);}};
+struct Group{};struct Inventory{};struct Entity{Vec pos;Inventory*inventory=nullptr;bool stock=true,compatible=true;Vec GetOrigin(){return pos;}};using IEntity=Entity*;
+struct Definition{Vec Position;};struct ERR_SiteRuntime{struct Definition*Definition=nullptr;ERR_SiteRuntime*Responders=nullptr;struct Group*Group=nullptr;IEntity Container=nullptr;Array<IEntity>items;};
+struct Sites{Array<ERR_SiteRuntime*>sites;int Count(){return sites.Count();}ERR_SiteRuntime*At(int i){return sites[i];}int DepotMagazineCount(ERR_SiteRuntime*s){return s?s->items.Count():0;}IEntity DepotMagazine(ERR_SiteRuntime*s,int i){return s->items[i];}};
+struct ERR_HQUnit{struct Group*Group=nullptr;int ForceSourceId=0,LogisticsReservation=0;float NextStatus=0;bool eligible=true;};
+struct ERR_ConvoyTask{};
+struct ERR_ConvoyVehicle{struct Group*Group=nullptr;IEntity Entity=nullptr;int SupplyToken=0;bool SupplyHeld=false;int clears=0;void ClearOrder(){clears++;}};
+struct ERR_HQWatchEntry{int SourceId=2,MessageId=1;float ObservedAt=0;Vec Position;bool valid=true;};
+struct ERR_InfantryResupplyRules{static bool Fresh(ERR_HQWatchEntry*r,float n){return r&&r->valid&&n>=r->ObservedAt&&n-r->ObservedAt<=120000;}};
+struct Watch{ERR_HQWatchEntry report;ERR_HQWatchEntry*Find(int){return &report;}};
+struct Ledger{void*FindGroup(Group*){return this;}};
+struct Mode{struct Sites sites;Ledger ledger;struct Sites*Sites(){return &sites;}Ledger*Forces(){return &ledger;}};
+struct ERR_GroundDepotLoading;struct ERR_InfantryResupply;
+struct ERR_FiniteMagazineReservation{Array<IEntity>*original,*spent;IEntity item;bool committed=false,closed=false;ERR_FiniteMagazineReservation(Array<IEntity>*a,Array<IEntity>*b,IEntity i):original(a),spent(b),item(i){}bool Reserve(){if(!item||!original->Contains(item)||spent->Contains(item)||spent->Count()>=96)return false;spent->Insert(item);return true;}bool ReleaseUnsubmitted(){if(closed||committed)return false;closed=true;spent->RemoveItem(item);return true;}bool CommittedFor(IEntity i){return committed&&i==item&&spent->Contains(i);}};
+struct Route{int outcome=1,calls=0;int Advance(float,void*){calls++;return outcome;}};
+struct HQ{Array<ERR_InfantryResupply*>services;ERR_HQUnit*crew=nullptr,*donor=nullptr;struct Watch watch;Route route;bool claim=true,radio=true;int orders=0,releases=0,claims=0;
+ int GroundSupplyCount(){return services.Count();}ERR_InfantryResupply*GroundSupplyAt(int i){return services[i];}ERR_HQUnit*GroundUnit(Group*g){return crew&&crew->Group==g?crew:donor&&donor->Group==g?donor:nullptr;}struct Watch*Watch(){return &watch;}void*Journal(){return this;}
+ bool ReserveGroundDepot(ERR_HQUnit*,ERR_HQUnit*,ERR_InfantryResupply*,int);
+ void ReleaseGroundDepot(ERR_HQUnit*c,ERR_HQUnit*d,ERR_ConvoyVehicle*t,int token){releases++;if(c&&c->LogisticsReservation==token)c->LogisticsReservation=0;if(d&&d->LogisticsReservation==token)d->LogisticsReservation=0;if(t&&t->SupplyToken==token){t->SupplyToken=0;t->SupplyHeld=false;}}
+ Route*Downlink(Group*,string,string,int){orders++;return radio?&route:nullptr;}
+};
+struct ERR_InfantryAmmoTransfer{static bool Compatible(IEntity a,IEntity i){return a&&i&&i->compatible;}};
+struct ERR_GroundDepotAccess{static inline bool clear=true;static bool Clear(IEntity,IEntity){return clear;}};
+struct ERR_GroundDepotTransfer{static inline int constructed=0;bool delivery=false,submitted=true,unknown=true,confirmed=false;int result=0;IEntity item;ERR_FiniteMagazineReservation*r;
+ ERR_GroundDepotTransfer(ERR_GroundDepotLoading*,IEntity,IEntity,IEntity i,ERR_FiniteMagazineReservation*q,bool d):delivery(d),item(i),r(q){constructed++;r->committed=true;}
+ static bool Magazine(IEntity i){return i&&i->stock;}bool Delivery(){return delivery;}IEntity Item(){return item;}bool Unresolved(){return submitted&&unknown;}bool Confirmed(){return confirmed;}void Stop(){result=-1;}int Tick(float){return result;}
+};
+struct ERR_InfantryResupply{bool available=true,needed=true;int m_DepotImports=0;ERR_ConvoyVehicle*truck=nullptr;ERR_ConvoyTask task;Array<IEntity>m_Stock,m_Spent;ERR_ConvoyVehicle*m_Truck=nullptr;
+ bool DepotAvailable(){return available&&m_Stock.Count()<96;}bool DepotNeeded(){return DepotAvailable()&&needed;}ERR_ConvoyVehicle*DepotTruck(){return available?truck:nullptr;}ERR_ConvoyTask*Task(){return &task;}bool Contains(IEntity,IEntity i){return i!=nullptr;}void Audit(string){}bool AdmitDepot(ERR_GroundDepotLoading*,IEntity);
+};
+struct ERR_GroundDepotLoading{HQ*m_HQ;Mode*m_Mode;Array<IEntity>m_Original,m_Spent;bool active=true,valid=true,stationary=true,canWalk=true,m_Stopped=false,m_Captured=false,m_PickedUp=false,m_DeliveryClaimed=false,m_Imported=false;int m_State=0,m_Attempts=0,m_Delivered=0,m_Token=0,m_WorkerSlot=0,walks=0,cleanups=0,notes=0;float m_NextPlan=0,m_Deadline=0,m_Last=-1,m_NextTick=0,m_HeldAt=-1;Vec m_CachePosition,m_TruckPosition;
+ ERR_HQUnit*m_Crew=nullptr,*m_Donor=nullptr;ERR_SiteRuntime*m_Site=nullptr;IEntity m_Worker=nullptr,m_Cache=nullptr,m_Item=nullptr;Inventory*m_CacheInventory=nullptr;void*m_CrewRecord=nullptr;ERR_InfantryResupply*m_Service=nullptr;ERR_ConvoyTask*m_Task=nullptr;ERR_ConvoyVehicle*m_Truck=nullptr;Route*m_Order=nullptr;ERR_GroundDepotTransfer*m_Move=nullptr;ERR_FiniteMagazineReservation*m_Reservation=nullptr;
+ bool Active(){return active&&!m_Stopped;}bool Busy(){return m_State!=0;}bool Unresolved(){return m_Move&&m_Move->Unresolved();}bool Valid(){return Active()&&valid&&(!m_Service||m_Service->available);}bool Stationary(){return stationary;}bool Quiet(ERR_HQUnit*u){return u&&u->eligible;}bool SelectWorker(ERR_HQUnit*u){return Quiet(u)&&u->LogisticsReservation==0;}bool Stored(IEntity,IEntity){return true;}void Capture(){m_Captured=true;}void Note(string){notes++;}void ClearAction(){}bool Walk(Vec){walks++;return canWalk;}
+ void Cleanup(){cleanups++;if(m_Reservation)m_Reservation->ReleaseUnsubmitted();m_HQ->ReleaseGroundDepot(m_Crew,m_Donor,m_Truck,m_Token);m_State=0;m_Token=0;m_Move=nullptr;m_Order=nullptr;}
+ METHODS
+};
+ADMISSION
+bool HQ::ReserveGroundDepot(ERR_HQUnit*c,ERR_HQUnit*d,ERR_InfantryResupply*s,int token){if(!claim||c->LogisticsReservation||d->LogisticsReservation||s->truck->SupplyToken)return false;claims++;c->LogisticsReservation=d->LogisticsReservation=s->truck->SupplyToken=token;return true;}
+struct F{Mode mode;HQ hq;ERR_GroundDepotLoading job;Group cg,dg;ERR_HQUnit crew,donor;Definition def;ERR_SiteRuntime site,responders;Entity worker,cache,truck,item;Inventory inv;ERR_ConvoyVehicle vehicle;ERR_InfantryResupply service;
+ F(){truck.pos={20};crew.Group=&cg;donor.Group=&dg;hq.crew=&crew;hq.donor=&donor;vehicle.Group=&dg;vehicle.Entity=&truck;service.truck=service.m_Truck=&vehicle;hq.services={&service};site.Definition=&def;site.Responders=&responders;responders.Group=&cg;site.Container=&cache;site.items={&item};cache.inventory=&inv;mode.sites.sites={&site};job.m_HQ=&hq;job.m_Mode=&mode;job.m_Worker=&worker;job.m_Original={&item};ERR_GroundDepotAccess::clear=true;}
+ void Start(){job.Plan(0);assert(job.m_State==1&&hq.claims==1&&hq.orders==1);}
+ void Reach(){Start();job.Tick(0);assert(job.m_State==2&&vehicle.SupplyHeld&&vehicle.clears==1);job.Tick(1000);assert(donor.NextStatus==1000&&job.walks==0);job.Tick(2000);assert(job.m_State==2);hq.watch.report.ObservedAt=3000;job.Tick(3000);assert(job.m_State==3&&hq.orders==2&&job.walks==0);job.Tick(4000);assert(job.m_State==4&&job.walks==1);}
+};
+int main(){
+ // No new stock or commands on missing capacity/camp/worker/report/claim.
+ for(int k=0;k<8;k++){F f;if(k==0)f.service.available=false;if(k==1)f.site.items.clear();if(k==2)f.crew.eligible=false;if(k==3)f.hq.watch.report.valid=false;if(k==4)f.hq.claim=false;if(k==5)f.item.compatible=false;if(k==6)f.job.m_Original.clear();if(k==7)f.service.needed=false;f.job.Plan(0);assert(!f.job.Busy()&&f.hq.orders==0&&f.job.m_Spent.empty());}
+ {F f;f.Start();f.hq.route.outcome=-1;f.job.Tick(0);assert(!f.job.Busy()&&f.job.walks==0&&!f.vehicle.SupplyHeld&&f.job.m_Spent.empty());}
+ // Complete actual state sequence; first proof retires before delivery callback.
+ {F f;f.Reach();f.job.Tick(5000);auto*pickup=f.job.m_Move;assert(pickup&&!pickup->Delivery());pickup->unknown=false;pickup->confirmed=true;pickup->result=1;f.job.Tick(6000);assert(f.job.m_State==5&&!f.job.m_Move&&f.job.walks==2);f.job.Tick(7000);auto*delivery=f.job.m_Move;assert(delivery&&delivery!=pickup&&delivery->Delivery());delivery->unknown=false;delivery->confirmed=true;delivery->result=1;f.job.Tick(8000);assert(f.service.m_Stock.Count()==1&&f.job.m_Delivered==1&&f.job.m_State==6);f.job.Tick(9000);assert(!f.job.Busy()&&!f.vehicle.SupplyHeld&&f.job.m_Spent.Count()==1);}
+ for(bool second:{false,true}){F f;f.Reach();f.job.Tick(5000);if(second){f.job.m_Move->unknown=false;f.job.m_Move->result=1;f.job.Tick(6000);f.job.Tick(7000);}auto*leaf=f.job.m_Move;int walks=f.job.walks;f.job.Stop();assert(f.job.m_State==7&&f.vehicle.SupplyHeld&&f.crew.LogisticsReservation>0);f.job.Tick(200000);assert(f.job.m_State==7&&f.service.m_Stock.empty()&&f.job.walks==walks);leaf->unknown=false;leaf->confirmed=true;f.job.Tick(200001);assert(!f.job.Busy()&&f.service.m_Stock.empty()&&f.job.m_Spent.Count()==1&&!f.vehicle.SupplyHeld);f.job.Plan(300000);assert(!f.job.Busy());}
+ // Expiry never extends the job; late proof does not adopt cargo.
+ {F f;f.Reach();f.job.Tick(5000);f.job.Tick(f.job.m_Deadline);assert(f.job.m_State==7);f.job.m_Move->unknown=false;f.job.Tick(999999);assert(!f.job.Busy()&&f.service.m_Stock.empty());}
+ // Target lifetime96 allowance: no eviction of spent/deleted identities.
+ {F f;f.service.m_Stock.resize(96,nullptr);f.job.Plan(0);assert(!f.job.Busy()&&f.hq.orders==0);}
+ // Filling the final lifetime slot does not invalidate the return phase.
+ {F f;f.service.m_Stock.resize(95,nullptr);f.Reach();f.job.Tick(5000);f.job.m_Move->unknown=false;f.job.m_Move->result=1;f.job.Tick(6000);f.job.Tick(7000);f.job.m_Move->unknown=false;f.job.m_Move->confirmed=true;f.job.m_Move->result=1;f.job.Tick(8000);assert(f.service.m_Stock.Count()==96&&f.job.m_State==6);f.truck.pos={3};f.job.Tick(9000);assert(f.job.m_State==6&&f.vehicle.SupplyHeld);f.truck.pos={20};f.job.Tick(10000);assert(!f.job.Busy());}
+ // A completed physical move cannot import wrong/previously-spent/foreign identity.
+ {F f;f.Reach();f.job.Tick(5000);auto*l=f.job.m_Move;l->unknown=false;l->result=1;f.job.Tick(6000);f.job.Tick(7000);f.job.m_Move->unknown=false;f.job.m_Move->confirmed=true;Entity foreign;assert(!f.service.AdmitDepot(&f.job,&foreign));f.service.m_Spent.Insert(&f.item);assert(!f.service.AdmitDepot(&f.job,&f.item));}
+}
+'''.replace('METHODS',methods).replace('ADMISSION',admit.replace('bool AdmitDepot(', 'bool ERR_InfantryResupply::AdmitDepot(')))
+print('PASS: actual depot radio/planning/two-leg state transitions, fixed deadline, late proof quarantine, finite import and no adoption after Stop')
@@ -0,0 +1 @@
PASS: actual authored identity capture, READY-only detached provenance, same shared stock admission, completed exact two-leg proof, lifetime caps and Stop no late adoption
@@ -0,0 +1,19 @@
check: /home/jakub/devel/escapistsrereintroduced/.build/death-diagnostic-2153/test-tmp/err-policy-4ct3p5cs/check.cpp:122: int main(): Assertion `f.sites.DepotOriginal(&f.site,&f.item)&&!f.sites.DepotOriginal(&f.site,&f.foreign)' failed.
Traceback (most recent call last):
File "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-leaf-review-0303/tests/test_ground_depot_provenance.py", line 22, in <module>
run(r'''
~~~^^^^^
#include <cassert>
^^^^^^^^^^^^^^^^^^
...<52 lines>...
}
^
''')
^^^^
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 '['/home/jakub/devel/escapistsrereintroduced/.build/death-diagnostic-2153/test-tmp/err-policy-4ct3p5cs/check']' died with <Signals.SIGABRT: 6>.
@@ -0,0 +1,279 @@
{
"test_native_maintenance_refuel.py": "15eb8c0ee75778fce2a1caace045940b63cd253f81d16a081f669643b9fefcae",
"test_mine_intel.py": "109d5c8532c3725ec3b42f7b0d769dfdf4eda5912a5d2409556c30f203cc6672",
"test_mine_intel_discovery_integration.py": "bac2c8ec269d6e51a46fc17893de4114a5613f37899a1e044a9132d97d44cc5a",
"test_infantry_combat.py": "03bc85811c52bd894ab8545794135227fc33b911a51f4e70d89fbeb2673de8ee",
"test_enemy_medicine.py": "d13ab1d4ebe81614e00a9a579c6bcc6bd5b2c608187458f414e47f47686d7ad0",
"test_hunter_combat.py": "240472940515795b205d5caf530392ce416e3e0d2b97e473bb935930f29287d6",
"test_hq_local_awareness.py": "00c8023f85e88ffc1113353836962c31e8e541a32c9b2f1f66b91eaff5b923af",
"test_unconscious_controls.py": "74d4008a5c02ad0087b55030c177c8320b7099c11b97a14d93acf0ad14941356",
"test_town_garrisons.py": "3674f713d7adc62ec9098f7923991c9f6b1d0edfc1431ccfd82fc8031ddae17f",
"test_field_sites.py": "fddb0e44e72fdfe32bb94347a14da64efbd2208e4f252754e80c620fbecda56c",
"test_gameplay_session_regressions.py": "d9968b06627ce10412e5b1165987de662385d5dcb29090c5626b90fb59df52f2",
"test_gameplay_review_fixes.py": "5f988d63ea4b2a8a364b181982ddd462baa628ab66e3a35d0fb5ea6f20c50b0b",
"test_server_log_regressions.py": "733084d7d2e33eb96740768c48d9e25bd7f3ffa9081949e38d0776c6822f5748",
"test_mortar_load_ack.py": "6eceee33969ec268d904f062bd1ac12ec4269cf87acd235469052b193b048774",
"test_hunter_profiles.py": "bdc7898666a7e1078ece35b5dc9bf903d2218843abb24addcea9353fe6b3f7f3",
"test_hunter_lifecycle.py": "c2e3bff077dcb4cc181cbae5526d38a8638be7b2187c72ed64b1e279b63cbafc",
"test_hunter_opening.py": "8d791372f465b6242a386d81b8e2136865390cbea5dfdcbfc6bb8b4f717c041d",
"test_enemy_awareness.py": "881289417a1e4af219546b113d018e9bc6a402a16cf4bfa7e983ab240f41c2aa",
"test_intel_body_inspection.py": "04dd19efafc796f349976d29df77cb71b95615e527ad9add4fceda1f6105fc94",
"test_body_recovery_lifecycle.py": "b4cc6df60863e12a16ac555ecb9818e318f6325cd989bc97d5bb6ed737857a73",
"test_air_support_policy.py": "bedd5437ba0667c371c390cb8c4fb5a3096e8ef6a71c8bac2091264b8d2eebf7",
"test_air_logistics_orders.py": "adf7181998f522f8825b71ef10955c9311aba9086e5bb601cfd47599baa46d8a",
"test_air_recon.py": "3b6ccb7b5bd60fe638f051094b96e2643c997280330ebfde0856f43a2e3ed3a0",
"test_scouts.py": "25c6bb1bcc9cb171d12cb1e59b5b278e256a7a4b257b5ce3a1d76d60d459bb59",
"test_mortar_station.py": "6570f18f787b7366ec5341da68dd99acf541cbbc31c6db7a9a3ae967506456ec",
"test_random_settings.py": "75fbcba53ff2331811fb91051bbae1b2c28108fa9477d98372e0eb057655f225",
"test_debug_ai.py": "7f4b847ba11e8da937eba7be3c4c0ab898b44567f6f553ff842da54c1e7a85c2",
"test_generated_sites.py": "111095f40133b025ab67380b6cdcbc25ce0ecbc03379d1a015db6fdb0e5f2b25",
"test_terrain_sites.py": "c3534a7fb8fcbae887965c47300fbba3c00db5569fcddc3ad3d8c00e9aa2d2d0",
"test_terrain_adapter.py": "bcc6f469a12399f833651c591b3e1ca9a8e7f49d8b98e223a271fddc245bc4c4",
"test_terrain_airfields.py": "3a6e7151902657a38d8bf0510fb5c1a8049408d4f84d51ca260a0b5d651431e4",
"test_terrain_takeover.py": "5cb36e7faad13867620cae608e119988f84ab9970aa7b40fcd60fb7ec939a8dd",
"test_faction_selection.py": "77e4789499b3560e729a115197c5b02d032c291ae1bd44b1cac5a2c2c476e450",
"test_faction_menu.py": "9e6381a4786487962358362b75a2287532a688ab27df756e84801e2bb6dc2e55",
"test_content_policy.py": "260eedd838802647af59f33a15510d2c721aa80a7540d54e47f22734041cb49e",
"test_hq_road_intercept.py": "ba4ce9af49acdbf5c0c04b849761ea36abe2ec7d68ccde1f0cd731fb9e3ed451",
"test_hq_delivered_task.py": "076aecdb0ff0d614cadbffedf9d9f8cbb1383fb94a468bd92050b31251bcbce2",
"test_hq_local_handoff.py": "0fdbcac1958b0d12296753e7c9d92700079ea6c5c8e33d0e21e8318f997b79e7",
"test_hq_local_handoff_intake.py": "c51f0ca082456331eb5856bf6dad864c3852adc20beba9b6829bdef978b11d88",
"test_native_local_handoff_probe.py": "5a0904863ea00fd7ad262fcf91d8c1e55036b2041f16b043104f333c37d8c7ba",
"test_infantry_resupply_waypoints.py": "df3596515e0bb6a4cbf1e6f07d56755344415ad1deeffb8a70f71e8ed73a139e",
"test_infantry_placement_settle.py": "1490a797e016b99a222280f57875cc83096980022d1784495a80b8a406d400f7",
"test_native_infantry_fixture_lifecycle.py": "c20ed9dd152489a8242ec0b97135b0691c9c104783bb843b0715cdd8d7c2e156",
"test_native_infantry_cargo.py": "0d27423c6834503840813327d0d3ba0d675206ca759260ff79cb775adf83e314",
"test_native_infantry_setup.py": "8d935cd24ae49ca8a11f9a52fbd73146e567b8f36e0a7acc6565eb3e7d55f1fd",
"test_infantry_ammo_access.py": "bd80e4405c3f2029553b5e932ec49c6370b8366cd4e9ed03be89393f86c07dbf",
"test_infantry_resupply_planning.py": "211e3d0ee20242f271afc46885e1ba7845ff2406d663bfe5118f40578cd5d709",
"test_infantry_supply_pool.py": "6fc0053337bbb889021c6eba608796ef946ff4d30a1b01cf678927293218d9d2",
"test_hq_multiconvoy_supply.py": "c96a941e75673a2c95adee83b57a84d3d8e2af772e96b197f85d78a90d469a2e",
"test_enemy_gunner_skill.py": "67172901ed950517977e535c1237e8eaab10d22d52452bbe05fe16bfbb4089fe",
"test_native_memory_deadlines.py": "cd50cb03be9efdde260a4cec4e6ab652fad43625928a0c4248cacaf129552cae",
"test_convoy_auto_settings.py": "fe4a1e237e31bfac11f07b1986bff859f6b4712aa7759ce9e359e28e5ec2aec1",
"test_convoy_startup.py": "2c9106023ecb6dcfb5c96c2edc98b51695c325c685b2ced37b999b6cd4504c65",
"test_failure_result_refresh.py": "076444d2c740609ea4290de1525cd5d7fbd99beef3c48c134afb581422a3dcfe",
"test_infantry_resupply_coordinator.py": "65fa119778289175766ba7fdecd9e5685199736dffecc32056692121cbc6a682",
"test_infantry_mine_coordinator.py": "2fdb2138685a329cef11557973450bd5189d3d7d657dac5cc51b3df2530fab6b",
"test_infantry_mine_transfer.py": "a94ae1bb6f646bc0cc307a99d0323d4139624ec6df887b6c8c4bbeb84eed8d25",
"test_infantry_ammo_transfer.py": "e1172dda6350d2f8b89166ba63995cd1590435930ba220cd38b022307103a306",
"test_finite_magazine_reservation.py": "dce435b1dd2d9b1e0ae1f54b5f911ca4207227c4c23586b4f4701c6a6995fc8b",
"test_mounted_ammo_transfer.py": "88afc9fe65e42b42cd46e060e9bde9c1a6c59cd4cd4f20f8642ba9d05ae4c7e0",
"test_mounted_ammo_pickup.py": "f304f2426e152171ce61509ad467e87fc9f1933962032fef8ac3f78b3194f22e",
"test_mounted_resupply.py": "c17525ffeca6791b4542ea0c7641e4b220b03bce506fc2fda924aac09e8b24ce",
"test_mounted_supply_integration.py": "2f365cd9918bf39457fab046b8e046392f7b35e2b2eff45a0d2ed7d6ffee956a",
"test_hq_ammo_reporting.py": "7cdf673d137a5c016630dd61d21d29f860469519c56303a12e19ee9630e1664f",
"test_enemy_radio.py": "698c3ea5e1a3680d5b0438c50a341e53dd09f08d2f1f935e59667bc72ae83765",
"test_native_maintenance_stock.py": "7acbb488f7075428c08a10cf0e975ca0d508f3bb6416eddcc2991da93a5fad91",
"test_packed_external_game.py": "c5581fa3225bbc5b160fafc26c65783eb7d551489ab101b17f7a6acc1d8d9e63",
"test_hq_radio_node.py": "2297ae23b7a5fece845c13f16432dece6e2dde55ecc097a5be6311f470dd5242",
"test_vehicle_maintenance_stock.py": "e09a6e98f314eef1cf487cbaf8b2185bda950c12329939214ed1ba95713a097a",
"test_optional_transport.py": "16c72845dd07f4ade7de361136c04bd264ff75634152e83a19d19a2fdf59bd0e",
"test_vehicle_entry_diagnostics.py": "49e8b4cd8274e08de628e89f4471ddb47823af38d98b464336e8c98a4308dbda",
"test_vehicle_security_native_probe.py": "977384c5ec07588bc77aa9aeae45b008c02d55d31169e46984a1947e987545c3",
"test_vehicle_security.py": "f08a1cffb0860ac7ad93e94f4cb8b7cc37b8c49b3dee72b1d310fc72d9f95422",
"test_vehicle_alarm.py": "1b58d6b35f080003ecab03b23c8da68e0ba2a6a82db4edce89e6031d83f26c82",
"test_vehicle_alarm_perception.py": "6c8854088c28e2a7b4ee8d38a1f10f66eddfcf9d67afdd460b395d19877b7191",
"test_native_convoy_mine_stock.py": "f069900030cb644ba9e04adb01a6d847a1afa6248a6c458f547aa4fcbd4b5a40",
"test_native_mine_stock_runner.py": "51b30d4d7d7543b1674285448d382dcbca55272a0403ea977d2cf08db6a5290c",
"test_native_mounted_ammo_probe.py": "dd7169d8127fef52a4815fb4ad8227307df557170da6a22723c765bcd74ba340",
"test_native_mounted_swap_probe.py": "08674b3c0121756fe94762bd0acd5b6880ba5b234691557851eca5558718e2ea",
"test_native_mounted_courier_probe.py": "4dadd3157f7da193ce8996b5b08e802f891295ad82a4236366f3018c778c07e7",
"test_native_alarm_hearing.py": "7842886a177aa9fbb6b943b72703c4dafd18d162f26581ce30ce04289e7e9ab5",
"test_native_convoy_cover_probe.py": "452ec47f1b3ee9c27e7a31d7c2c09b16dbe981723f4b7dd72afd3fad899a73ba",
"test_enemy_optics.py": "06361eccef16d60a6f5072f9b126814a8f686c478049760047bb2ae8d19b5c52",
"test_convoy_combat.py": "b31239028d6fa0b43812c67eb3532ff1b3f4a87b43092dfed6b98de90f8b3a68",
"test_ai_stinger_admin.py": "d645813857f85854aeca60c9010689662d7cc43f298256d73ae37b05d74e94c1",
"test_hq_ammo_dispatch.py": "6c7a4cbaa41ca3bee01082ffab376fc2db5b08757aac88c5e8caf99b39677d0a",
"test_hq_convoy_combat.py": "9f4cd9688effba59be85fea230ed59a2dab3adcf25b40677f9140ab727b33e0a",
"test_hq_ammo_sampler.py": "4f59b80291ec6f636a0ba5f748689f2664d3a1e44e74c2f709fb73c8019c7572",
"test_hq_mine_sampler.py": "67186d8f6609c3544a9c60f57af876b046618f9b586b2a56520d3a5c8a0e6e22",
"test_hq_mounted_ammo_sampler.py": "b1c630909e5227d0f7bd0d69d7927403fcb0f33e7297d5fa52f96001720f8442",
"test_hq_mounted_binding.py": "40b6af209178cab30b2d6b4420acabf2086532fe0d3f836caaba60e369bdb905",
"test_hq_vehicle_seats.py": "8f35fcbd30e51b5576349245a102105926c7df738f3f77abb6ffcd780c6cb62e",
"test_native_hq_body_probe.py": "f2b761fadf013d55d4e9c2ae11c5349fc054e767cf950aa632a43b8f4fe1d758",
"test_hq_delivered_casualties.py": "c22ad9e395b36b41e8292b034f170e14b5d13a6a02b2a81dc619dd37110ad905",
"test_external_profile_review.py": "a35e9670a8f5eb47d28b4d6afe498e5a58b2ab2dbdc59912a206010ac8dc5240",
"test_hq_uplink_fairness.py": "fc4808a2045522ac6038eef9c37c75ef133bd8af7ffa02c6c1d105b3bfd6c555",
"test_actor_group.py": "0d808be40d13866bf8bd983d62ea3a8e7772e9c49a41109fffb02c5352153a4d",
"test_native_package_external.py": "8eb3eaee401640521c67a51607104a28de89ea9c32b3b6dffd05d9d3026fca3d",
"test_native_convoy_probe.py": "9a0ed03c1274d0c5b7f459285f7f2c17c68800cd6db8dd55dcae706bfd9d700f",
"test_convoy_placement.py": "dcbf572747a85edbfac341e7e358b1987150a2eb721708a3a025639be228a7c3",
"test_convoy_road_plan.py": "62bb655a84f90e934bb894f8e472a8a06905d72e1c0b05bd641e46eb8f4873b4",
"test_hq_convoy_dispatch.py": "945a3cba06694608b4880408a13447ebbbf812d400fba3af5b7a57cb006a1f6d",
"test_convoy_admission.py": "0ace42a7e1afee7413e45a3909e7ea5c29dbb8c0e692acc3dc9a35ea7ffd4adf",
"test_convoy_dispatch.py": "47e77f544ec6f3f34346dc6b5082f9df0a2d869897e094ca993a92c7315468c0",
"test_convoy_lifecycle.py": "1f1a7f938bbb618c21889199c48cb512fb3e21a5087708fe8361400762fb1472",
"test_convoy_budget.py": "481364c432715336825466a9ff199edeedaa2d3621daba90c0503addfa6010f7",
"test_supply_convoys.py": "19309aff2b38f59eae2f5637960f133b78957962ad2dd95527a847692f127e74",
"test_supply_budget_admission.py": "3d0e1372f89873470c336038c667df38d2e2e71b3dc2abfddd1215939c448fc5",
"test_mounted_initial_stock.py": "cf7d101d8bd31cbdaaa0e7d66f0d8b39aff9b3b70acf51641902c6d0de5be096",
"test_convoy_mine_stock.py": "e0073271428f00edf86251c9af5530f39094261b05474058df6b794bd958091f",
"test_convoy_column.py": "a626be183761fb823cbb78e287cb410583500e37fd7d0ee96041d539a0af36e2",
"test_hq_body_observer.py": "6cae50ef0a2b2fe35845f42e90998c517c061fc417cadfac375bacc89bbe603a",
"test_hq_status_sampler.py": "b8582fb71b7ac77a23158ccd6230e8124ef0432831204e4b8992dee3a9c10062",
"test_hq_watch.py": "5bf0debdeecb8f7fff6be94cc3772acfa948b839771d309291b1720b249b2890",
"test_hq_assignment_lifecycle.py": "4cfd15d1655b7cfadcbc08104bd01cdfc9960dc88a95ebc5a9958f6f71ce4aea",
"test_force_ledger.py": "3dc268db304b9465d53056edfcd8cedcc15591b411c55ae8f9bd43e163ff9c49",
"test_enemy_equipment.py": "bbc753525bdfe05ea9ee7fcf45f3158307ed56428518b08845e097fbcdf299c0",
"test_enemy_loadout.py": "0cdfd28ce4d9c89223a7f439eaec1cad762cfc6c9e1cc4c3213d4600a3501b37",
"test_automatic_equipment.py": "117c02741647feb91a5b9ec7cce5e9909d0338a4fea476e7e7a8164ee93e119c",
"test_engineer_mine.py": "3ffd360652ba66d4bb96247496e9b34175cc35c4e5d665f6524cb1cbd563bb73",
"test_engineer_mine_site.py": "9c01b326f4d171041669f6aff25a1750ab80cec113be4481eeabc471c45ccd80",
"test_engineer_mine_hq.py": "822f50e363be3ba03bc5d12748cfc93d83e93552d66797b01afc6460e7ab7d5d",
"test_hq_doctrine.py": "5c18ee72454cf92132dedfb4bf581d174d67fc2e423158347ebe52ca74e8a416",
"test_hq_coverage.py": "d790ae0e5b533f702284e6deeb2c84f7ede5c89bb2b6a68847400e915d50c146",
"test_hq_task_reservations.py": "aa6c5a38618d4bb469c84f18fb7d1748501b4608bd1929cf7e0a6600d248c0f8",
"test_hq_pursuit.py": "7ccbf51c7317097d9db6a66cc5be4bec67e542187f0fce5b4f3750bdc4311733",
"test_hq_memory.py": "839c7adc63dfab023fafe1547e29caf0ccef52882c5d2fad7b342691b562a41d",
"test_external_addons.py": "4e2c3fa2c92661c49ea0c492648b736bebd54f24cd244f3fe27710a0c7a487ab",
"test_admin_tick_delivery.py": "8f61a6aaf07b0c41df2f415a1956d8f09fe61a7d4f256775ca62511030937a5d",
"test_project_schema.py": "0e25ade3ee0083618c1b2837aaaef36ce33663d78f35d862e1dbec256f4d6e40",
"test_admin_session.py": "6e1850c625e18460a5d64ccbadac992b663a46bd612fcc16b6006f19b3014896",
"test_admin_providers.py": "4869c86d2cb8c17a383680d594131f4053a051eb4af369657523e20f68311de6",
"test_admin_menu.py": "246ab269aabe8b743beefba8536d5b72a5c49db5ef6254fa7ee6684c6a82ad0a",
"test_journal_readability.py": "47764126522e7d7a90100cd9beff741bf49e4d8390111f977919d3e323a5c7df",
"test_admin_player_tools.py": "7520c768b760ef3a03dd2f17376077fc17695360a89f91df88af924899a74517",
"test_intel_admin.py": "f2704740a380de8e93c7ceace414744f938442cffc6bca77a3439b4ae36aade6",
"test_intel_reroll.py": "d102cff7467323440273eb457b5dfed6610d27f32c52c6fb7801ce93348ef5ae",
"test_intel_discovery_feedback.py": "49b2fedd8704ec67af60a6bb3dd156ddca28eb334d18b20692ab1e4659f439c5",
"test_hq_report_selection.py": "4bd4c4800c217584ad9e1b4a37968350eb9a160e0151fc8b0375781736726cc0",
"test_casualty_feedback.py": "2d8bada9a3fd7583af4fd4f07033dd9eac28ca3bdf34a4557c8985b7a1714dbc",
"test_initial_admission_exhaustion.py": "14d6959a1185f154389be1405c49e2f7c1c9a3f27295e26074ac4ec74380057d",
"test_prison_held_action_proof.py": "349ee99d36f18fb7c70382ce95f1e9d84d819575a45b6f5429394d1702f1f227",
"test_prison_held_action_evidence.py": "bbb032736774bc5db5fab7758faeaf038eeaae9eb49ba706a52f1e9bfe09fd01",
"test_prison_held_input_adapter.py": "56fa60ae69bf280e1c2e90e7882fa213914623980b6800a4312c6f1017b8f632",
"test_prison_held_runner.py": "d50905e899c2d0d92ca2f4c51dccbf2166ee21b8c6d2d4b218da459b724c5a4c",
"test_prison_coarse_facing.py": "fe0ceebb74dba77005d6a7e31baa1a50156cc66f79a1d90eba4db9b27b099acb",
"test_aircraft_field_probe.py": "fe4e5b58bbdca0f366fe4c614f7506f2a05fa29fabcde345e322cdb3d62db897",
"test_aircraft_field_runner.py": "822717f77702c335667b226f025aa6525415689b492f9ed42dd256d4c893429d",
"test_aircraft_field_rules.py": "dbed3a499eeddf2513e3582667ea2bd90fff6ed26057891c7df6e196c3d00e84",
"test_aircraft_field_envelope.py": "67e60717a92580e3c4caa4974994cd92a96c98562be805b31319b3585f296639",
"test_aircraft_field_flight.py": "ae5e18f0e2efe5ad01523cb1cf9bc64139094aeaac7477a900a9abd8e6ae8f18",
"test_command_maintenance.py": "be2c942aa11a5f874448e94f06925f2f1de2210a14881fb7e486842119cb673c",
"test_aircraft_service.py": "9c19a09354ccfe8b41961204d80c3621d11e6704909b7266fa00e6c197bfd20b",
"test_aircraft_service_cancel_runner.py": "1220e7c45c50590d12c9a5192eb4482e7e6942d7c00f36d9a79b5ca70bd1429d",
"test_prison_action_selection_proof.py": "1f09fb84b73ea916bb39ef985c58aa6886223e60cd425f929b3a020eef74ebae",
"test_prison_action_selection_evidence.py": "1fee0421669721618dc2f9a3039f945d470b83b186661d3b1f00291ff8b78e9f",
"test_ordinary_gate_choices.py": "0e21f2933a4862eb5fd2f04b3b32dc7de6b2ca72d920aaa332d179edadb932cf",
"test_aircraft_control_bridge.py": "bae6f1711dcc5f55f7a813af251fc210ed017c58a8067c03d91e936824542ef0",
"test_prison_alignment_proof.py": "04c96825ea03b95c3966e3a53ce2c15990d63388386d84f2bff3e6b6838b18c0",
"test_prison_alignment_evidence.py": "214af04ff9b0e8ebf0bc97f528233f5d55fccc7623392a65c6dd286ed415e724",
"test_aircraft_route_demand.py": "96d9a21c49605cb671525f977928a21c57f1d0b441460a2624892006e7057efb",
"test_prison_approach_proof.py": "ca71ba6c8cc20dad52d2966984676a111004333c24bc408f1ec84312e4208039",
"test_prison_approach_evidence.py": "660e03b6f9932947c1aafc4c043c2a2c5bca776433c2146df18e8bb90c606a9a",
"test_ordinary_gate_evidence.py": "2bb3cff082b3fe45f668933a5039fd06a8d31562049cdd41c4f32181136ea5df",
"test_ordinary_gate_observer.py": "78ff734604724a525809567ecda88f4d5fcd67816a6ba4960b72d0685f1a8b00",
"test_ordinary_look_observer.py": "cd5842e54c9ccab16766637bf2ab4e4e0b98f4d597b5927b0c2ec3f720fa3668",
"test_ordinary_look_evidence.py": "1b98be4b69a5e5bacf46791f1e009fa3c73cdaff875c012837c9888443a61633",
"test_relative_look_runner.py": "131d829c60a7bbfe3e047af8e38d255e5ecb9d84b7d2188d14422dde724fa05e",
"test_radio_waiting_text.py": "2aa54d8126b3fddae2b77d496f56d2d6e6d393c6d5124bdb5598713d9c29d629",
"test_inventory_control_runner.py": "f325fe1975f7a56fbbb1a6357206d2ac0c9e7c32c396473fdfaf1cb80ad39b11",
"test_inventory_layout.py": "8e176f8a87c300b8062a37ee34b22a105978c7d9c6147b506757135f4f48a1ff",
"test_headless_input_proof.py": "55c84de6dac3a9c44bd1ab4113d306544025a405c613f6e7d26550328e84f6c1",
"test_headless_input_exercise_runner.py": "0b812647718a3d7145905a3ed17fef97b025d57b1372773d2c1069a3473a9b1f",
"test_private_prefix_cleanup.py": "bc6d3fcf6a5ee5b5266bfc4516642d2f73e71dfc870c527d67cb5a47964dede0",
"test_runner_private_cleanup.py": "4380874af7553391ea7e1e234c8a3f8e61922e0f16b1bf9bd4821cc479e5edf4",
"test_ordinary_input_runner.py": "1ed373818673a438647fc7074c4c689f5bac0a91e8d55edf29d466b96f6703f8",
"test_ordinary_input_observer.py": "09cf661ae47f53cb429a7ab17c2b752ae30a04368a260468227b0678148b2434",
"test_aircraft_route_envelope.py": "08b16d4e7f97db96e3f88af0cfccd9b6bc083f6f25ec33cffd7ec36b18798729",
"test_aircraft_route_policy.py": "b717734a07a59ada837f05c36172110bd7d0b5a5a277e8fae55a11dcab3e2aa2",
"test_aircraft_route_probe.py": "bd8cb998fef33db8f26342eec0198c54b7715662d333530e2bede572c81f162f",
"test_rough_intel_feedback.py": "d7395ecc498dda46e1c9a4c8fbf98a64f2bbd013de7806517fb8008756e7b40d",
"test_headless_display_probe.py": "d4d6c9907d7419ca888d5d9ba7448cbe6f5d2e53810f74c85660dfbdfc9f7e2d",
"test_headless_display_runner.py": "f03a908e813c9ca4dc2ff13b3ade08549931e39490b8636742390a304c73974f",
"test_preparation_status.py": "e43cb7ce81232a31d00219004574dc2d1806760e0b6f0c49693725ffcb1b4e9e",
"test_hint_delivery.py": "6e76532e32c4bc545a1c8d483dba2200d4f3c94f43ba80c6d5b54f2583542ac2",
"test_native_end_lifecycle.py": "8b187723c9039e68e3e590c812c91dcffe1e5917d4e450ed798dc177888fda7a",
"test_native_end_runner.py": "aed94be9b370a412937303cc5b66f0151c2cd64c3e1358f983f9ea53eb0d1057",
"test_escape_result_wording.py": "7b3613cccd4f24d3ef4665dfc1854cfc958a69018a59f9b8090617f0185a82a8",
"test_native_stats.py": "a9ce90c74f0ae7e5c40e451f6b1d60dadde831c3d858710a70929390d5c70f7c",
"test_aircraft_translation.py": "983fcff4800e777cd1c42126431ca94e7c03bc06b5fb34a243704b8ca55dc36d",
"test_spawn_retry_budget.py": "c182acfcfd52cd74a94dc3336d7603d14668850a684b758cc7545a98a5d14beb",
"test_spawn_preload_timeout.py": "db3a3aa42c20f047da90cac6755cb283d15cb3de6a22a57a6e1f352e9b4511dc",
"test_action_feedback.py": "1fec11a218b6da69c8c40ce232523582f0ad390f8357e74f24daccf5d46d3814",
"test_native_aircraft_control.py": "3ffed5429896254d96b67ff3fdd01f65689f526e6a1766cc6874e2e63f2e26f3",
"test_aircraft_flight_policy.py": "147a27fb57c0b01cded35eae26af4394d7f41eeeb68856f564972e1c89c629c9",
"test_aircraft_flight_envelope.py": "6499ec174ed68dbfc07bd49275eaff8a7e60865615bbaefee354de7233a6ff13",
"test_ordinary_screenshot.py": "eadd4f8ae2a8057d0ac7bca5e8f4abc260faa10cddfca31b8552d7b49669ab33",
"test_participant_selection.py": "e153f69ffa60d186dc3b1a238df1d48f2a0623b2dd8331d2cbbbdd57cce5529e",
"test_native_shared_map_ownership.py": "672d248550339dc6350e548034c50b3440d44b91668457f3efb2d91c8445c3dc",
"test_shared_map_ownership.py": "486eb3a8a04a47878b87ec3952c613542871077af1de27ea7299fa3d72caff1d",
"test_intel_registration.py": "41cd929a29ea5e6b37d856cfc873c33fa2a8130e3aad30146f522ce217875488",
"test_mortar_activity_completion.py": "a0db3b63962bc95de42ec12ef17c53730464ac7421a4475020957121513586ec",
"test_packed_chat_game.py": "d23c099d17a0dda09e5ee28931a4850f9bf6df5a7874581342eacbd16860565e",
"test_native_mortar_refresh.py": "60f3c4fcb063506e9bd85e4abd3cd2fc802304bc71933f3e31d88f5b896aaa7b",
"test_archive_packed.py": "37712810b7c6fd11a2df35665df81546f8b98682dc74b317ad1f9ad6ad274d86",
"test_mortar_refresh.py": "0ac74cff8aa10fb06ecb75d17eb7ca3a6b80bf5194522bffec583a44fc01a419",
"test_packed_core_game.py": "ddac4281f74999b1e60c2052bbdee36c97699192cfd5174a88b6f01ee740111e",
"test_pak_inventory.py": "8f0b55bb295117c226900bd641d25175db1021a365866a5ce6482a78d08c7f41",
"test_native_mortar_salvo.py": "f45625eb92d16adc8b3eb57bc72b77c8829d46c2c7e5bef40d302fc90252ba72",
"test_spectator_guidance.py": "26c02deb1a707f51dcf577a9ccb789bf33f432b41d9404d36a7b1b3c8802298f",
"test_spectator_recovery.py": "8bb59c51df003e24532ad9476af4c8ff3b7f4276dca25e8162b91eb77c7b67c2",
"test_native_package.py": "0776a1eedede7185aa36c7fe816ea6231e6f475c0f6d210a2c732b23dc6d765e",
"test_item_station_teardown.py": "4e0f508dea6172862be82d6c7f295ede2bfb2412c390a0937a75ab176655f4b6",
"test_source_bundle.py": "074ad87ee7ab0b41ab94a7cb28efca66a975c24b8e2574122a13a52a4d491d0a",
"test_native_flight_footprint.py": "96923c018608f0c4d24294a9f8e769e2037be1fac8f1d51f4d73463706e134ad",
"test_native_flight_input_diagnostics.py": "355e2e45b86b9a46c68efb0563d16bef7a032cd7758169704b4b26ea92bee2bc",
"test_mortar_logistics.py": "98cdf38e43eb564163d8b409dfc95c4ae23e775c423651f05698acd52a7ef5a2",
"test_mortar_courier_storage.py": "0eb75fbcdcd712ff1c2220dcdd87cff6f3ed1e6e8f1c889916daa6b84a4359f5",
"test_powered_flight_pad.py": "690c1c6e05f3520a6d4d6c45a0fc5d9184e30a12b24356b3126bdb35c4171b82",
"test_prison_escape_policy.py": "d5d54588116eb730a8fda046f25fc4edc89a5345f85774cbc0f0a9b3adb85b98",
"test_powered_flight_policy.py": "86bfd5851be6fe3a187e1fe7fd2b7b0965c891cf29b2260b0df292255c5c547a",
"test_flight_action_runner.py": "aa14ebe85fce7c0435f48aceec1d4463b33fe8a5792b4e935b543dff94f4ad02",
"test_native_local_admission_probe.py": "16864bc359ab607dae3919442bd18f191320721411a8156e23be999f24e4454f",
"test_mortar_report_ledger.py": "fd2346e06c37a9e7621e1861e0f472b72ac14786fd2bcfbd785b62700d55ffde",
"test_dedicated_native.py": "f0323b20743221bd1ad46d6462246c2a0e2be84b395e40faa39007ef330aaa3c",
"test_native_mortar_transfer.py": "3b2a201a73c9ff2509276428988e4a98023c6aa94f8eeb42bc06c6cc604473d2",
"test_mortar_aim_renewal.py": "cf228b7f83d247d93277ec4c8644eb1090a20336a7e9ee2b90086c78199a70ca",
"test_dedicated_preflight.py": "0d654375db6b8eb91d0b92663b50e32776aaa7ecafbfdb83c00f04826df5236e",
"test_mortar_transactions.py": "b169cee3ccde42a24b6a0aa0ac2c3ff879bd1478bed1979dbea7b82c8006ee43",
"test_native_mortar_probe.py": "217801a6eddd48f76e99363a72a9812c0f48766ebd2faf8e188f4466ed1e4088",
"test_diagnostic_no_splash.py": "d99539a8b3277c2f1ac3e3bfa4c897876fe21e704c9ae33c542eed79fc2e9e65",
"test_casualty_incapacitation.py": "55b5cfb7b3eae496a8cc18888872d11331ecc01afb7326fbee3b8d65047dbe93",
"test_casualty_remove_probe.py": "e3b8ac386bb8e4a9832215cbbe1cacf7a5bd1314467bd4b07ed4a57b2db75458",
"test_extraction_placement_policy.py": "d924f163d98c78989938ca01eca5935891fb454266810f4817cbe49651b84ae2",
"test_guard_cancellation_policy.py": "f8f134b6d525a3c775677b2a95c562b12aa84ba287318c08c833d684ad0bd9d8",
"test_casualty_ground_policy.py": "6543c594293d7122242ec68d506a92dc81464d110cdb7496a225555cee338c83",
"test_casualty_reservation_death.py": "fd68dce04ea48ee2a22fac499c32a5c53847a25e3f14eaba3f50437d2c040f25",
"test_casualty_loading_policy.py": "cdf2c0abe4b794502f18228b173db47c4093ea062378ec9e3971e0c4f9e3bf1f",
"test_initial_guard_policy.py": "0c80e744db1ce0a0d0746c43d867f5d2f47d9b92bc48d6561ceeb28a204d8743",
"test_headless_game_runner.py": "0d84160076ec9961e7315ccd50d6ce45ff971328c298649505fbba6305c22f31",
"test_vanilla_game_control.py": "8ab3777a5bd0f8213efae08bd6db70a05790af992c2abfda8e5e5aa079beebbb",
"test_archive_game_control.py": "8126e2be91f9ee8c09fceb82d03bb0d9c51247909189a424c3e24dd2b1ed22ce",
"test_site_discovery_policy.py": "40fda37b86d469a1cf8fcb7a1fb18abcaab0df44ad09f50018744d42f8f4f649",
"test_faction_catalog_scope.py": "c8fab92575f2621f47ed8685243338aa9ea717bb809c2ef9e8e0884af9df263b",
"test_mission_rules.py": "f534ae447fe1db6ae939430c3b14568d2bf1b84956dca295cce04211411d9ee7",
"test_admin_setting_policy.py": "69af6f74e262ee4981ac428ac1ab85561f8b365aed5879e20d315ededca9ee22",
"test_player_admission_policy.py": "745ec0a9e491ffcf5bec53ebf67ecee8333f4dcfa5d19bafbde31cbd1cad7f8b",
"test_progression_identity.py": "2fb3725aa735e00b20ba7a4ac45f8e087d4346c58a176bee091bab0a9755c1df",
"test_discovery_map_position.py": "0644aea60d4c546e819ef417771563ab7598e84d5e13db2fa63416ae1fe6ddb0",
"test_local_admission.py": "0bde82f6d5c31c4187ed0aa1935940b8b9e634868b3a4820eca073580ad136b4",
"test_prison_placement_policy.py": "34539744426f0b30e41883203484ed60606df8ca319324014f07e833bcbf854b",
"test_recovery_policy.py": "adc4966ab92f0849d08636d93da5bd02b9162d1ad7369b325a1a357903abaa55",
"test_player_medical.py": "e4b3140a3afc0161db53f261e5480e51f1ca09f85657e25b0efb7dbba3336e3f",
"test_time_policy.py": "45ae5768f6e87009b4074937cbc2e384c59341e905a3f250672bd2a110b2e6c5",
"test_environment_policy.py": "66b86e66f47c4ce397c6093a50a724bbe8dedbf3db53e0dd7d53ff33243a0b52",
"test_view_distance.py": "ddc6cbeb41485f14a4f2ce23a7a86f1708e7e335bbeecee6309be49fd72e00e7",
"test_environment_restart_runner.py": "05bc09bc45db70ba4a635b65b0a96aa38437ba50c98640b47ed8d0683c3a5f71",
"test_inventory_enumeration_policy.py": "95cbfd7c4351cb9a8e1cd6783524be79f77255e5996299919a61dcfce8b0f21a",
"test_radio_defence_policy.py": "48c9c01dc6135a3f6d2187b0974645758040f041c3c2c2c26b14222fc572dfe1",
"test_radio_feedback_policy.py": "6b576472f81a35bd4df4dae3f19925b046eedbba262ad67f9bfe1ce9d220a487",
"test_performance_comparison.py": "5f932de9e9898acdd379f26c777a35c884269522dbf8c41991a7a25bf61c369a",
"test_release_check.py": "8b6e755ed922ad129ba01c228989610a31f3a79841dc7cdddd4ddbd0e510971b",
"test_settings_migration.py": "5a82ba8672b72fb388a95e297d53452e45679ed3b94f5c7d4598455179038aef",
"hq_network_regression.py": "f7021b7bbdfdc2eefcdfade2bc4ad2108e1312cd07e8e09025783c626e7c8cae",
"helicopter_availability_regression.py": "3f256b7f5db246723b75caa2cc247249881cba95bde71ea1c90733404fe19f35",
"mortar_salvo_regression.py": "0f5d5f5d33f64ff43f5a2b954fe4eec032a00697f51f09efa10284537a3682db",
"test_prefab_identity.py": "2a1c6e4cb1ead0c7b36b8fffb2ba0c59dc7e025dafaf8344a8158d38fe17582d",
"test_spawn_scene.py": "d89ef752906c1cf27c4cc7292997a4d793ddb3b56a6dfbdeff837978350167be",
"test_spawn_scene_inventory.py": "f29bee9c629072f51caf66b680013b18f608bbfc5135a1f020e1a2904e89cdd5",
"test_spawn_scene_lease.py": "adaf38b259cc36af526884d3d2312ccec0cbe6eca18d7aed2c1a066be8ea0da6",
"test_prison_ai.py": "557015a4a3191aede258dcd7dee4ec4f555c3efde02331687185ed124cebb4fc",
"test_native_player_death_fixture.py": "0d0825ebb948a68ff8b8f5cbdcc7e27bdf940e5af1e277ba1780d03e12f2ba33",
"test_hq_planner_budget.py": "c9e6b85a3d25267c187f503f903136a16aee382e9d842f61ff88c550b5bb4e51",
"test_ground_depot_loading.py": "61b31dc3c2a6cf6bf0aef67fe3ec92b4b2d51ee93fe47e7cc8dc77f2235747af",
"test_ground_depot_lifecycle.py": "927a6f15560e177c838322e18ef555ce7db3acde0651d1a43353a2c6e805f3a8",
"test_ground_depot_transfer.py": "fc37626765919dd449432d445a17ec25a390ed687807571a1c5e2570c4ecddb7",
"test_ground_depot_provenance.py": "33880dbf308dd4f338cc4e4bb04449d662cc2fe0941721a819528b7f7a6decd7"
}
@@ -0,0 +1,589 @@
PASS: missing, child-only, malformed, zero and duplicate prefab root IDs rejected
PASS: delayed scene/inventory arrival, deferred preload, identity checks, stale replies, timeout and observer cleanup
PASS: actual inventory manifest, delayed/missing/wrong-owner item links, finite cap, consumed-stock refresh and preload ordering
PASS: spawn scene remains held through final acknowledgement and nearby use; leaving, reassignment, disconnect and teardown release it
PASS: production prison AI hold/release, repeat activation, authority/faction/player exclusion, dead actor and stop cleanup
PASS: actual protected/capped damage plus exact-actor terminal fixture bypass through delayed native damage, fail-closed ownership and untouched ordinary actor; no native claim
PASS: actual full planner selection/commit body, 360 equivalence scenarios, orders/reservations/cooldowns identical; one128-unit scan vs >10000 repeated unit visits; no FPS claim
PASS: actual depot radio/planning/two-leg state transitions, fixed deadline, late proof quarantine, finite import and no adoption after Stop
PASS: actual depot HQ lifecycle, existing planner priority, server/mode/owner gates, idempotent polling and owner replacement
PASS: actual full depot leaf, exact custody, isolated callbacks, finite reservation, false/unknown and Stop quarantine, once-only delivery and caps; native movement unqualified
PASS: actual authored identity capture, READY-only detached provenance, same shared stock admission, completed exact two-leg proof, lifetime caps and Stop no late adoption
PASS: actual Tick clock initialization admits fractional first ticks and expires without extending the original start
PASS: actual finite conservation/deadline/callback policies; read-only selection, bounded once-only inventory submission and no can refill; native transfer not executed
PASS: actual exact-context membership, bounded identity/reach gates, native start/cache/eligibility ordering and no duplicate/foreign action start; fuel manager identity and empty-can headroom guards checked
PASS: actual detached node/value snapshot and conservation refuse mismatched lengths before indexed reads, retain original identities under native out-array aliasing and log bounded counts once; native cause remains unknown
PASS: actual mine evidence sealing/recovery, historical coarse publication, caps, canonical ownership, marker join retry/owner-change/stop; native arming and replicated vector-array transport untested
PASS: actual full document recovery retains authored/sealed targets, one shared spent ledger, retry/exhaustion semantics and canonical multi-player ownership alongside supplemental mine intel
PASS: actual infantry search suspension, quiet grace, finite resume, expiry/replacement and defensive/ownership boundaries
PASS: infantry combat gate precedes radio delivery and preserves non-task transports
PASS: actual HQ contact transition wakes only fit squad members, cancels only task orders and logs changes once
PASS: actual finite medicine grants, authored stock deduction, full-backpack refusal/pouch fallback, no loot replenishment, unresolved-operation quarantine and ownership/stop guards
PASS: only recent native detected/identified threats suspend hunter travel; stale/disarmed/destroyed contacts cannot strand patrols
PASS: actual hunter combat transition cancels only its travel once, holds through renewed contact and resumes after quiet; unregistered startup preserved
PASS: captured sighting retention, immutable details, expiry, replay rejection, bounded sound uncertainty/cooldown, radio loss, priority and overdue-status fairness
PASS: arrow press/release, held keys, opposing keys, disabled/menu input and firearm-only retention
PASS: town trigger and hard 700m exclusion for all observers, empty/invalid positions and final-check crossings
PASS: exact finite site squads, invalid roster/count rejection, committed-site spacing and safe fallback boundary
PASS: mortar couriers use the mobile site team and refuse permanent-only garrisons
PASS: omitted preferred mortar depot selects a surviving owned camp/mobile team; no camp, foreign cache and permanent-only sites are unavailable; historical priority retained
PASS: real-session mortar deadline, failed-support convoy admission and hunter survivor/recovery gates
PASS: native-route retry preserves delivered target, limits attempts and suspends during combat
PASS: stale/deleted AI utility cannot receive Complete; mortar HQ preflight withholds unsafe orders; mounted convoy cover never creates infantry Defend
PASS: flight crew affiliation and group precede native boarding; preparation remains bounded even while passengers wait
PASS: factionless/deleted map targets do not abort perception; faction lookup tolerates teardown; deleting helicopter releases without capture/engine access
PASS: shoot adapter waits for a physical round; bounded same-shell retries, interrupted/never-started loads, committed no-retry, order/owner changes and normal native delegation
PASS: missing/invalid faction crew defers before any native spawn or allowance insertion; all registered RHS factions have explicit soldier and medic profiles
PASS: vehicle radio issued once; pending, refusal and looting cannot duplicate or fabricate a physical radio link
PASS: actual vehicle-radio link requires the original seated crew, physical manpack and live uncaptured mission vehicle; looting, dismount, release and teardown remove it
PASS: actual hunter release preserves survivors/HQ, releases driving ownership once, delegates capture/teardown, and excludes prison/patrol/mortar from generic objective defence
PASS: real opening road geometry enforces wide azimuths; fresh delivered contact preempts patrol cooldown, respects radio failures and does not starve in-flight interception
PASS: actual scoped 10% tighter REGULAR aim error and alert perception; preserves equipment multiplier and restores vanilla behavior when unbound
PASS: physical inspection and parent-wreck retention; server-only searched/report delivery unlocks native cleanup once with a 300-second delay
PASS: bounded same-group empty-spawn retries, no casualty refill, queue retirement, delivery-gated intel, prepared-team reuse, throttled diagnostics and LOD release
PASS: production airborne memory confidence, persistence, ground coverage, confirmed losses, artillery veto, cooldown and invalid-input rules
PASS: production cover retains the carried HQ target until its deadline; airport reload waits until the drop pass and cover have finished
PASS: air logistics reservation preserves delivered search until radio handoff, excludes guards/combat/in-flight orders, and quarantines unresolved native loads/moves
PASS: actual ammunition cargo selector handles empty rifle/machinegun/sniper magazines, preserves loaded variants, excludes auxiliary launchers and tolerates missing native metadata
PASS: original 15-minute launch/loss cadence, active/captured timer disarm, saved delay reset, stop, 300m orbit and bounded close-contact standoff at 30/60/120 Hz
PASS: actual aircraft-removal notification guards owner/server/active/stop and schedules one full delay without replay extension
PASS: hill prominence/elevation, actual road edges/heights/bends and server-only finite scout admission, pending stock, timeout and no replacements/refills
PASS: mortar duty scope excludes players, other crews, stopped/client/inactive states; only destruction releases an active assignment, while the gunner may approach the gun
PASS: random mode restrictions, full numeric ranges, independent calendar dates and strict daylight boundaries
PASS: actual killais eligibility includes the 1000m boundary, excludes players/retained bodies/dead/non-character entities and checks full 3D distance
PASS: actual generation scheduler bounds each tick, enforces deadline/candidate ceiling, validates fallback, commits only accepted positions, skips only dispensable sites, preserves required objectives/intel, and resets the next search budget
PASS: terrain placement samples world bounds, retains streaming candidates, bounds waits/work, rejects foreign fallbacks, preserves objectives/intel and validates completion
PASS: actual navigation readiness supports static meshes, yields only for loadable streaming tiles and refuses unreachable positions
PASS: universal connector, embedded/standalone exports, multiple terrains, stable IDs, native nav configs, missing-nav visibility, path validation and overwrite protection
PASS: airfield detection accepts physical runways/towers and bounded authored markers, rejects unrelated props, water and out-of-world markers, and samples terrain height
PASS: configured airport parsing, bounded readiness, stale admission rejection and cleanup wiring
PASS: explicit CLI opt-in, disabled/editor guards and mission-header airport precedence
PASS: singleton identity guards, paired faction deserialization and client world-cleanup wiring
PASS: task/map/respawn getters survive delayed old destruction and preserve ordinary-mode behavior
PASS: replication hierarchy refuses absent/aliased nodes and establishes delivery dependencies idempotently
PASS: standalone old faction delegates collected once, with null/deleted owners ignored
PASS: actual faction resolution reserves explicit roles, samples without replacement, substitutes disabled selections, and rejects duplicate/unknown/missing choices and insufficient pools
PASS: Random all submits persistent random roles immediately; manual mixed choices, stale/unauthorized UI guards and debounce preserved
PASS: actual content policy gates parent packs, individual factions, faction identity and finite group rotation with vanilla fallback
PASS: actual delivered road eligibility, ahead projection without chords, reservations, stock road query bounds, terrain/water/obstruction refusal and clean outputs
PASS: actual delivered-task lineage, expiry, old-order retention, native commit, release, road precision expiry and duplicate delivery
PASS: actual original-roster local handoff,100m3D bound,busy carrier/budget exclusion,origin interruption including deletedsource,normal radio delivery and per-source replay history
PASS: actual visual intake retains source/time/position/id, rejects replay, prefers usable own route, excludes simultaneous callers and conservatively resets negative-sweep dwell
PASS: actual fixture local/radio gating, immutable source/time/position, interrupted-report exclusion and exact-owner cleanup
PASS: local-handoff runner refuses wrong project/round count/insufficient deadline before runtime work
PASS: actual fixture allocator terminal/unsubmitted guard, original-group lookup and both candidate gates
PASS: actual report-derived waypoint insertion/order and tighter positive radii; no formation navigation claim
PASS: actual Place/Stop waits native pose update, bounds four attempts, preserves original position, restores pending/settled placement and respects ownership/accepted-move quarantine
PASS: actual fixture current/original recipient ownership, unresolved transfer cleanup, exact-token release and idempotent Stop
PASS: actual fixture phased-cargo readiness, bounded callbacks, captured-stock mixed-caliber selection/continuation, reservation cleanup and component magazine counts
PASS: actual inventory-fixture setup uses ordinary prison unlock before constructing its convoy-waiting probe; failed unlock cannot run fixture
PASS: actual authored storage anchors, native trace flags, own-hierarchy exclusion, external wall/vehicle obstruction, range, unknown geometry and bounded context refusal
PASS: actual convoy binding, finite identities, disjoint tokens, shared report replay/cooldown, original recipients and HQ cleanup
PASS: actual finite convoy supply pool; immutable slots, shared demand state, sparse/capped discovery and permanent shutdown
PASS: actual HQ rotates finite donors, skips unavailable/contacted trucks, uses delivered reports and dispatches at most one trip per planning cadence
PASS: actual original turret identity, native/canonical guards, scoped maximum-skill profile, reset, dismount/reboard, requested-skill preservation and restoration
PASS: bounded HQ startup/memory windows and outcome-specific full-route deadlines
PASS: explicit escape-route skips only administrator stress, preserving original full-fixture wait/failure paths
PASS: normal escape route keeps ordinary catalog and generated placement; historical selectors remain unchanged
PASS: actual read migrates old valid settings, preserves explicit disabled state, rejects invalid data; next-round feedback and fixed menu remain honest
PASS: actual automatic convoy timing/authority/admission/one-attempt/manual-task/stop policy; native deployment unproved
PASS: late authoritative failure reason refreshes open result; detach, mode change and success subscriptions preserved
infantry resupply actual rules, radio transitions, owned cleanup and unresolved-operation tests passed
PASS: actual resupply Roster preserves permanent release, original slot mapping and bounded ownership
PASS: actual designated zero/one original carrier selection, settled startup, shared finite claims, no refund after submission
PASS: actual HQ startup grant readiness forwarding is authoritative and fail-closed
PASS: actual finite PMN4 designated-zero/one entitlement, pinned original ownership, shared commit, physical custody, callback quarantine/deletion and no retry
PASS: actual bounded empty-return and finite delivery; phase-isolated callbacks, exact ownership proof, stop quarantine and original actor/vehicle boundaries
PASS: actual shared finite identity reservation; competing consumers, submission permanence, stale cleanup and96-item bound
PASS: actual carried-mounted swap, shared committed claim, physical slot reach, exact two-way proof, uncertainty and terminal cleanup
PASS: actual mounted pickup, exact finite ownership, pre-submission commit, physical custody, bounded callback and quarantine lifecycle; no native coverage claim
PASS: actual mounted courier admission, radio, individual orders, two-stage transfer, reboarding, token cleanup and quarantine lifecycle
PASS: actual scoped crew permit and native board completion/failure preserves foreign seats without teleport fallback
PASS: actual shared mounted stock/history ownership, atomic exact HQ pair claim, and bounded stopped-owner proof polling
PASS: actual carried/mounted early ammunition policy and status-first shared uplink; complete threshold, phases, cooldown, failures requested check-ins and non-urgent detached carried-mine status
PASS: actual group radio startup preservation, finite native grants, callback quarantine, frozen selection/actor ownership and bounded observation
PASS: actual maintenance native-stock check rejects missing/duplicate/wrong-identity/unowned/depleted/malformed stock and is read-only; native runtime not executed
..................
----------------------------------------------------------------------
Ran 18 tests in 0.241s
OK
PASS: actual radio node rejects current incapacitation, death, ownership and faction changes despite cached inventory; one-second capability refresh remains explicit
PASS: Southern finite maintenance stock preserves weapons/clues and optional transport, historical Western fixture stays separate; native capacity/consumption untested
PASS: optional transport deferred behind required readiness, bounded once-only spawn/omission, isolated cleanup, occupied-candidate retention and required-default preservation
PASS: actual diagnostic fallback runs only on failed missing-context call, derives unique native pilot door, preserves stock eligibility and restores prior index on success/failure; diagnostics mutate no game state.
PASS: actual native-prelude cleanup restores only original changed damage, refuses stale/incapacitated/aboard teleport; bounded five-seat/four-door fixture wiring checked. Native execution remains pending.
PASS: actual CreateTransport requires successful scoped Configure after handbrake, preserves ordinary vehicles, tracks spawned entity before failures and never treats failed lock registration as ready.
PASS: actual preparation Configure guards/idempotence/breach preservation, security eligibility/final current-body server mutation and all scoped action guards; all five seat/four door resource overrides. Native hold, prefab merge, replication and boarding remain unverified.
PASS: production vehicle alarm single trigger/replica completion/no replay, fixed deadline/readiness wait, failed audio, dedicated server, moving exact handle, destruction/native end/deletion/clock and mission teardown. Native sound and multiplayer delivery require engine qualification.
PASS: production alarm emitter/receiver original time/location, explicit native queue only, 32-entry cap, 50m local witness eligibility, bound perception, native-super preservation; actual engine broadcast/hearing remains unverified.
PASS: actual optional candidate barrier, exact callback/custody proof and unchanged mine/primary snapshots; no native transfer claim
Native finite mine-stock runner: parser, scope, exclusions and command pass
PASS: actual bounded native mounted proof/detached payload/deadline/cleanup methods, production-only setup and isolated runner selector
PASS: actual one-existing-convoy candidate readiness, sender-root identity, incomplete cargo refusal and fixed three-candidate bound
PASS: actual once-only native dry query, exact before/after slots, native refusal, shutdown; shared bounded discovery and distinct opt-in verdict
PASS: actual completion selector and pre-cleanup variant capture preserve separate radio and eligibility verdicts
PASS: actual cargo diagnostic stages separate absent/foreign magazines, used/empty/invalid rounds, well mismatch and exact truck storage/attachment without mutation
PASS: actual native courier witness rejects missing radio/custody/swap/reboard evidence; CLI opt-in bounded; native success remains unqualified
PASS: actual courier constructor/Tick waits for preparation, returns before physical checks, preserves fixed deadline and sticky stop/failure; Enfusion startup awaits native verification
PASS: actual arranged native alarm fixture deadline, single emit, natural-route observation, original timestamp/area/detail assertions, natural observer proximity/activation wait, failure cleanup and independent canonical-body restoration; native delivery itself remains unqualified.
PASS: actual convoy cover observation/snapshot/uplink/HOLD/RESUME/cleanup transitions; native boundaries mocked, non-convoy runner opt-in refused
Enemy optics actual-service ownership, preservation, callback, deadline and bounded-inspection policies passed
PASS: actual delivered cover freshness/lineage/replay and canonical executor; owned waypoint-only hold, one resume at preserved route index, invalid ownership/crew/ledger refusal and fail-closed native recreation
PASS: actual Stinger show/set/help state precise actor-roll effects; read-only help, bounded values, malformed syntax and failed-save preservation; no rerolls/gameplay edits and no native persistence claim
PASS: new/retasked search and radio delivery ammo gates; active tasks and delivered release preserved
HQ convoy delivered-report planning and downlink regressions passed
PASS: actual own-inventory ammo inspection deduplicates loaded/carried/shared wells, separates chambers/launchers, freezes scalar snapshots and treats unsupported/capped/foreign inventory as unknown
PASS: actual carried PMN4 inventory, original-owner guards, bounded deduplication, independent unknown state and detached counts
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
PASS: actual HQ original convoy-root admission rejects wrong force/server/group and never supplies replacement lookup
PASS: production mounted structural seat scan ignores >128 carried/cargo descendants, shares exact native mount/magazine ownership, preserves attachment seats and exact occupants, rejects unknown/cyclic/oversize structures; native binding still requires qualification.
PASS: native body fixture uses existing immutable actors, real production LOS/queued uplink, pre-delivery isolation, actual status overlap, bounded cleanup and no fabricated reports/spawns
PASS: actual native fixture lookup selects exact BODY kind/identity/message from bounded evaluations, never sighting-only Get
PASS: actual ammo snapshot comparison checks every scalar/category flag; native probe requires real roster rescan, loaded-round lower bound and separate immutable pending/Watch objects
PASS: actual delivered slot-union bodies preserve overlap/disjoint evidence, replay idempotence, status subset integrity, full-wipe closure and formation-local bounds
test_review_added_allowed_media_invalidates_snapshot (__main__.ReviewTests.test_review_added_allowed_media_invalidates_snapshot) ... ok
test_review_added_source_directory_rejected (__main__.ReviewTests.test_review_added_source_directory_rejected) ... ok
test_review_loose_root_resource_and_symlink_rejected (__main__.ReviewTests.test_review_loose_root_resource_and_symlink_rejected) ... ok
test_review_metadata_media_and_sidecars_remain_allowed_and_bound (__main__.ReviewTests.test_review_metadata_media_and_sidecars_remain_allowed_and_bound) ... ok
test_review_missing_link_rejected (__main__.ReviewTests.test_review_missing_link_rejected) ... ok
test_review_package_guard_sees_new_scripts (__main__.ReviewTests.test_review_package_guard_sees_new_scripts) ... ok
test_review_retargeted_private_link_rejected (__main__.ReviewTests.test_review_retargeted_private_link_rejected) ... ok
----------------------------------------------------------------------
Ran 7 tests in 0.062s
OK
PASS: actual report methods reproduce old starvation; status-first scheduler delivers check-ins and requires 30s without combat or actual visible contacts before negative reports
PASS: actual actor group lookup retains controlled character membership when seated/inherited vehicle agents differ; missing control or parent refuses
.................
----------------------------------------------------------------------
Ran 17 tests in 3.333s
OK
PASS: actual convoy motion thresholds, native-only proof boundaries, physical cargo/crew ownership and pre-launch runner restrictions
PASS: actual filled rotated-footprint TraceBox and nine terrain/water samples; broad tree/cable bounds alone accepted, actual collision/nonfinite trace refused, nonzero sweep and ENTS/OCEAN flags, bounded diagnostic query and reset
PASS: actual road interpolation/projection/orientation, six35m starts,200m forward tail, preserved bends, short/far/degenerate/nonfinite/overdense/hairpin refusal and deterministic candidate ties
PASS: actual authenticated convoy dispatch, active/ready admission gates, canonical receipt, safe unconsumed preflight retry, pool refusal, retained partial failure and consumed no-retry
PASS: actual native readiness exact membership, one-time per-vehicle ledger admission/reservation, partial readiness retry without duplicate records and one-pass56-item cargo allocation without replenishment
PASS: actual per-vehicle readiness reasons, native agent/activity counts, intended-seat diagnostics, five-second throttle and read-only observation
PASS: actual convoy dispatch validates before receipt consumption, consumes once before native mutation, retains all12 partial-failure paths, accepts the selected non-USSR enemy, and allocates exact19 bodies without capacity shrinking
PASS: own memberless prefab disables automatic spawn before initialization; actual admission rejects populated, immediate or authored-slot templates before finite crew creation
PASS: actual native seated-group arrival outside35m, native waypoint removal, idempotent advance, and convoy waypoint idempotence/arrival/deadline, missing/dead/captured/reparented crew refusal, failed native waypoint release, original vehicle/member preservation and no replacement
PASS: actual convoy receipt identity/one-use, shared60-body and128-formation caps, outstanding/native-ledger accounting, exact19-body composition, source reuse, mode/client guards and no consumed receipt refunds
PASS: actual supply route cycling/arrival/stops, finite startup bounds, contact freshness, dismount hold, quiet interval, interrupted boarding, timeout and lost-truck release
PASS: moving-convoy perception boundaries and scoped individual/group abandonment priorities
PASS: actual supply startup reasons expose unchanged body budget/requirement, journal only failure changes, preserve retry cadence/caps and report the true final refusal
PASS: actual StartOne plus actual pool preserve unconsumed receipt retry, reject consumed replay, skip impossible new-budget surveys, retain equality, retry caps and journal dedup; no FPS claim
PASS: actual admission seeds use exact installed loaded prefab, reject replacement/foreign/projectile paths and preserve bounded immutable identity
PASS: actual primary-before-mounted one-shot batch, shared96/128 caps, physical snapshot headroom, original ownership, callback refusal and admission pinning
PASS: actual bounded HQ query validates only existing original binding without admission or replacement lookup
PASS: exact optional PMN4 startup, primary callback independence, original owner,128 capacity/callback limits, terminal no-retry and callback-proven freeze
PASS: production convoy spacing, physical arrival, stable follower targets, supply ownership, leader promotion and bounded stuck recovery
PASS: convoy combat keeps native manoeuvres for unchanged contacts and refreshes when contact moves
PASS: native convoy proof excludes pre-departure movement and ends via explicit fixture reset, not prohibited player death
PASS: boarding retries only after approach/seat progress stops, capped at three, with delayed native reissue and completed-team preservation
PASS: slow only owned vehicles near fit dismounted infantry; ignore passengers, casualties and released teams/vehicles
PASS: restore missing native driving registration only for healthy owned seated crews; preserve existing association and refuse invalid/released vehicles
PASS: actual body observer enforces owned physical roster, local death-only candidates, native trace gating, budget/cadence/caps, immutable body-only snapshots, radio retries and confirmed suppression
PASS: own initial roster, explicit retained corpse evidence, unconscious/missing/ref transfer guards, fixed strength, no replacement adoption, detached samples, surviving radio sender, immutable convoy root/ledger, mounted capture release and lost-root unknown
PASS: delivered-only status snapshots, two missed check-ins/reply deadline, last reported coordinates, episode/replay guards, confirmed-loss idempotence, detached/validated mounted payload replacement 256-record cap and detached carried-mine radio delivery/chronology
PASS: actual failed-retask deadline rollback plus assignment cancellation/release preserves radio ownership, native waypoint lifecycle and failed-order retry boundaries
PASS: actual force ledger, finite casualties/identity/cap, routes/arrival/elevation/overshoot, server and physical guards, staggered 256-record simulated hour without world queries
PASS: actual equipment coordinator registration dedupe, startup delay, five member scans, finite component retries, unregister/stop terminal behavior and 256-group bound
PASS: actual percentage selection, native/preferred launcher preservation, failure/removal fallback, pending-operation quarantine, capture, finite two-mine grants and no replenishment
PASS: automatic inventory one-shot roll, exact item ownership, finite compatible ammo, rejection, capture/stop, deletion, loot and late callback quarantine
PASS: enabled/valid catalog eligibility, category restrictions, content filtering, GUID deduplication across factions and bounded catalogs
PASS: actual engineer mine preparation/deadline, original custody/identity, once-only callback removal, cancellation quarantine, withdrawal/clearance, native refusal and owned-action cleanup; native execution untested
PASS: actual road mine-site annulus/bend geometry, deterministic bounded candidates, server/query limits, and native ground/water/obstruction rejection; no runtime placement claim
PASS: actual HQ mine admission, one site query per tick, maximum two active/32 retained jobs, delivered-only original post, once-per-unit refusal latch, 256-item ceiling and maintenance/teardown ownership
PASS: actual objective heading/threat/approach rules, persistent doctrine weight, fresh-contact coverage invalidation, stale-sweep rejection and atomic radio retask ownership
PASS: actual bounded delivered-negative coverage, replay/freshness/expiry/invalid guards, oldest eviction, small-circle and nearest-unswept selection, reserved-cell exclusion and cleanup
PASS: actual HQ active/pending reservations, interruption, committed replacement, bounded coverage and unchanged force counts
PASS: actual bounded pursuit roles/objectives/scores, stale search degradation, physical/busy/home guards, finite lifetime and two-bearing escape gap; no hidden player reads or spawning
PASS: actual HQ memory rules/service preserve delivered snapshots, chronology, replay bounds, decay, motion limits, identity and negative-search revisions
.......
----------------------------------------------------------------------
Ran 7 tests in 0.023s
OK
PASS: actual session Tick + journal router delivers each grant completion and new HQ line once, without repeats on empty/unavailable feeds or unauthorized ticks
.....
----------------------------------------------------------------------
Ran 5 tests in 0.347s
OK
PASS: actual current-controller/admin/mode authorization, per-round anti-replay, token-rotation refusal, command/snapshot throttles and client scope; owner-only replies and player-tool cleanup wiring
PASS: mission provider registration is idempotent, optional dispatch is ordered, status aggregates, journals preserve cursors, aliases stay with their addons and topic help is bounded
PASS: actual menu command routing covers all fourteen settings, rejects unsupported keys, gates companions, and matches unique authored widgets
PASS: explicit weapon retention buttons use the same ready/authorized server command path
PASS: actual summaries preserve queued/delivered meaning, clear counts and IDs; raw records, legacy display, cursor gaps and RPC limits remain intact
PASS: actual admin body authorization, god restoration, vanilla item deposit, callback completion/failure, timeout quarantine and stop/revocation paths
PASS: same-body revoke/regrant preserves pending insertions and timeout quarantine; new-body binding isolates late callbacks and never inherits god mode
PASS: actual Intel commands distinguish status/start/failure, preserve authorization gate and reject malformed requests; spent ledger is idempotent, server-only and bounded
PASS: actual reroll snapshot, authority, cancellation, ownership, accepted operations, quarantine, bounded work and stop methods; no native runtime claim
PASS: production Intel feedback coalescing, rough secrecy, rate limit, bounded dedupe, local/remote delivery and round cleanup; native UI/RPC not exercised
PASS: actual per-squad bounded report selector rotates visible targets, survives ordering/turnover, records only queued attempts, and preserves radio intake ordering
PASS: actual action denial/clearing, server request failure, single submitted-result feedback, current rescuer identity and terminal/stop suppression; native UI/RPC pending
PASS: actual physical denial precedence and transport-seat occupancy/reservation/access/lock checks
PASS: actual initial admission exhaustion and ServerTick grace; new/pending/empty/controller/life guards, normal death preserved
......................
----------------------------------------------------------------------
Ran 22 tests in 0.242s
OK
......................
----------------------------------------------------------------------
Ran 22 tests in 23.599s
OK
..................
----------------------------------------------------------------------
Ran 18 tests in 2.737s
OK
.........
----------------------------------------------------------------------
Ran 9 tests in 2.166s
OK
...............
----------------------------------------------------------------------
Ran 15 tests in 0.993s
OK
PASS: actual field result/braking observer and Chat dispatch rules; one finite fixed candidate, deferred callback failure and guarded cleanup; no native measurement
PASS: actual opt-in terrain audit records one fixed1681-point grid, preserves original survey refusal/success and exact no-allocation scope; malformed heights stop without retry; no native data acquired
....
----------------------------------------------------------------------
Ran 4 tests in 0.556s
OK
PASS: actual field PI/ramp/vector caps, antiwindup, braking hypothesis, immutable admission limits and segment bounds; no native physics tested
PASS: actual100m whole-field survey sampling/4096cap, rotated coverage, all-node terrain and native trace refusal; original certificate lineage retained; no native qualification
PASS: actual QualifyField preserves original identity/footprint/time, orders complete surveys before issuance, and refuses failed stages/moved body/expired or changed world; native boundaries faked
PASS: WORKBENCH first-refusal diagnostics preserve ordinary predicates, query order/count/budget and opt-in scope; no native logging run
PASS: actual field startup delegation, immutable lease/target, braking/settling/cancel transitions, early abort, callback scope, physical terminal policy and shared landing demand; native boundaries faked
PASS: actual inherited airborne pre-CLIMB cancellation enables verified native autohover once, refuses failed enable and never writes after capture
PASS: actual Core maintenance/default/tick/stop methods; empty/populated authority, terminal reentry, no tactical resume or new scheduler; native boundaries substituted
PASS: actual finite registration, unique claims/tokens, retention/cancel/stop, readiness gating, capture/expiry retirement and bounded cross-kind order history and typed field/route construction; native boundaries faked
PASS: actual WORKBENCH route observer returns exact retained route subtype and refuses absent/field controllers
.....
----------------------------------------------------------------------
Ran 5 tests in 0.610s
OK
......................
----------------------------------------------------------------------
Ran 22 tests in 0.188s
OK
................
----------------------------------------------------------------------
Ran 16 tests in 9.415s
OK
......
----------------------------------------------------------------------
Ran 6 tests in 0.017s
OK
PASS: actual production bridge lookup, lease/world/mode/seat/capture guards, no allocation, native super ordering and read-only fixture hooks
...............
----------------------------------------------------------------------
Ran 15 tests in 0.050s
OK
.............
----------------------------------------------------------------------
Ran 13 tests in 4.403s
OK
PASS: actual route gain/caps/braking, callback selection, old landing/cancellation control and matching read-only telemetry
..............................
----------------------------------------------------------------------
Ran 30 tests in 0.365s
OK
..............
----------------------------------------------------------------------
Ran 14 tests in 0.177s
OK
.........
----------------------------------------------------------------------
Ran 9 tests in 0.122s
OK
PASS: actual gate observer binds native registered action/context and current life, reads accumulated progress, refuses stale bindings and never revives outside original bounds
PASS: actual read-only look observer methods enforce explicit scope, pinned native camera/body/identity, normalized pose, terminal cancellation and original sample/time bounds
...........
----------------------------------------------------------------------
Ran 11 tests in 0.063s
OK
.......................
----------------------------------------------------------------------
Ran 23 tests in 0.030s
OK
PASS: actual initial WAITING task/guide copy, configured duration, unchanged interruption and rounded progress; native task assertion pending
........
----------------------------------------------------------------------
Ran 8 tests in 0.012s
OK
PASS: actual inventory adapter scope, grid placement, sole compatible host, refresh reuse, rollback, foreign hierarchy refusal and exactly-once native delegation; native compatibility pending
.................................................................................
----------------------------------------------------------------------
Ran 81 tests in 0.470s
OK
......
----------------------------------------------------------------------
Ran 6 tests in 0.064s
OK
.................
----------------------------------------------------------------------
Ran 17 tests in 0.004s
OK
...........
----------------------------------------------------------------------
Ran 11 tests in 0.063s
OK
.........
----------------------------------------------------------------------
Ran 9 tests in 0.310s
OK
PASS: actual observer nonce, admission pins, baseline/menu sequencing, snapshots, bounded clocks/samples, cleanup and one-attempt latch; native untested
PASS: actual corridor caps/height/hold and whole-rectangle survey bounds, terrain refusal, native trace refusal and exact certificate lineage; native route unqualified
PASS: actual route entry, fixed corridor/target, hover hold, cancellation landing freeze, shared lease/capture/deadline gate and unchanged native startup/tick sequence
PASS: finite opt-in route fixture, original native input order, meaningful physical-arrival evidence and guarded cleanup; no native launch
PASS: actual Chat route step result dispatch and scoped completion/cleanup wiring; six real early-parser refusal paths leave no prefix/profile output
PASS: actual retained-service fixture entry, immutable controller/token/deadline/count bindings, observer getter and cleanup ownership ordering; native route validation pending
PASS: actual measured cancellation gate, one-shot retained service Stop, no premature drain, immutable lease, fresh real controller readback and separate physical cancellation result policy
PASS: actual rough-intel objective selection, exact precedence, source grid dimensions and unchanged other-phase dispatch; native UI pending
.................................
----------------------------------------------------------------------
Ran 33 tests in 0.090s
OK
...............
----------------------------------------------------------------------
Ran 15 tests in 0.035s
OK
PASS: actual preparation status scope, persistent updates, spinner restoration, placeholder replacement/deletion/destruction, native observation persistence/timeout; rendering remains native-pending
PASS: actual guide/observer monitors retry native refusal, cache successful delivery, deduplicate and preserve living/preparing/spectator boundaries; native UI not exercised
PASS: actual native-end shutdown, existing terminal snapshots, reentrancy, unchanged native end data and stale preparation guards
....
----------------------------------------------------------------------
Ran 4 tests in 1.219s
OK
PASS: actual three-state result wording and UI refresh; stale winner IDs never manufacture escape
...........
----------------------------------------------------------------------
Ran 11 tests in 0.104s
OK
PASS: actual immutable target, bounded autohover demand, drift refusal, five-second hold and unchanged qualification/deadline
PASS: actual admission attempt budget bounds blocked/missing prerequisites; preparation, spent life and async pending remain protected
PASS: delayed admission retry retains controller ownership across same-account recycled connection IDs
PASS: actual scene deadline overrides delayed native preload only for rejection; late completion cannot assign, ordinary verified admission preserved
PASS: actual action permission matrix unchanged; useful phase/intel/consciousness denials, stale reason cleared, native door denial preserved; no native UI claim
.....
----------------------------------------------------------------------
Ran 5 tests in 0.221s
OK
PASS: actual aircraft cancellation/stage rules, ground-only completion, expiry/capture faults, input ownership and no physical shortcuts
PASS: actual exact-instance single-use qualification, native-clock staleness/movement refusal, footprint bounds and ownership-safe ground/fault cleanup
PASS: actual optional screenshot helper flag/identity/world/life revalidation, one queued attempt, delayed capture and mission/world cleanup; no native image/presentation claim
PASS: actual yard diagnostic exact registered prison ownership, eight native-bound corner projections, no root-sibling escape, bounded duplicate/deep/wide hierarchy traversal; native projection/mask still unmeasured
PASS: actual CurrentActor, SpawnPosition and observer-selection methods reject pending/unregistered/replaced/recycled/foreign/dead bodies; canonical selection/cycling, unconscious following and prison/geometry fallback preserved; native boundaries adapted
PASS: actual native-map fixture ownership, cleanup and callback evidence fail closed; native execution remains separate
PASS: actual shared-map callbacks bind exact map/config/root, preserve replacement UI/camera, defer focus, and remove only owned delayed work
PASS: actual Intel/HQ methods and one-shot qualified readiness handoff deliver late actors once; duplicate readiness, accepted spawn, pickup/drop, death and original negative rolls do not mint assignments
PASS: Workbench-only read accessor rejects unknown/nonserver identities; Chat observes all distinct ready crew before existing shell-depletion mutation
PASS: actual native-event latch survives deselection, requires exact activity/order, detaches before cleanup, preserves failure/timeout and never infers completion from physical shot count
.........
----------------------------------------------------------------------
Ran 9 tests in 0.091s
OK
PASS: actual refresh-fixture gates pin immutable observations/actual downlinks/original activity, reject unaccepted or relabelled commits, stop queueing early and require all queued contacts claimed before replay
..........................
----------------------------------------------------------------------
Ran 26 tests in 0.174s
OK
PASS: actual refresh scheduler/delivery/cancellation/projectile methods reject interrupted or replayed reports, retain committed ownership, preserve immutable snapshots/aim geometry and isolate stopped or replaced orders; native radio/crew behavior remains separate
.....................
----------------------------------------------------------------------
Ran 21 tests in 0.037s
OK
...........
----------------------------------------------------------------------
Ran 11 tests in 0.037s
OK
PASS: actual full-salvo gates require eight fresh committed physical launches, natural closure and exact finite inventory; reject partial/extra/replayed events
PASS: actual reason/availability guidance and refresh matrix; no-target copy omits cycling, hint retry retained, existing command/admin paths unchanged; native UI pending
PASS: actual client camera policy closes immediately on healing or mission end; late unconscious metadata cannot keep the view active
PASS: actual input dispatch, one press per edge, menu-held suppression; actual revival camera handoff with editor close/retry, missing camera, replacement body and stopped round
PASS: first-person pose survives missing samples without drift, follows body motion/rotation, resumes fresh pose and cannot leak between targets
................usage: test_native_package.py [-h] [--project {core}] --session SESSION
--compat COMPAT [--steam STEAM]
[--timeout TIMEOUT]
[--external-addons EXTERNAL_ADDONS]
[--silent-workbench | --exit-after-init]
[--continue-on-failure]
test_native_package.py: error: argument --exit-after-init: not allowed with argument --silent-workbench
................................
----------------------------------------------------------------------
Ran 48 tests in 11.567s
OK
.......
----------------------------------------------------------------------
Ran 7 tests in 0.228s
OK
..............
----------------------------------------------------------------------
Ran 14 tests in 2.002s
OK
....
----------------------------------------------------------------------
Ran 4 tests in 0.275s
OK
....
----------------------------------------------------------------------
Ran 4 tests in 0.062s
OK
PASS: actual finite-courier age, token, exact ownership/callback and delivered-status admission reject stale, replayed, captured, canceled and ambiguous work
PASS: actual native-gun ownership gate rejects player/foreign/replaced/dead occupant, faction change, missing seat and missing registry
PASS: four-battery courier selection preserves pending trip/report/transfer identity, skips unavailable crews, and selects the next depleted battery without new stock
PASS: 64 bounded distinct storage candidates; native gates, five-store barrier and finite-stock ownership retained; native placement pending
PASS: 128 coarse+80 local refinement+169 airport grid candidates retain all native clearance gates; real terrain untested
PASS: actual prison registration/crossing policies reject missing/duplicate/destroyed initial gate, incomplete ownership/scan, outside-only body, jumps and stale samples; physical exit independent of later gate damage
PASS: actual prison door execution blocks direct AI/UI bypass while locked and delegates unchanged native action once after unlock and permission approval
..................
----------------------------------------------------------------------
Ran 18 tests in 1.907s
OK
.....
----------------------------------------------------------------------
Ran 5 tests in 1.076s
OK
PASS: native local-admission snapshot rejects changed life/key/body/participant/pending state; authentication is not simulated
PASS: actual mortar report ledger prevents duplicate response after cancellation, expiry and interleaved reports; native scheduler separate
.........
----------------------------------------------------------------------
Ran 9 tests in 0.012s
OK
....
----------------------------------------------------------------------
Ran 4 tests in 0.128s
OK
PASS: actual aim renewal requires fresh same-report solve and original-command equivalence; native firing untested
........
----------------------------------------------------------------------
Ran 8 tests in 0.012s
OK
PASS: actual startup/generation/ownership/timeout/callback policies and native-counter wait; integration preserves one-shot allocation and pending-crew cancellation
PASS: rapid mortar cycle counts eight physical rounds once and waits for native completion without a ninth aim or shell
PASS: actual probe binds native events to fresh immutable commits, permits delayed emission, rejects unrelated expiry closure and premature stop
PASS: actual noSplash Load body requires both explicit diagnostic and noSplash, preserves vanilla otherwise, and handles repeated Load/reload
PASS: actual fixture method permits one native resilience operation and restores either prior protection state, including failure paths
PASS: actual safe-exit boundary policy, native action/door selection, stop/cache cleanup, separate old mechanism and opt-in runner contracts
PASS: actual one-shot deadline/stability policies and preparation ownership, fuel, cleanup integration contracts
PASS: pending-only cancellation retires copied instance intent, preserves physical/control actors, and stops once
PASS: actual short-cast hit, upward support normal, no self support and no dynamic support
PASS: actual committed-ticket structure preserves reservation after death, rejects missing bodies/seats and ends at observation expiry
PASS: actual pending callback expires an empty-server reservation once, preserves its full lease, and cancels on completion/Stop
PASS: rescue lease expiry/reordering, fresh five-second settling, independent rescue ranges and grounded upright aircraft motion boundaries
PASS: requested guard population requires complete physical conscious membership before deadline
......................................
----------------------------------------------------------------------
Ran 38 tests in 0.016s
OK
..........
----------------------------------------------------------------------
Ran 10 tests in 0.003s
OK
.....
----------------------------------------------------------------------
Ran 5 tests in 0.933s
OK
PASS: authored radio/optional-site bounds and physical horizontal/vertical boundaries
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
PASS: all phase transitions, terminal states, defence boundaries, stale/future observations, intel discovery
PASS: Core document-discovery alias, companion-only alias exclusion, strict integer parsing and setting boundaries
PASS: player admission phase/life/identity/controller matrix, preload displacement limits, pending reservation overlap and owner exclusion
PASS: actual gate and pre-inventory document guards reject noncanonical/faction/life/disconnect/server mismatches; canonical reconnect and unconscious carried intel preserved
PASS: WB-only native fault injection restores both body mutations before checks/returns and requires eligible held-document negative/positive proof; runtime pending
PASS: actual discovery coordinates disclose stable 500m cell center until identified, then exact point, including negative/boundary coordinates
PASS: actual local admission context/selection/latch, same-round late identity, replacement/mode failure, fresh round and untouched network path
PASS: prison search packs 16 unique 3m-spaced inside-wall centers, prioritizes inner/edge positions and never bypasses clearance
PASS: physical body occupancy rejects overlap, permits diagonal neighboring slots, and excludes own body and unrelated broad-phase bounds
PASS: recovery state excludes dead bodies, preserves reservations, requires controlled rescuers and distinguishes empty/all-dead teams
PASS: authority-scoped slow recovery, bleeding pauses resilience, medicine unaffected, player-only lethal damage cap without healing
PASS: bleeding severity survives low health, retains armour, causes no knockout and restores the actual damage/blood-loss cap
PASS: viable passive recovery survives native delay; bleeding, disabled/full effects and low-blood resilience do not block defeat
PASS: every minute round-trips, malformed clocks rejected, defaults limited to added keys, progression bounds and day duration aligned
PASS: native settings policy matches calendar boundaries 1900-2050, date/profile parsing is strict, authored defaults preserve old worlds
PASS: view-distance bounds, default, save failures, command parsing, temporary ownership, server/platform limits and lifecycle wiring
.....
----------------------------------------------------------------------
Ran 5 tests in 0.538s
OK
.
----------------------------------------------------------------------
Ran 1 test in 0.318s
OK
PASS: radio authorization/discovery/phase matrix, exact distance limits, defender handover, interruption, empty samples, clock regression and duration boundary
PASS: actual radio feedback policy, initial wait, interruption persistence, resumption and terminal/new-round reset
...............
----------------------------------------------------------------------
Ran 15 tests in 1.918s
OK
..............................................
----------------------------------------------------------------------
Ran 46 tests in 0.899s
OK
PASS: legacy values preserved, unsupported fields reported, invalid data rejected, existing files protected, runtime bounds aligned
PASS: failed initial settings promotion leaves defaults writable after restart; prior/fallback saves survive copy, readback and mismatch faults
PASS: real-carrier shortest-hop paths, 500m boundary, three-hop cap, no-manpack failure, three-second originating-call interruption, unchanged downlink hop timing, completed-hop survival, interrupted final uplink, radio loss, capture, motion, timeout, reset and network bounds
PASS: migrated aircraft availability policy (controller migration still pending)
PASS: migrated salvo offsets are deterministic, spread and bounded (native firing and complete salvo qualification are separate)
PASS: 35 prefabs have unique saved root entity IDs
PASS: 299 original script entries tracked across 18 unfinished responsibilities
PASS: 1 isolated addons, acyclic dependencies, 56 unique resources, exact vanilla/authorized external references
All repository checks passed. Native compilation and multiplayer tests are separate requirements.
@@ -0,0 +1,39 @@
{
"implemented": "One bounded original camp cache -> existing responder -> original ammo truck job, fair delivered radio dispatch and two separately proved finite native inventory legs. No generated stock/actors or arbitrary later deposits.",
"source_files": 403,
"regression_programs_passed": 277,
"validation_order": "Full277 programs passed initial integration. Native compile failure retained; only helper rename and getter formatting corrected; four relevant actual-method programs rerun and passed on corrected source.",
"native_evidence": "native-2026-10-02-ground-depot-integration",
"native_assertions": 63,
"native_rounds": 1,
"native_script_failures": 0,
"retained_installed_resource_errors": 13,
"native_scope": "Frozen corrected-source compilation and scripted normal escape integration; no autonomous depot pickup/walking/delivery or multiplayer qualification.",
"initial_native_failure_preserved": true,
"independent_inline_stop_failure_reproduced_and_fixed": true,
"independent_original_identity_and_used_magazine_mutations_failed": true,
"cleanup_confirmed": true,
"preservation": {
"original_missions": {
"files": 533,
"unchanged": true
},
"existing_playtest": {
"files": 409,
"unchanged": true
},
"inherited_unstaged": {
"files": 61,
"preserved": true
}
},
"release_qualified": false,
"remaining": [
"Native depot navigation/action anchor reach/two-leg delivery",
"Human full escape",
"Real multiplayer/JIP/reconnect/spectators",
"Physical maintenance/resupply qualification",
"Equivalent-workload FPS",
"Clean packaging/release"
]
}
@@ -0,0 +1,5 @@
{
"exit_code": 0,
"registered_programs": 277,
"scope": "Complete canonical /tmp run against initial integrated depot source. Subsequent native compile repairs require focused revalidation."
}
@@ -0,0 +1 @@
PASS: actual depot HQ lifecycle, existing planner priority, server/mode/owner gates, idempotent polling and owner replacement
@@ -0,0 +1 @@
PASS: actual depot radio/planning/two-leg state transitions, fixed deadline, late proof quarantine, finite import and no adoption after Stop
@@ -0,0 +1 @@
PASS: actual authored identity capture, READY-only detached provenance, same shared stock admission, completed exact two-leg proof, lifetime caps and Stop no late adoption
@@ -0,0 +1 @@
PASS: actual full depot leaf, exact custody, isolated callbacks, finite reservation, false/unknown and Stop quarantine, once-only delivery and caps; native movement unqualified
@@ -0,0 +1,12 @@
check: /home/jakub/devel/escapistsrereintroduced/.build/death-diagnostic-2153/test-tmp/err-policy-zwkppeca/check.cpp:250: int main(): Assertion `a.Tick(0)==-1&&!a.Submitted()&&f.source.calls==0&&f.reservation.ReleaseUnsubmitted()' failed.
Traceback (most recent call last):
File "/home/jakub/devel/escapistsrereintroduced/.build/ground-depot-leaf-review-0303/tests/test_ground_depot_transfer.py", line 80, in <module>
run(pre+translated_reservation()+code+'\n'.join(callbacks)+main)
~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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 '['/home/jakub/devel/escapistsrereintroduced/.build/death-diagnostic-2153/test-tmp/err-policy-zwkppeca/check']' died with <Signals.SIGABRT: 6>.