Aufgefallen beim Umsetzen von #131 (HQ-Decke 2.000 → 3.000). Der Test RulesRevisionOneAndTwo_GoldenHashesRemainByteStable wurde rot — mit der Meldung, die den ganzen Befund enthält:
revision 1 canonical stream is frozen
Assert.That(revisionOne, Is.EqualTo(0x531CE8F614A16CB5UL))
Expected: 5988917748101639349
But was: 1252868810252661096
Eine Änderung an einer heutigen Konstante hat den historischen Revision-1-Hash verändert.
Befund
MatchFingerprint.ComputeRulesHash64(ushort rulesRevision) schreibt für jede Revision die aktuellen Konstanten in den Hash:
hash.WriteUInt32(rulesRevision == RulesRevisionV1 ? 5u : ...); // nur die FELDZAHL ist historisch
hash.WriteFieldTag(2);
hash.WriteInt64(EconomySystem.HqBaseCapacityAE); // <- der HEUTIGE Wert
hash.WriteFieldTag(3);
hash.WriteInt64(EconomySystem.StorageCapacityBonusAE);
...
Historisch ist ausschließlich, wie viele Felder geschrieben werden. Welche Werte darin stehen, ist immer der Stand von heute.
Der Docstring sagt aber:
This compatibility entry point exists so replay and relay tests can represent prior rules exactly.
Das tut die Funktion nicht. Sie bildet nie die früheren Regeln ab, sondern immer die heutigen unter einer alten Feldzahl.
Was daraus folgt
- Die Zusicherung „frozen" ist unhaltbar. Jede Änderung an einer gehashten Konstante schreibt rückwirkend die Identität aller Revisionen um. Der Golden-Wert lässt sich zwar neu setzen — aber dann pinnt er wieder nur den heutigen Stand, und beim nächsten Mal passiert dasselbe.
- Ein alter Replay ist nicht mehr identifizierbar. Eine unter Revision 1 aufgezeichnete Partie ergab damals einen anderen Revisions-Hash als denselben Replay heute. Was als Kompatibilitätspfad gedacht war, wird beim nächsten Konstantenwechsel zum Inkompatibilitätspfad.
- Zwei Builds können sich über eine historische Revision uneinig sein, obwohl beide dieselbe Revisionsnummer melden. Genau der Zustand, gegen den der Fingerprint existiert.
Verhältnis zu #108
Verwandt, aber nicht dasselbe. #108 sagt: der Hash deckt zu wenig ab — die Ankerregel fließt nicht ein. Dieses Issue sagt: die Werte, die er abdeckt, sind für historische Revisionen nicht eingefroren. Beide zusammen heißen, dass „gleiche Regelidentität" heute weniger verspricht, als der Name nahelegt.
Sprint 21 hat einen dritten Fall derselben Familie gefunden: eine komplette Kartenneuschreibung samt unbegehbarem Gelände bewegt keinen einzigen Fingerabdruck.
Was zu tun wäre
Die historischen Revisionen müssen ihre Werte als Literale tragen, nicht als Verweise auf lebende Konstanten. Nur die aktuelle Revision darf aus dem Bestand lesen.
Das geht nicht nebenbei: Scripts/Simulation/Replays/ ist im Parallelbetrieb als „niemand ohne D-ID" geführt. Speicherformat und Fingerprint zu ändern ist eine Inhaberentscheidung — deshalb dieses Issue statt eines PR.
Abgrenzung, damit nichts hängenbleibt
#131 wird nicht hierdurch aufgehalten. Die Regeländerung ist fertig; der Golden-Wert wird im Baseline-PR neu gesetzt. Dieser Neusetzung ist aber bewusst, dass sie einen bekannten Defekt überstreicht — sie macht den Test wieder grün, ohne die Zusicherung wieder wahr zu machen. Das gehört in die PR-Beschreibung, sonst sieht der nächste Leser einen sauberen grünen Test.
Aufgefallen beim Umsetzen von #131 (HQ-Decke 2.000 → 3.000). Der Test
RulesRevisionOneAndTwo_GoldenHashesRemainByteStablewurde rot — mit der Meldung, die den ganzen Befund enthält:Eine Änderung an einer heutigen Konstante hat den historischen Revision-1-Hash verändert.
Befund
MatchFingerprint.ComputeRulesHash64(ushort rulesRevision)schreibt für jede Revision die aktuellen Konstanten in den Hash:Historisch ist ausschließlich, wie viele Felder geschrieben werden. Welche Werte darin stehen, ist immer der Stand von heute.
Der Docstring sagt aber:
Das tut die Funktion nicht. Sie bildet nie die früheren Regeln ab, sondern immer die heutigen unter einer alten Feldzahl.
Was daraus folgt
Verhältnis zu #108
Verwandt, aber nicht dasselbe. #108 sagt: der Hash deckt zu wenig ab — die Ankerregel fließt nicht ein. Dieses Issue sagt: die Werte, die er abdeckt, sind für historische Revisionen nicht eingefroren. Beide zusammen heißen, dass „gleiche Regelidentität" heute weniger verspricht, als der Name nahelegt.
Sprint 21 hat einen dritten Fall derselben Familie gefunden: eine komplette Kartenneuschreibung samt unbegehbarem Gelände bewegt keinen einzigen Fingerabdruck.
Was zu tun wäre
Die historischen Revisionen müssen ihre Werte als Literale tragen, nicht als Verweise auf lebende Konstanten. Nur die aktuelle Revision darf aus dem Bestand lesen.
Das geht nicht nebenbei:
Scripts/Simulation/Replays/ist im Parallelbetrieb als „niemand ohne D-ID" geführt. Speicherformat und Fingerprint zu ändern ist eine Inhaberentscheidung — deshalb dieses Issue statt eines PR.Abgrenzung, damit nichts hängenbleibt
#131 wird nicht hierdurch aufgehalten. Die Regeländerung ist fertig; der Golden-Wert wird im Baseline-PR neu gesetzt. Dieser Neusetzung ist aber bewusst, dass sie einen bekannten Defekt überstreicht — sie macht den Test wieder grün, ohne die Zusicherung wieder wahr zu machen. Das gehört in die PR-Beschreibung, sonst sieht der nächste Leser einen sauberen grünen Test.