Files
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

301 lines
21 KiB
Python

"""Run the actual bounded memory implementation with value-only native adapters.
No fake world polling: identity stubs deliberately have no position/health API.
"""
import os,re
from pathlib import Path
from policy_harness import ROOT, body, run
path = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_HQMemory.c'
source = path.read_text()
for forbidden in ('GetOrigin(', 'GetControlledEntity(', 'GetPlayerManager(', 'GetDamageManager(', 'GetWorld('):
assert forbidden not in source
assert max(map(len, source.splitlines())) <= 120
# Native Enforce weak parameters do not retain a block-local sanitized report.
# Guard the owner scope that crashed on real radio delivery. The raw-pointer C++
# adapter below checks values/caller isolation, not native reference counting.
ingest = body(path, 'bool Ingest(ERR_HQReport report, float now)')
ingest = re.sub(r'//[^\n]*|/\*.*?\*/|"(?:\\.|[^"\\])*"', '', ingest, flags=re.S)
owner = ingest.index('ref ERR_HQReport alarm;')
branch = ingest.index('if (kind == ERR_HQMemoryKind.ALARM)')
allocate = ingest.index('alarm = new ERR_HQReport();')
append = ingest.index('track.Append(report, now);')
assert owner < branch < allocate < ingest.index('report = alarm;') < append
for position, depth in ((owner, 1), (allocate, 2), (append, 1)):
assert ingest[:position].count('{') - ingest[:position].count('}') == depth
code = source
for kind in ('ERR_HQReport', 'ERR_HQMemoryTrack'):
code = code.replace('ref array<ref ' + kind + '>', 'Array<' + kind + '*>')
for kind in ('int', 'float'):
code = code.replace('ref array<' + kind + '>', 'Array<' + kind + '>')
code = code.replace('protected ', '').replace('ref ERR_HQReport ', 'ERR_HQReport ')
code = re.sub(r'\b(ERR_HQReport|ERR_HQBelief|ERR_HQMemoryTrack) ([A-Za-z_]\w*)', r'\1* \2', code)
code = re.sub(r'class (\w+)\n\{', r'class \1\n{\npublic:', code)
code = re.sub(r'^}', '};', code, flags=re.M)
code = re.sub(r'\bvector\b', 'Vec', code)
for cls in ('ERR_HQMemoryRules', 'ERR_HQMemoryKind', 'Math', 'Vec'):
code = code.replace(cls + '.', cls + '::')
for name in ('report', 'last', 'belief', 'previous', 'track', 'alarm'):
code = re.sub(r'\b' + name + r'\.', name + '->', code)
code = re.sub(r'm_Tracks\[([^\]]+)\]\.', r'm_Tracks[\1]->', code)
code = code.replace('Latest().', 'Latest()->').replace('null', 'nullptr')
code = re.sub(r'^(\s+(?:IEntity|Vec|bool|float|int|string|ERR_HQReport\*|ERR_HQMemoryTrack\*) \w+);$',
r'\1{};', code, flags=re.M)
# Execute the production delivery boundary against this actual memory service.
# World/radio/body adapters below only isolate unrelated side effects.
accept = body(Path(os.environ.get('ERR_HQ_SOURCE', ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c')),
'protected void Accept(')
accept = accept.replace('protected ', '').replace('null', 'nullptr')
accept = re.sub(r'\b(ERR_HQReport|ERR_HQBelief) (\w+)', r'\1* \2', accept)
for name in ('report', 'previous', 'contact', 'belief'):
accept = re.sub(r'\b' + name + r'\.', name + '->', accept)
for cls in ('ERR_MissionRules', 'ERR_HQMemoryRules', 'ERR_HQMemoryKind', 'Math'):
accept = accept.replace(cls + '.', cls + '::')
accept = accept.replace('vector.DistanceXZ(', 'Vec::DistanceXZ(').replace('vector.Zero', 'Vec{}')
accept = accept.replace('string.Format(', 'Format(')
run(r'''
#include <cassert>
#include <cmath>
#include <limits>
#include <algorithm>
#include <vector>
#include <string>
#include <type_traits>
using string=std::string;
struct Identity {int id;};
using IEntity=Identity*;
struct Vec {
float v[3]={0,0,0};Vec()=default;Vec(float x,float y,float z):v{x,y,z}{}
float& operator[](int i){return v[i];}float operator[](int i)const{return v[i];}
Vec operator+(Vec b)const{return {v[0]+b[0],v[1]+b[1],v[2]+b[2]};}
Vec operator-(Vec b)const{return {v[0]-b[0],v[1]-b[1],v[2]-b[2]};}
Vec operator*(float b)const{return {v[0]*b,v[1]*b,v[2]*b};}
Vec operator/(float b)const{return {v[0]/b,v[1]/b,v[2]/b};}
float Length()const{return std::sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);}
Vec Normalized()const{return *this/Length();}
static float DistanceXZ(Vec a,Vec b){return std::hypot(a[0]-b[0],a[2]-b[2]);}
};
template<class T>struct Array:std::vector<T>{
void Clear(){this->clear();}int Count(){return this->size();}
void Insert(T v){this->push_back(v);}void Remove(int i){assert(i>=0&&i<Count());this->erase(this->begin()+i);}
bool Contains(T v){return std::find(this->begin(),this->end(),v)!=this->end();}
};
namespace Math {
template<class A,class B>auto Min(A a,B b){using T=std::common_type_t<A,B>;return std::min(T(a),T(b));}
template<class A,class B>auto Max(A a,B b){using T=std::common_type_t<A,B>;return std::max(T(a),T(b));}
template<class A,class B,class C>auto Clamp(A a,B b,C c){using T=std::common_type_t<A,B,C>;return std::clamp(T(a),T(b),T(c));}
float AbsFloat(float v){return std::abs(v);}float Pow(float a,float b){return std::pow(a,b);}
float Atan2(float a,float b){return std::atan2(a,b);}constexpr float RAD2DEG=57.295779513f;
}
struct ERR_HQReport {
int MessageId=0;IEntity Target=nullptr,Source=nullptr;Vec Position,Velocity;
float ObservedAt=-1;bool Distress=false,HasVelocity=false,Engaged=false;string TravelMode="unknown";
int SeenEscapists=-1,CasualtySlot=-1,CasualtyStrength=0;float DetailsObservedAt=-1;
string SeenWeapons="unknown",RoadStatus="road unknown",CasualtySourceId;
ERR_HQReport* Snapshot(){return new ERR_HQReport(*this);}
};
''' + code + r'''
ERR_HQReport Report(int id,IEntity target,float when,Vec pos={0,0,0},string mode="on foot"){
ERR_HQReport r;r.MessageId=id;r.Target=target;r.Source=target;r.ObservedAt=when;r.Position=pos;r.TravelMode=mode;return r;
}
bool near(float a,float b,float tolerance=.001){return std::abs(a-b)<tolerance;}
struct ERR_MissionRules{static bool ContactFresh(float t,float now){return ERR_HQMemoryRules::DeliveryFresh(t,now);}};
struct WatchAdapter{bool IngestBody(ERR_HQReport*,float){return false;}int IdentifiedBodies(){return 0;}
int Aggression(){return 0;}int HunterTarget(){return 0;}};
struct BodiesAdapter{void ConfirmDelivered(IEntity){}};
struct RecoveryAdapter{void ReportBody(ERR_HQReport*){}};
struct CoverageAdapter{void Forget(Vec,float){}};
struct JournalAdapter{void Write(string,string,int){}};
template<class... Args>string Format(string,Args...){return "delivered";}
struct HQDelivery{struct LocalCoverage{void Forget(Vec,float){}}m_LocalCoverage;
ERR_HQMemory m_Memory;WatchAdapter m_Watch;BodiesAdapter m_Bodies;RecoveryAdapter m_Recovery;
CoverageAdapter m_Coverage;JournalAdapter m_Journal;float m_NextAssignment=5000;
Array<ERR_HQReport*> m_Contacts;
''' + accept + r'''
};
int main(){
// Accepted fire-support contacts use the actual memory history, not a second
// looser pair estimate. Native transport is tested separately.
Identity contactActor{44};
for(int scenario=0;scenario<6;scenario++){
HQDelivery h;auto first=Report(1,&contactActor,1000,{0,0,0});h.Accept(&first,1000);
auto next=Report(2,&contactActor,11000,{300,0,0});
if(scenario==1){next.TravelMode="vehicle";next.Position={60,0,0};}
if(scenario==2){next.ObservedAt=2000;next.Position={10,0,0};}
if(scenario>=3){next.Position={60,12,0};}
if(scenario==4){auto close=Report(3,&contactActor,10000,{0,0,0});h.Accept(&close,10000);}
next.HasVelocity=true;next.Velocity={99,22,33}; // input must stay detached and untouched
h.Accept(&next,next.ObservedAt);
assert(h.m_Contacts.Count()==1&&h.m_Contacts[0]!=&next);
auto stored=h.m_Contacts[0];auto belief=h.m_Memory.Get(&contactActor);
assert(stored->HasVelocity==belief->HasVelocity);
if(scenario<3||scenario==4)assert(!stored->HasVelocity&&near(stored->Velocity.Length(),0));
else assert(stored->HasVelocity&&near(stored->Velocity[0],6)&&near(stored->Velocity[1],0));
assert(next.HasVelocity&&near(next.Velocity[0],99)&&near(next.Velocity[1],22));
auto equal=Report(10,&contactActor,next.ObservedAt,{900,0,0});h.Accept(&equal,next.ObservedAt+1);
auto older=Report(11,&contactActor,500,{900,0,0});h.Accept(&older,next.ObservedAt+2);
h.Accept(&next,next.ObservedAt+3); // duplicate identity and observation do not refresh contact
assert(h.m_Contacts[0]==stored&&stored->ObservedAt==next.ObservedAt);
if(scenario==5){auto close=Report(4,&contactActor,12000,{66,12,0});h.Accept(&close,12000);
assert(h.m_Contacts[0]->HasVelocity&&near(h.m_Contacts[0]->Velocity[0],6));}
}
using Rules=ERR_HQMemoryRules;
float nan=std::numeric_limits<float>::quiet_NaN(),inf=std::numeric_limits<float>::infinity();
assert(near(Rules::Confidence(0),1)&&near(Rules::Confidence(600),.5)&&near(Rules::Confidence(1200),.25));
assert(Rules::Confidence(-1)==0&&Rules::Confidence(1,0)==0&&Rules::Confidence(nan)==0&&Rules::Confidence(inf)==0);
assert(near(Rules::Radius(0,1.2,25),25)&&near(Rules::Radius(600,1.2,25),745));
assert(Rules::Radius(1,nan,25)>2000&&!Rules::Actionable(.5,2001)&&!Rules::Actionable(nan,20));
assert(Rules::RadiusGrowth(ERR_HQMemoryKind::SIGHTING,"vehicle")>Rules::RadiusGrowth(ERR_HQMemoryKind::SIGHTING,"on foot"));
assert(!Rules::DeliveryFresh(10,9)&&!Rules::DeliveryFresh(-1,9)&&!Rules::DeliveryFresh(0,120001));
assert(Rules::DeliveryFresh(0,120000)&&!Rules::DeliveryFresh(nan,0));
assert(!Rules::PositionValid({nan,0,0})&&!Rules::PositionValid({0,inf,0})&&!Rules::PositionValid({1000001,0,0}));
assert(Rules::MotionCredible(10,60,"on foot","on foot"));
for(float gap:{0.f,1.f,121.f,nan})assert(!Rules::MotionCredible(gap,10,"on foot","on foot"));
assert(!Rules::MotionCredible(10,130,"on foot","on foot"));
assert(!Rules::MotionCredible(10,20,"unknown","unknown")&&!Rules::MotionCredible(10,20,"on foot","vehicle"));
assert(near(Rules::Predict({0,40,0},{100,10,0},100)[0],300));
assert(near(Rules::Predict({0,40,0},{1,10,0},100)[0],30)&&near(Rules::Predict({0,40,0},{1,10,0},100)[1],40));
Identity a{1},b{2},friendly{3};ERR_HQMemory memory;
auto first=Report(1,&a,1000,{10,40,10});first.HasVelocity=true;first.Velocity={100,0,100};
assert(memory.Ingest(&first,2000));auto belief=memory.Get(&a);int beliefId=belief->BeliefId;
assert(belief->BeliefRevision==1&&belief->SampleCount==1&&!belief->HasVelocity&&belief->EvaluatedAt==2000);
first.Position={999,999,999};first.TravelMode="aircraft";belief->Position={777,0,777};belief->Report->Position={888,0,888};
assert(near(memory.Get(&a)->Position[0],10)&&memory.Get(&a)->TravelMode=="on foot");
auto next=Report(2,&a,11000,{70,80,10});assert(memory.Ingest(&next,16000));belief=memory.GetById(beliefId);
assert(belief->BeliefRevision==2&&belief->HasVelocity&&near(belief->Speed,6)&&near(belief->HeadingDegrees,90));
assert(near(belief->PredictedPosition[0],100)&&near(belief->PredictedPosition[1],80));
memory.Tick(611000);belief=memory.GetById(beliefId);
assert(belief&&near(belief->Confidence,.5)&&near(belief->Radius,745)&&near(belief->PredictedPosition[0],250));
assert(belief->PredictionSeconds==30&&belief->Actionable());
memory.Tick(610000);assert(memory.Get(&a)->EvaluatedAt==611000);memory.Tick(nan);assert(memory.Get(&a)->EvaluatedAt==611000);
assert(!memory.Ingest(&next,16000)&&!memory.Ingest(&next,611000));
assert(memory.NegativeSearch(beliefId,2,611000));belief=memory.Get(&a);
assert(near(belief->Confidence,.325)&&belief->ObservedAt==11000&&belief->SampleCount==2&&belief->BeliefRevision==2);
assert(!memory.NegativeSearch(beliefId,2,611000)&&!memory.NegativeSearch(beliefId,1,611000));
auto renewed=Report(3,&a,611000,{100,80,10});assert(memory.Ingest(&renewed,611000));
assert(near(memory.Get(&a)->Confidence,1)&&memory.Get(&a)->BeliefRevision==3&&!memory.Get(&a)->HasVelocity);
assert(!memory.NegativeSearch(beliefId,2,611000));
// Per-kind identity protects a moving contact from uncertain friendly/body information.
auto distress=Report(4,&a,611000,{500,0,500});distress.Distress=true;distress.Source=&friendly;
assert(memory.Ingest(&distress,612000)&&memory.Count()==2&&memory.Get(&a)->Kind==ERR_HQMemoryKind::SIGHTING);
auto distressBelief=memory.At(1);assert(distressBelief->Target==nullptr&&!distressBelief->HasVelocity&&!distressBelief->Actionable());
auto body=Report(5,&a,612000,{100,0,10},"body");assert(memory.Ingest(&body,612000));
assert(memory.At(2)->Kind==ERR_HQMemoryKind::BODY&&!memory.At(2)->HasVelocity&&memory.Get(&a)->BeliefRevision==3);
assert(!memory.NegativeSearch(memory.At(2)->BeliefId,1,612000));
// A deleted engine identity cannot erase or rebind an already numbered belief.
memory.m_Tracks[0]->Key=nullptr;memory.m_Tracks[0]->Latest()->Target=nullptr;
assert(memory.GetById(beliefId)&&near(memory.GetById(beliefId)->Position[0],100));
memory.Tick(2300000);assert(memory.Count()==0&&!memory.GetById(beliefId));
memory.Clear();auto restart=Report(1,&a,0);assert(memory.Ingest(&restart,0));assert(memory.Get(&a)->BeliefId>beliefId);
// Delayed legitimate deliveries for another track survive arbitrarily high fresh IDs.
memory.Clear();auto high=Report(100000,&a,10000);assert(memory.Ingest(&high,11000));
auto delayed=Report(2,&b,9000);assert(memory.Ingest(&delayed,12000));
auto replay=delayed;replay.ObservedAt=12000;replay.Position={500,0,0};assert(!memory.Ingest(&replay,12000));
auto stale=Report(200000,&a,0);assert(!memory.Ingest(&stale,130001));
auto low=Report(3,&b,130001);assert(memory.Ingest(&low,130001));
auto future=Report(999999,&a,130003);assert(!memory.Ingest(&future,130002));
auto good=Report(4,&b,130002);assert(memory.Ingest(&good,130002));
// Strictly chronological samples, limited history and conservative discontinuities.
memory.Clear();for(int i=1;i<=12;i++){auto r=Report(i,&a,i*2000,{float(i*2),0,0});assert(memory.Ingest(&r,i*2000));}
assert(memory.Get(&a)->SampleCount==8&&memory.Get(&a)->BeliefRevision==12&&memory.Get(&a)->HasVelocity);
auto old=Report(13,&a,23000);assert(!memory.Ingest(&old,25000)&&memory.Get(&a)->BeliefRevision==12);
auto jump=Report(14,&a,26000,{10000,0,0});assert(memory.Ingest(&jump,26000)&&!memory.Get(&a)->HasVelocity);
// A near-simultaneous second observer must not erase credible motion
// history. Use the nearest sample at least two seconds old, never a live
// entity position or an older convenient sample across a mode change.
memory.Clear();
auto spaced=Report(1,&a,1000,{10,0,20});assert(memory.Ingest(&spaced,1000));
auto closeA=Report(2,&a,4000,{10,0,20});assert(memory.Ingest(&closeA,4000));
auto closeB=Report(3,&a,4500,{10,0,20});assert(memory.Ingest(&closeB,4500));
assert(memory.Get(&a)->HasVelocity&&near(memory.Get(&a)->Speed,0));
auto moving=Report(4,&a,5000,{18,0,20});assert(memory.Ingest(&moving,5000));
assert(memory.Get(&a)->HasVelocity&&near(memory.Get(&a)->Speed,2));
auto boarded=Report(5,&a,5500,{18,0,20},"vehicle");assert(memory.Ingest(&boarded,5500));
assert(!memory.Get(&a)->HasVelocity);
auto dismounted=Report(6,&a,6000,{18,0,20});assert(memory.Ingest(&dismounted,6000));
assert(!memory.Get(&a)->HasVelocity); // do not bridge the intervening vehicle observation
auto farJump=Report(7,&a,8000,{10000,0,0});assert(memory.Ingest(&farJump,8000));
assert(!memory.Get(&a)->HasVelocity); // do not skip an implausible eligible pair
memory.Clear();
auto rapidA=Report(1,&a,1000);assert(memory.Ingest(&rapidA,1000));
auto rapidB=Report(2,&a,1500);assert(memory.Ingest(&rapidB,1500));
assert(!memory.Get(&a)->HasVelocity); // insufficient time baseline still refuses motion
// A near-time report may not hide a contradiction by skipping to an older convenient pair.
memory.Clear();
auto origin=Report(1,&a,0,{0,10,0});assert(memory.Ingest(&origin,0));
auto away=Report(2,&a,10000,{100,10,0});assert(memory.Ingest(&away,10000));
auto returned=Report(3,&a,11000,{0,10,0});assert(memory.Ingest(&returned,12000));
auto contradicted=memory.Get(&a);
assert(!contradicted->HasVelocity&&near(contradicted->Speed,0)&&near(contradicted->Velocity.Length(),0));
assert(near(contradicted->Position[0],0)&&near(contradicted->PredictedPosition[0],0));
assert(contradicted->ObservedAt==11000&&contradicted->LastDeliveredAt==12000);
assert(contradicted->SampleCount==3&&contradicted->BeliefRevision==3&&contradicted->EvaluatedAt==12000);
assert(near(contradicted->Confidence,Rules::Confidence(1))&&near(contradicted->Radius,26.2));
// Equal-time contradiction is refused at intake; it cannot replace the newest position or reset its age.
auto sameTime=Report(4,&a,11000,{100,10,0});assert(!memory.Ingest(&sameTime,13000));
assert(memory.Get(&a)->ObservedAt==11000&&memory.Get(&a)->LastDeliveredAt==12000);
assert(memory.Get(&a)->SampleCount==3&&!memory.Get(&a)->HasVelocity&&near(memory.Get(&a)->Position[0],0));
// A second identity retains independent credible motion despite the contradiction above.
auto otherStart=Report(5,&b,12000,{200,0,0});assert(memory.Ingest(&otherStart,13000));
auto otherMove=Report(6,&b,14000,{210,0,0});assert(memory.Ingest(&otherMove,14000));
assert(memory.Get(&b)->HasVelocity&&near(memory.Get(&b)->Speed,5)&&!memory.Get(&a)->HasVelocity);
// The existing two-second speed envelope tolerates tightly spaced samples up to its limit.
for(float separation : {23.99f,24.f,24.01f}){
memory.Clear();auto start=Report(1,&a,0,{0,0,0});assert(memory.Ingest(&start,0));
auto nearTime=Report(2,&a,10000,{separation,0,0});assert(memory.Ingest(&nearTime,10000));
auto last=Report(3,&a,11000,{0,0,0});assert(memory.Ingest(&last,11000));
assert(memory.Get(&a)->HasVelocity==(separation<=24));
}
// No equal/weak burst can evict a stronger current sighting; later stronger reports can.
memory.Clear();Identity people[70];for(int i=0;i<70;i++)people[i].id=i+10;
for(int i=0;i<64;i++){auto r=Report(i+1,&people[i],0);assert(memory.Ingest(&r,0));}
auto over=Report(65,&people[64],0);assert(!memory.Ingest(&over,0)&&memory.Count()==64);
over.ObservedAt=10000;assert(memory.Ingest(&over,10000)&&memory.Count()==64);
auto weak=Report(66,&people[65],10000);weak.Distress=true;assert(!memory.Ingest(&weak,10000));
assert(!memory.At(-1)&&!memory.At(64)&&!memory.Get(nullptr));
// Heard fire is source-keyed, imprecise, short-lived, never a precision target.
memory.Clear();auto sound=Report(1,nullptr,1000,{75,0,225},"heard gunfire");sound.Source=&friendly;
assert(memory.Ingest(&sound,1000));auto noise=memory.At(0);
assert(noise->Kind==ERR_HQMemoryKind::GUNFIRE&&!noise->Target&&!noise->HasVelocity&&!noise->Actionable());
assert(near(noise->Radius,150)&&near(noise->Confidence,.4));
int soundId=noise->BeliefId;assert(memory.NegativeSearch(soundId,1,1000));
assert(near(memory.GetById(soundId)->Confidence,.26));
sound.MessageId=2;sound.ObservedAt=3000;sound.Position={375,0,225};assert(memory.Ingest(&sound,3000));
assert(memory.Count()==1&&!memory.At(0)->HasVelocity&&memory.At(0)->Target==nullptr);
auto visual=Report(3,&a,3000,{400,0,210});assert(memory.Ingest(&visual,3000));
assert(memory.Count()==2&&memory.Get(&a)->Actionable()&&near(memory.Get(&a)->Confidence,1));
memory.Tick(63000);assert(near(memory.GetById(soundId)->Confidence,.2));
// Alarm identity is distinct from gunfire and sightings even for the same source.
memory.Clear();auto alarm=Report(1,&a,1000,{75,20,225},"heard vehicle alarm");alarm.Source=&friendly;
alarm.HasVelocity=true;alarm.Velocity={40,0,0};alarm.Distress=true;alarm.Engaged=true;
alarm.SeenEscapists=12;alarm.SeenWeapons="rifle";alarm.RoadStatus="road";alarm.DetailsObservedAt=1000;
alarm.CasualtySourceId="forged";alarm.CasualtySlot=1;alarm.CasualtyStrength=4;
assert(memory.Ingest(&alarm,1000));auto heard=memory.At(0);int alarmId=heard->BeliefId;
assert(heard->Kind==ERR_HQMemoryKind::ALARM&&!heard->Target&&!heard->HasVelocity&&!heard->Actionable());
assert(near(heard->Confidence,.25)&&near(heard->Radius,150)&&near(heard->PredictedPosition[0],75));
assert(!heard->Report->Target&&!heard->Report->HasVelocity&&near(heard->Report->Velocity.Length(),0));
assert(!heard->Report->Distress&&!heard->Report->Engaged&&heard->Report->SeenEscapists==-1);
assert(heard->Report->SeenWeapons=="unknown"&&heard->Report->RoadStatus=="road unknown");
assert(heard->Report->DetailsObservedAt==-1&&heard->Report->CasualtySourceId.empty());
assert(heard->Report->CasualtySlot==-1&&heard->Report->CasualtyStrength==0);
assert(alarm.Target==&a&&alarm.HasVelocity&&alarm.SeenEscapists==12); // caller was not mutated
assert(heard->Report->Source==&friendly&&heard->Report->ObservedAt==1000&&heard->Report->MessageId==1);
heard->Report->Position={999,0,999};assert(near(memory.GetById(alarmId)->Position[0],75));
auto distinctSound=Report(2,nullptr,1000,{75,20,225},"heard gunfire");distinctSound.Source=&friendly;
assert(memory.Ingest(&distinctSound,1000)&&memory.Count()==2&&!memory.Get(&a));
alarm.MessageId=3;alarm.ObservedAt=4000;alarm.Position={375,20,225};assert(memory.Ingest(&alarm,4000));
assert(memory.Count()==2&&memory.GetById(alarmId)->BeliefRevision==2&&!memory.GetById(alarmId)->HasVelocity);
assert(!memory.NegativeSearch(alarmId,1,4000)&&memory.NegativeSearch(alarmId,2,4000));
assert(!memory.NegativeSearch(alarmId,2,4000)&&near(memory.GetById(alarmId)->Confidence,.1625));
memory.Tick(49000);assert(near(memory.GetById(alarmId)->Confidence,.08125));
assert(near(memory.GetById(alarmId)->Radius,240));
alarm.MessageId=4;alarm.ObservedAt=49000;alarm.Source=nullptr;assert(!memory.Ingest(&alarm,49000));
// The global replay table is bounded even when valid observation IDs arrive rapidly.
memory.Clear();for(int i=1;i<=4096;i++){auto r=Report(i,&a,float(i));assert(memory.Ingest(&r,float(i)));}
auto full=Report(4097,&a,4097);assert(!memory.Ingest(&full,4097)&&memory.m_Seen.Count()==4096);
memory.Tick(124096);full.ObservedAt=124096;assert(memory.Ingest(&full,124096)&&memory.m_Seen.Count()==2);
auto expired=Report(1,&b,1);assert(!memory.Ingest(&expired,124096));
}
''')
print('PASS: actual HQ memory rules/service preserve delivered snapshots, chronology, replay bounds, decay, motion limits, identity and negative-search revisions')