Save The Tree implementation and acceptance work in progress

Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
This commit is contained in:
Takeshi
2026-10-11 15:58:00 +09:00
parent 39f6068461
commit b84bade045
235 changed files with 495831 additions and 312 deletions
@@ -0,0 +1,171 @@
class_name SupplyAutoPurchaseQuotePlans
extends "res://scripts/supply/supply_auto_purchase_plans.gd"
## v1 class remains byte-identical. Only explicit v2 success rows branch here.
const QuoteV2 = preload("res://scripts/supply/supply_purchase_quote_v2.gd")
const V1 = preload("res://scripts/supply/supply_auto_purchase_plans.gd")
const RUNTIME_KEYS: Array[StringName] = [&"runtime_schema_version", &"weather", &"world_seed", &"next_command_id", &"staffing_projection_enabled", &"save_lifecycle", &"command_queue", &"id_generator", &"domain_events", &"rng_streams", &"world", &"path", &"movement_credits", &"mana", &"economy", &"facility_upkeep", &"upkeep_settlement", &"inventory", &"kitchen_production", &"auto_purchase_plans", &"elevators", &"legacy_stairs", &"logistics_dispatcher", &"logistics_requests", &"facilities", &"facility_cleanliness", &"guests", &"staff", &"catalog_manifest", &"progression", &"hired_staff_candidate_ids", &"operations", &"relationships", &"event_definitions", &"events", &"authority", &"defense", &"construction", &"excavation", &"spatial_subslots", &"route_projection", &"facility_infrastructure"]
const V2_KEYS: Array[StringName] = [&"warehouse_id", &"item_id", &"enabled", &"target_stock",
&"last_attempt_minute", &"last_result", &"last_transaction_id", &"last_quantity", &"last_quote", &"last_total_cost"]
func record_attempt(warehouse_id: StringName, item_id: StringName, minute: int,
result: CommandResult, economy: EconomyService) -> bool:
if not result.is_success() or not result.details.has(&"purchase_quote"):
var previous := get_plan(warehouse_id, item_id)
# A later real failure/ordinary purchase replaces only the last attempt;
# append-only v2 payment history stays in EconomyService.
if previous.has(&"last_quote"):
var legacy := _empty_plan(warehouse_id, item_id)
for key: StringName in legacy:
if previous.has(key): legacy[key] = previous[key]
_plans[warehouse_id][item_id] = legacy
var accepted := super.record_attempt(warehouse_id, item_id, minute, result, economy)
if not accepted and previous.has(&"last_quote"):
_plans[warehouse_id][item_id] = previous
return accepted
if not result.is_success() or not _plans.has(warehouse_id) \
or not (_plans[warehouse_id] as Dictionary).has(item_id): return false
var plan := get_plan(warehouse_id, item_id)
if minute < 0 or minute <= int(plan[&"last_attempt_minute"]): return false
var quote: Variant = result.details[&"purchase_quote"]
if not quote is Dictionary or not QuoteV2.valid(quote) \
or quote[&"item_id"] != String(item_id) \
or typeof(result.details.get(&"transaction_id")) != TYPE_STRING_NAME \
or typeof(result.details.get(&"quantity")) != TYPE_INT \
or result.details[&"quantity"] != quote[&"quantity"] \
or typeof(result.details.get(&"total_cost")) != TYPE_INT \
or result.details[&"total_cost"] != quote[&"effective_total"]: return false
var receipt := QuoteV2.receipt_from_ledger(economy, warehouse_id, item_id, minute, result.details[&"transaction_id"])
if var_to_bytes(receipt) != var_to_bytes(quote): return false
var row := {&"warehouse_id": String(warehouse_id), &"item_id": String(item_id),
&"enabled": plan[&"enabled"], &"target_stock": plan[&"target_stock"],
&"last_attempt_minute": minute, &"last_result": &"PURCHASED",
&"last_transaction_id": String(result.details[&"transaction_id"]),
&"last_quantity": quote[&"quantity"], &"last_quote": quote.duplicate(true),
&"last_total_cost": quote[&"effective_total"]}
_plans[warehouse_id][item_id] = row
return true
func create_snapshot() -> Dictionary:
var rows := get_plans()
for row: Dictionary in rows:
if row.has(&"last_quote"):
return {&"version": 2, &"plans": rows}
return super.create_snapshot()
func restore_snapshot(snapshot: Dictionary, facilities: FacilityService,
economy: EconomyService, minute: int) -> bool:
last_error = ""
if not QuoteV2.keys_match(snapshot, [&"version", &"plans"]) \
or typeof(snapshot[&"version"]) != TYPE_INT: return false
if snapshot[&"version"] == 1:
# The original v1 parser stays literal. A new paid v2 receipt cannot be
# represented as a REPLAY_MISMATCH failed old row.
var original_parser := V1.new()
if not original_parser.restore_snapshot(snapshot, facilities, economy, minute):
last_error = original_parser.last_error
return false
if not _v1_rows_have_no_valid_v2_payment(snapshot[&"plans"], economy): return false
_plans = original_parser._plans.duplicate(true)
last_error = original_parser.last_error
return true
if snapshot[&"version"] != 2 or not snapshot[&"plans"] is Array \
or facilities == null or economy == null or minute < 0: return false
if (snapshot[&"plans"] as Array).size() > facilities.get_instances().size() * Catalog.get_purchase_items().size(): return false
var candidate: Dictionary = {}
var saw_v2 := false
var old_rows: Array[Dictionary] = []
for value: Variant in snapshot[&"plans"]:
if not value is Dictionary: return false
var row: Dictionary = value
if row.has(&"last_quote"):
if not _valid_v2_row(row, facilities, economy, minute): return false
saw_v2 = true
else:
old_rows.append(row.duplicate(true))
if not saw_v2 or not _v1_rows_have_no_valid_v2_payment(old_rows, economy): return false
var original_parser := V1.new()
if not original_parser.restore_snapshot({&"version": 1, &"plans": old_rows}, facilities, economy, minute): return false
# Identifiers are accessed only after every old/new row passed its own
# strict alternative, avoiding casts of malformed old rows in a mixed table.
for row: Dictionary in snapshot[&"plans"]:
var warehouse := StringName(row[&"warehouse_id"])
var item := StringName(row[&"item_id"])
if candidate.has(warehouse) and (candidate[warehouse] as Dictionary).has(item): return false
if not candidate.has(warehouse): candidate[warehouse] = {}
candidate[warehouse][item] = row.duplicate(true)
var canonical := SupplyAutoPurchaseQuotePlans.new()
canonical._plans = candidate
if var_to_bytes(canonical.create_snapshot()) != var_to_bytes(snapshot): return false
# No live owner changes until both strict alternatives/crosslinks pass.
_plans = candidate
last_error = ""
return true
static func _valid_v2_row(row: Dictionary, facilities: FacilityService,
economy: EconomyService, minute: int) -> bool:
if not QuoteV2.keys_match(row, V2_KEYS): return false
for field: StringName in [&"warehouse_id", &"item_id", &"last_transaction_id"]:
if typeof(row[field]) != TYPE_STRING or String(row[field]).strip_edges().is_empty(): return false
for field: StringName in [&"target_stock", &"last_attempt_minute", &"last_quantity", &"last_total_cost"]:
if typeof(row[field]) != TYPE_INT: return false
if typeof(row[&"enabled"]) != TYPE_BOOL or typeof(row[&"last_result"]) != TYPE_STRING_NAME \
or row[&"last_result"] != &"PURCHASED" or not row[&"last_quote"] is Dictionary: return false
var warehouse := StringName(row[&"warehouse_id"])
var item := StringName(row[&"item_id"])
if not bool(V1.validate_intent(warehouse, item, row[&"enabled"], row[&"target_stock"], facilities)[&"ok"]): return false
var quote: Dictionary = row[&"last_quote"]
if not QuoteV2.valid(quote) or quote[&"item_id"] != String(item) \
or row[&"last_quantity"] != quote[&"quantity"] or row[&"last_total_cost"] != quote[&"effective_total"] \
or row[&"last_attempt_minute"] < 0 or row[&"last_attempt_minute"] > minute: return false
var receipt := QuoteV2.receipt_from_ledger(economy, warehouse, item, row[&"last_attempt_minute"], StringName(row[&"last_transaction_id"]))
return var_to_bytes(receipt) == var_to_bytes(quote)
static func _v1_rows_have_no_valid_v2_payment(rows: Variant, economy: EconomyService) -> bool:
if not rows is Array or economy == null: return false
for value: Variant in rows:
if not value is Dictionary: return false
var row: Dictionary = value
if row.has(&"last_quote"): return false
if typeof(row.get(&"last_attempt_minute")) != TYPE_INT \
or typeof(row.get(&"warehouse_id")) != TYPE_STRING or typeof(row.get(&"item_id")) != TYPE_STRING: continue
var minute: int = row[&"last_attempt_minute"]
if minute < 0: continue
var warehouse := StringName(row.get(&"warehouse_id", ""))
var item := StringName(row.get(&"item_id", ""))
var paid := economy.get_transaction_id_for_idempotency_key(V1.order_key(warehouse, item, minute))
if not paid.is_empty() and not QuoteV2.receipt_from_ledger(economy, warehouse, item, minute, paid).is_empty(): return false
return true
static func valid_runtime_format(runtime_data: Dictionary, minute: int) -> bool:
if not QuoteV2.keys_match(runtime_data, RUNTIME_KEYS) or typeof(runtime_data.get(&"runtime_schema_version")) != TYPE_INT \
or runtime_data[&"runtime_schema_version"] != 15 or not QuoteV2.has_history(runtime_data): return false
if not runtime_data.get(&"economy") is Dictionary or not runtime_data.get(&"facilities") is Dictionary \
or not runtime_data.get(&"auto_purchase_plans") is Dictionary: return false
var economy := EconomyService.new()
var facilities := FacilityService.new()
if not economy.restore_snapshot(runtime_data[&"economy"]) or not facilities.restore_snapshot(runtime_data[&"facilities"]): return false
if not runtime_data.get(&"command_queue") is Dictionary or not runtime_data.get(&"domain_events") is Dictionary: return false
var queue := CommandQueue.new()
var stream := DomainEventStream.new()
if not queue.restore_snapshot(runtime_data[&"command_queue"]) \
or not stream.restore_snapshot(runtime_data[&"domain_events"]): return false
# Match Runtime's existing domain-minute rule, including held/terminal Ops.
var operations: Variant = runtime_data.get(&"operations")
if not operations is Dictionary or typeof(operations.get(&"enabled")) != TYPE_BOOL \
or typeof(operations.get(&"deferred_runtime_minute")) != TYPE_INT \
or not operations.get(&"coordinator") is Dictionary: return false
var domain_minute := minute
if operations[&"enabled"]:
var coordinator := OperationsCoordinator.new()
if not coordinator.restore_snapshot(operations[&"coordinator"]): return false
if operations[&"deferred_runtime_minute"] == minute or coordinator.is_terminal(): domain_minute = minute - 1
var plans := SupplyAutoPurchaseQuotePlans.new()
return QuoteV2.valid_history(runtime_data, economy) \
and plans.restore_snapshot(runtime_data[&"auto_purchase_plans"], facilities, economy, domain_minute)
@@ -0,0 +1 @@
uid://cm52patq1djat
+49 -2
View File
@@ -1,10 +1,45 @@
class_name SupplyManagementService
extends RefCounted
const PurchaseQuoteV2 := preload("res://scripts/supply/supply_purchase_quote_v2.gd")
## Player commands and deterministic replenishment. Vendor purchases arrive in
## the selected warehouse; all transfers inside the tree use real porter tasks.
func preview_purchase(runtime: Variant, warehouse_id: StringName, item_id: StringName, quantity: int) -> Dictionary:
# Keep the entire ordinary branch literal; only placed UNIQUE Mimi
# selects the explicit total-order quote. No attendance/role/floor condition.
if not PurchaseQuoteV2.eligible(runtime):
return _preview_purchase_v1(runtime, warehouse_id, item_id, quantity)
var quote := _preview_purchase_v1(runtime, warehouse_id, item_id, quantity)
var item := SupplyCatalog.get_item(item_id)
var facility: FacilityInstance = runtime.facility_service.get_instance(warehouse_id)
if facility == null or facility.definition_id != &"warehouse" or item.is_empty() \
or not bool(item.get(&"purchasable", false)) or quantity <= 0 or quantity > 10000: return quote
var frozen := PurchaseQuoteV2.make(item_id, quantity, int(item[&"unit_price"]))
if frozen.is_empty(): return quote
var cash: int = runtime.economy_service.get_balance(&"PLAYER_CASH")
var space: int = maxi(SupplyCatalog.storage_capacity(facility.definition_id) - SupplyCatalog.inventory_weight(runtime.inventory_service, facility.local_inventory_id) - _incoming_weight(runtime, facility.local_inventory_id), 0)
@warning_ignore("integer_division")
var slots := space / int(item[&"unit_weight"])
quote[&"purchase_quote"] = frozen
quote[&"total_cost"] = frozen[&"effective_total"]
quote[&"cash_after"] = cash - int(frozen[&"effective_total"])
quote[&"max_quantity"] = PurchaseQuoteV2.affordable_quantity(cash, slots, int(item[&"unit_price"]))
quote[&"ok"] = false
quote[&"reason"] = &""
if not facility.allows_logistics():
quote[&"reason"] = &"FACILITY_CLOSED"
elif int(frozen[&"effective_total"]) > cash:
quote[&"reason"] = &"INSUFFICIENT_FUNDS"
elif quantity * int(item[&"unit_weight"]) > space:
quote[&"reason"] = &"STORAGE_FULL"
else:
quote[&"ok"] = true
return quote
func _preview_purchase_v1(runtime: Variant, warehouse_id: StringName, item_id: StringName, quantity: int) -> Dictionary:
var cash: int = runtime.economy_service.get_balance(&"PLAYER_CASH")
var item := SupplyCatalog.get_item(item_id)
var facility: FacilityInstance = runtime.facility_service.get_instance(warehouse_id)
@@ -62,12 +97,20 @@ func _purchase_paid(runtime: Variant, warehouse_id: StringName, item_id: StringN
runtime.economy_service.restore_snapshot(economy_before)
return _purchase_failure(command_id, &"INVENTORY_ERROR")
var memo: StringName = SupplyAutoPurchasePlans.receipt_memo(item_id, quantity, int(item[&"unit_price"]), int(quote[&"total_cost"])) if record_auto_attempt else &"supply_purchase"
if quote.has(&"purchase_quote"):
memo = PurchaseQuoteV2.receipt_memo(quote[&"purchase_quote"])
var paid: CommandResult = runtime.economy_service.transfer(&"PLAYER_CASH", runtime.OPERATING_EXPENSE_ACCOUNT, int(quote[&"total_cost"]), minute, &"OPERATING_EXPENSE", warehouse_id, ledger_key, memo, &"", false)
if not paid.is_success():
runtime.inventory_service.restore_snapshot(inventory_before)
runtime.economy_service.restore_snapshot(economy_before)
return _purchase_failure(command_id, &"PAYMENT_FAILED")
if record_auto_attempt and not runtime.auto_purchase_plans.record_attempt(warehouse_id, item_id, minute, CommandResult.succeeded(0, {&"transaction_id": paid.details[&"transaction_id"], &"quantity": quantity, &"unit_price": item[&"unit_price"], &"total_cost": quote[&"total_cost"]}), runtime.economy_service):
var recorded := true
if record_auto_attempt:
if quote.has(&"purchase_quote"):
recorded = runtime.auto_purchase_plans.record_attempt(warehouse_id, item_id, minute, CommandResult.succeeded(0, {&"transaction_id": paid.details[&"transaction_id"], &"quantity": quantity, &"purchase_quote": quote[&"purchase_quote"], &"total_cost": quote[&"total_cost"]}), runtime.economy_service)
else:
recorded = runtime.auto_purchase_plans.record_attempt(warehouse_id, item_id, minute, CommandResult.succeeded(0, {&"transaction_id": paid.details[&"transaction_id"], &"quantity": quantity, &"unit_price": item[&"unit_price"], &"total_cost": quote[&"total_cost"]}), runtime.economy_service)
if not recorded:
runtime.inventory_service.restore_snapshot(inventory_before)
runtime.economy_service.restore_snapshot(economy_before)
return _purchase_failure(command_id, &"PAYMENT_FAILED")
@@ -153,7 +196,11 @@ func advance_auto_purchases(runtime: Variant, minute: int) -> Array[Dictionary]:
# today's quote is unaffordable. It never stocks, charges or notifies.
var receipt := SupplyAutoPurchasePlans.receipt_from_ledger(runtime.economy_service, warehouse_id, item_id, minute, prior_id)
if receipt.is_empty():
result = _purchase_failure(0, &"REPLAY_MISMATCH")
var frozen := PurchaseQuoteV2.receipt_from_ledger(runtime.economy_service, warehouse_id, item_id, minute, prior_id)
if frozen.is_empty():
result = _purchase_failure(0, &"REPLAY_MISMATCH")
else:
result = CommandResult.succeeded(0, {&"transaction_id": prior_id, &"quantity": frozen[&"quantity"], &"purchase_quote": frozen, &"total_cost": frozen[&"effective_total"], &"replayed": true})
else:
result = CommandResult.succeeded(0, {&"transaction_id": prior_id, &"quantity": receipt[&"quantity"], &"unit_price": receipt[&"unit_price"], &"total_cost": receipt[&"total_cost"], &"replayed": true})
if (not result.is_success() or not prior_id.is_empty()) and not runtime.auto_purchase_plans.record_attempt(warehouse_id, item_id, minute, result, runtime.economy_service):
+297
View File
@@ -0,0 +1,297 @@
class_name SupplyPurchaseQuoteV2
extends RefCounted
## Explicit total-order quote. v1 unit receipts are never reinterpreted.
## Placement uses the existing staff UI plan-first/legacy-live fallback rule.
## Total-order rounding reuses Pricing; attendance/role/floor multipliers are not added.
const Pricing = preload("res://scripts/facility/facility_pricing.gd")
const V1Plans = preload("res://scripts/supply/supply_auto_purchase_plans.gd")
const PREFIX := "supply_purchase.quote.v2:"
const MIMI := &"heroine_mimi"
const MULTIPLIER_BP := 8000
const MAX_INT_TEXT := "9223372036854775807"
const MAX_INT := 9223372036854775807
const KEYS: Array[StringName] = [&"version", &"item_id", &"quantity", &"base_unit_price",
&"base_total", &"multiplier_bp", &"effective_total", &"applied_unique_id"]
static func eligible(runtime: Variant) -> bool:
var mimi: StaffRuntime = runtime.staff_service.get_staff(MIMI)
if mimi == null or mimi.employment_kind != StaffRuntime.EmploymentKind.UNIQUE: return false
var assignment: Dictionary = runtime.staff_service.get_work_assignment(MIMI)
var facility_id := mimi.assigned_facility_id
if not assignment.is_empty(): facility_id = StringName(assignment.get(&"facility_id", &""))
return not facility_id.is_empty() and runtime.facility_service.get_instance(facility_id) != null
static func make(item_id: StringName, quantity: int, base_unit_price: int) -> Dictionary:
@warning_ignore("integer_division")
var maximum_base := (MAX_INT - 5000) / MULTIPLIER_BP
if String(item_id).strip_edges().is_empty() or quantity <= 0 or quantity > 10000 or base_unit_price <= 0:
return {}
@warning_ignore("integer_division")
var maximum_unit := maximum_base / quantity
if base_unit_price > maximum_unit: return {}
var base_total := quantity * base_unit_price
return {&"version": 2, &"item_id": String(item_id), &"quantity": quantity,
&"base_unit_price": base_unit_price, &"base_total": base_total,
&"multiplier_bp": MULTIPLIER_BP, &"effective_total": Pricing.apply_multiplier(base_total, MULTIPLIER_BP),
&"applied_unique_id": String(MIMI)}
static func valid(quote: Dictionary) -> bool:
if not keys_match(quote, KEYS): return false
for key: StringName in [&"version", &"quantity", &"base_unit_price", &"base_total", &"multiplier_bp", &"effective_total"]:
if typeof(quote[key]) != TYPE_INT: return false
if typeof(quote[&"item_id"]) != TYPE_STRING or typeof(quote[&"applied_unique_id"]) != TYPE_STRING:
return false
if quote[&"version"] != 2 or quote[&"multiplier_bp"] != MULTIPLIER_BP \
or quote[&"applied_unique_id"] != String(MIMI): return false
var canonical := make(StringName(quote[&"item_id"]), quote[&"quantity"], quote[&"base_unit_price"])
# This also preserves canonical key/container/type order without normalizing
# corrupt saved fields or consulting today's catalog/personnel state.
return not canonical.is_empty() and var_to_bytes(canonical) == var_to_bytes(quote)
static func affordable_quantity(cash: int, space: int, base_unit_price: int) -> int:
var lower := 0
var upper := mini(maxi(space, 0), 10000)
while lower < upper:
@warning_ignore("integer_division")
var middle := (lower + upper + 1) / 2
var quote := make(&"affordability", middle, base_unit_price)
if not quote.is_empty() and quote[&"effective_total"] <= cash:
lower = middle
else:
upper = middle - 1
return lower
static func receipt_memo(quote: Dictionary) -> StringName:
if not valid(quote): return &""
var item: String = quote[&"item_id"]
var actor: String = quote[&"applied_unique_id"]
return StringName(PREFIX + "%d:%s:%d:%s:%d:%d:%d:%d:%d" % [item.length(), item,
actor.length(), actor, quote[&"quantity"], quote[&"base_unit_price"], quote[&"base_total"],
quote[&"multiplier_bp"], quote[&"effective_total"]])
static func decode_receipt_memo(memo: StringName) -> Dictionary:
var text := String(memo)
if not text.begins_with(PREFIX): return {}
var item := _take_text(text.substr(PREFIX.length()))
if item.is_empty(): return {}
var actor := _take_text(item[&"rest"])
if actor.is_empty(): return {}
var fields: PackedStringArray = String(actor[&"rest"]).split(":", true)
if fields.size() != 5: return {}
var quote := {&"version": 2, &"item_id": item[&"text"], &"quantity": _positive(fields[0]),
&"base_unit_price": _positive(fields[1]), &"base_total": _positive(fields[2]),
&"multiplier_bp": _positive(fields[3]), &"effective_total": _positive(fields[4]),
&"applied_unique_id": actor[&"text"]}
return quote if valid(quote) and receipt_memo(quote) == memo else {}
static func receipt_from_ledger(economy: EconomyService, warehouse_id: StringName,
item_id: StringName, minute: int, transaction_id: StringName,
automatic := true, command_id := 0) -> Dictionary:
var key := V1Plans.order_key(warehouse_id, item_id, minute) if automatic \
else StringName("supply.purchase.%d" % command_id)
if economy == null or transaction_id.is_empty() or (not automatic and command_id <= 0) \
or economy.get_transaction_id_for_idempotency_key(key) != transaction_id:
return {}
var entries := economy.get_transaction_entries(transaction_id)
if entries.size() != 1: return {}
var entry: LedgerEntry = entries[0]
var quote := decode_receipt_memo(entry.memo_key)
if quote.is_empty() or quote[&"item_id"] != String(item_id) \
or entry.amount != quote[&"effective_total"] or entry.absolute_minute != minute \
or entry.source_entity_id != warehouse_id or entry.category != &"OPERATING_EXPENSE" \
or entry.credit_account != &"PLAYER_CASH" or entry.debit_account != &"OPERATING_EXPENSE" \
or not entry.related_transaction_id.is_empty(): return {}
return quote
static func has_history(runtime_data: Dictionary) -> bool:
var economy: Variant = runtime_data.get(&"economy")
if economy is Dictionary and economy.get(&"entries") is Array:
for entry: Variant in economy[&"entries"]:
if entry is Dictionary and typeof(entry.get(&"memo_key")) in [TYPE_STRING, TYPE_STRING_NAME] \
and String(entry[&"memo_key"]).begins_with(PREFIX): return true
var plans: Variant = runtime_data.get(&"auto_purchase_plans")
if plans is Dictionary:
if plans.get(&"version") == 2: return true
if plans.get(&"plans") is Array:
for row: Variant in plans[&"plans"]:
if row is Dictionary and row.has(&"last_quote"): return true
var queue: Variant = runtime_data.get(&"command_queue")
if queue is Dictionary and queue.get("processed") is Array:
for result: Variant in queue["processed"]:
if result is Dictionary and _result_has_quote(result): return true
var stream: Variant = runtime_data.get(&"domain_events")
if stream is Dictionary and stream.get("recent_events") is Array:
for event: Variant in stream["recent_events"]:
if event is Dictionary and event.get("event_type") in ["COMMAND_COMPLETED", "COMMAND_FAILED"] \
and event.get("payload") is Dictionary and _result_has_quote(event["payload"]): return true
# The uncapped processed queue also keeps history after recent-event eviction.
return false
static func valid_history(runtime_data: Dictionary, economy: EconomyService) -> bool:
if economy == null: return false
var raw_economy: Variant = runtime_data.get(&"economy")
if not raw_economy is Dictionary or not raw_economy.get(&"entries") is Array \
or not raw_economy.get(&"idempotency") is Array: return false
var entries := economy.get_entries()
if entries.size() != (raw_economy[&"entries"] as Array).size(): return false
var v2_transactions: Dictionary = {}
for index: int in entries.size():
var entry: LedgerEntry = entries[index]
if not String(entry.memo_key).begins_with(PREFIX): continue
# The old Economy parser permits legacy coercions. New v2 payment fields
# must retain the complete actual nine-field producer representation.
var raw: Variant = raw_economy[&"entries"][index]
if not raw is Dictionary or var_to_bytes(raw) != var_to_bytes(entry.to_dictionary()): return false
v2_transactions[String(entry.transaction_id)] = true
for value: Variant in raw_economy[&"idempotency"]:
if not value is Dictionary: return false
if not v2_transactions.has(value.get(&"transaction_id")): continue
if not keys_match(value, [&"key", &"transaction_id"]) \
or typeof(value[&"key"]) != TYPE_STRING or typeof(value[&"transaction_id"]) != TYPE_STRING \
or var_to_bytes(value) != var_to_bytes({&"key": value[&"key"], &"transaction_id": value[&"transaction_id"]}): return false
var required_manual: Dictionary = {}
for entry: LedgerEntry in economy.get_entries():
if not String(entry.memo_key).begins_with(PREFIX): continue
var quote := decode_receipt_memo(entry.memo_key)
if quote.is_empty() or entry.source_entity_id.is_empty(): return false
var item := StringName(quote[&"item_id"])
var automatic := receipt_from_ledger(economy, entry.source_entity_id, item, entry.absolute_minute, entry.transaction_id)
if not automatic.is_empty(): continue
var command_id := _manual_command_id_for_transaction(economy, entry.transaction_id)
if receipt_from_ledger(economy, entry.source_entity_id, item, entry.absolute_minute, entry.transaction_id, false, command_id).is_empty(): return false
required_manual[command_id] = quote
var queue: Variant = runtime_data.get(&"command_queue")
if not queue is Dictionary or not queue.get("processed") is Array: return false
var processed: Dictionary = {}
for result: Variant in queue["processed"]:
if not result is Dictionary or not _valid_result_quotes(result, economy): return false
if typeof(result.get("command_id")) != TYPE_INT: return false
processed[result["command_id"]] = result
# Manual payments have uncapped processed results; removing/replacing their
# frozen quote is invalid. Auto plans may legitimately be replaced/pruned,
# so their append-only ledger receipt remains sufficient historical proof.
for command_id: int in required_manual:
if not processed.has(command_id): return false
var result: Dictionary = processed[command_id]
if result.get("code") != "OK" or not result.get("details") is Dictionary \
or not result["details"].get(&"purchase_quote") is Dictionary \
or var_to_bytes(result["details"][&"purchase_quote"]) != var_to_bytes(required_manual[command_id]): return false
var stream: Variant = runtime_data.get(&"domain_events")
if not stream is Dictionary or not stream.get("recent_events") is Array: return false
for event: Variant in stream["recent_events"]:
if not event is Dictionary: return false
if event.get("event_type") not in ["COMMAND_COMPLETED", "COMMAND_FAILED"]: continue
var payload: Variant = event.get("payload")
if not payload is Dictionary or not _result_has_quote(payload): continue
var command_id: Variant = event.get("causation_command_id")
if typeof(command_id) != TYPE_INT or not processed.has(command_id) \
or typeof(event.get("source_service")) != TYPE_STRING or event["source_service"] != "simulation_runtime" \
or var_to_bytes(payload) != var_to_bytes(processed[command_id]): return false
return true
static func _result_has_quote(result: Dictionary) -> bool:
# Only the owned original_result chain is traversed; arbitrary dictionaries
# and schema-looking strings elsewhere are not version authorities.
var current: Dictionary = result
var seen: Array[Dictionary] = []
while true:
for visited: Dictionary in seen:
if is_same(visited, current): return false
seen.append(current)
var details: Variant = current.get("details")
if not details is Dictionary: return false
if details.has(&"purchase_quote"): return true
var original: Variant = details.get("original_result")
if not original is Dictionary: return false
current = original
return false
static func _valid_result_quotes(result: Dictionary, economy: EconomyService) -> bool:
var current: Dictionary = result
var seen: Array[Dictionary] = []
while true:
for visited: Dictionary in seen:
if is_same(visited, current): return false
seen.append(current)
var details: Variant = current.get("details")
if not details is Dictionary: return false
if details.has(&"purchase_quote"):
# Existing CommandQueue owns all seven result fields; quote results
# additionally retain their exact producer string/container types.
if not _canonical_result(current): return false
var quote: Variant = details[&"purchase_quote"]
if not quote is Dictionary or not valid(quote): return false
if current["code"] == "OK":
if typeof(details.get(&"quantity")) != TYPE_INT or details[&"quantity"] != quote[&"quantity"] \
or typeof(details.get(&"total_cost")) != TYPE_INT or details[&"total_cost"] != quote[&"effective_total"] \
or typeof(details.get(&"warehouse_id")) != TYPE_STRING_NAME or typeof(details.get(&"item_id")) != TYPE_STRING_NAME \
or typeof(details.get(&"transaction_id")) != TYPE_STRING_NAME: return false
var entries := economy.get_transaction_entries(details[&"transaction_id"])
if entries.size() != 1: return false
var receipt := receipt_from_ledger(economy, details[&"warehouse_id"], details[&"item_id"],
(entries[0] as LedgerEntry).absolute_minute, details[&"transaction_id"], false, current["command_id"])
if var_to_bytes(receipt) != var_to_bytes(quote): return false
var original: Variant = details.get("original_result")
if not original is Dictionary: return true
current = original
return false
static func _canonical_result(result: Dictionary) -> bool:
if result.size() != 7: return false
for key: Variant in result:
if typeof(key) != TYPE_STRING or key not in ["code", "command_id", "target_id", "message", "resolution_hints", "details", "is_replay"]: return false
if typeof(result["code"]) != TYPE_STRING or String(result["code"]) not in CommandResult.Code.keys() \
or typeof(result["command_id"]) != TYPE_INT or result["command_id"] <= 0 \
or typeof(result["target_id"]) != TYPE_STRING or typeof(result["message"]) != TYPE_STRING \
or not result["resolution_hints"] is Array or not result["details"] is Dictionary \
or typeof(result["is_replay"]) != TYPE_BOOL: return false
for hint: Variant in result["resolution_hints"]:
if typeof(hint) != TYPE_STRING: return false
return true
static func _manual_command_id_for_transaction(economy: EconomyService, transaction_id: StringName) -> int:
for row: Dictionary in economy.create_snapshot()[&"idempotency"]:
var key: String = row[&"key"]
if row[&"transaction_id"] != String(transaction_id) or not key.begins_with("supply.purchase."): continue
var number := _positive(key.substr("supply.purchase.".length()))
if key == "supply.purchase.%d" % number: return number
return 0
static func keys_match(value: Dictionary, expected: Array[StringName]) -> bool:
if value.size() != expected.size(): return false
for key: Variant in value:
if typeof(key) != TYPE_STRING_NAME or key not in expected: return false
return true
static func _take_text(text: String) -> Dictionary:
var delimiter := text.find(":")
if delimiter <= 0: return {}
var length := _positive(text.substr(0, delimiter))
var rest := text.substr(delimiter + 1)
if length <= 0 or length >= rest.length() or rest.substr(length, 1) != ":": return {}
return {&"text": rest.substr(0, length), &"rest": rest.substr(length + 1)}
static func _positive(text: String) -> int:
if text.is_empty() or text.length() > MAX_INT_TEXT.length() or text.substr(0, 1) == "0": return 0
for index: int in text.length():
var code := text.unicode_at(index)
if code < 48 or code > 57: return 0
if text.length() == MAX_INT_TEXT.length() and text > MAX_INT_TEXT: return 0
return text.to_int()
@@ -0,0 +1 @@
uid://dpihsajte0m6w