Merge the power fixes: multiplier, active gating, honest tiers, shield repair
F1 power supply multiplies the resolved value (operator ruling), so zero supply means zero and a flat stat still responds. F2 the bus agrees with Active in both directions. F3 an empty tier reports no demand instead of full supply, and sub-epsilon demand is rationed and subtracted. F4/F5 the shield restores while inactive and CanTakeHit no longer mutates. F6/F7 the validator names every stat a request reads and the tools validate before writing. F8 re-anchors two dead mutation harnesses. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
commit
cd47eefe9e
21 changed files with 667 additions and 108 deletions
|
|
@ -72,12 +72,16 @@ public static class CultRecordRefs
|
|||
new CultRecordRef<T>(cache.TryGetHandle(document)?.Key ??
|
||||
throw new InvalidOperationException($"This cache holds no such {document.GetType().Name}."));
|
||||
|
||||
// Writes a document to its home store; the cache mints its key the first time. Every catalog write in this
|
||||
// repository (tools, tests, migration scripts) goes through this one function, so it is where R-heat's
|
||||
// validation closes the gap AetheriaStores.Open leaves: Open only checks what is already on disk when a
|
||||
// session starts, not what a session then writes. Validating here means an invalid heat response is refused
|
||||
// before the write ever reaches disk, not just the next time someone reopens the file.
|
||||
public static CultRecordRef<T> Upsert<T>(this CultCache cache, T document) where T : class
|
||||
// F7 (docs/stats-and-power-cut.md, Soul pass 2026-09-19): the validation body itself, pulled out of Upsert
|
||||
// below so it has exactly one owner. Every catalog write in this repository was supposed to go through
|
||||
// Upsert, but three of tools/AetherDb/Program.cs's own migration commands (Dangling, ShieldMigrate,
|
||||
// BrownoutMigrate) cannot: they repair an EXISTING record in place and must preserve its key, which Upsert's
|
||||
// own cache.UpsertAsync(document) does not support (Upsert mints or resolves a key from the document itself,
|
||||
// not from a caller-supplied one). Rather than leave those three writing raw and unvalidated -- as they did
|
||||
// before this fix -- they call this method directly, immediately before their own identity-preserving
|
||||
// batch.Upsert(document.GetType(), document, key) commit, so the same rules run either way. Takes `object`
|
||||
// (not a generic T) because that is what those three tools' own (Document, Key) change lists are typed as.
|
||||
public static void Validate(object document)
|
||||
{
|
||||
if (document is EquippableItemData data)
|
||||
{
|
||||
|
|
@ -92,6 +96,17 @@ public static class CultRecordRefs
|
|||
StatValidation.ValidateNoPowerSupplyOnRequest(consumable.Name, consumable.Behaviors);
|
||||
StatValidation.ValidateRoleUsage(consumable.Name, consumable.Roles, consumable.Behaviors);
|
||||
}
|
||||
}
|
||||
|
||||
// Writes a document to its home store; the cache mints its key the first time. Every catalog write in this
|
||||
// repository (tools, tests, migration scripts) goes through this one function, or through Validate above
|
||||
// directly when the caller must preserve an existing key (see Validate's own comment) -- so this is where
|
||||
// R-heat's validation closes the gap AetheriaStores.Open leaves: Open only checks what is already on disk
|
||||
// when a session starts, not what a session then writes. Validating here means an invalid heat response is
|
||||
// refused before the write ever reaches disk, not just the next time someone reopens the file.
|
||||
public static CultRecordRef<T> Upsert<T>(this CultCache cache, T document) where T : class
|
||||
{
|
||||
Validate(document);
|
||||
return new CultRecordRef<T>(cache.UpsertAsync(document).Result.Key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue