extends "res://tests/s3/test_guest_service.gd" var _bulk_records: Array = [] var _bulk_core: Object var _bulk_cases := 0 func _bulk_state(service: GuestService) -> Array: return [service.create_snapshot(), service.last_error, service._decision_rejections.duplicate(true)] func _bulk_service() -> GuestService: var service := _service_with_definitions() service.spawn_guest(&"bulk", &"adventurer", 0, { &"wallet_gold": 500, &"planned_exit_at": 1000, &"state": GuestRuntimeType.State.DECIDING, &"needs": {&"hunger": 80, &"sleep": 30, &"hygiene": 40, &"medical": 20, &"leisure": 60, &"intimacy": 50}, }) return service func _bulk_compare(label: String, rows: Array, patch: Dictionary = {}, context: Dictionary = {}) -> void: _bulk_cases += 1 var service := _bulk_service() var guest := service.get_guest(&"bulk") for key: Variant in patch: guest.set(key, patch[key]) service.last_error = "retained-before-pure-call" var before := var_to_bytes(_bulk_state(service)) var input_before := var_to_bytes(rows) var batch: Dictionary = _bulk_core.call(&"guest_candidate_batch", service, &"bulk", rows, context) _expect(bool(batch.get(&"supported", false)), label + " supported fixed pure input") _expect(var_to_bytes(_bulk_state(service)) == before, label + " pure call preserves full Guest snapshot/errors/rejections") _expect(var_to_bytes(rows) == input_before, label + " input ownership preserved") if not bool(batch.get(&"supported", false)): return var accepted := service.extract_candidates(&"bulk", rows, context) var rejected := service.get_last_candidate_rejections(&"bulk") var ranked := service.rank_candidates(&"bulk", accepted) _expect(var_to_bytes(batch[&"accepted"]) == var_to_bytes(accepted), label + " entire ordered typed accepted original equality") _expect(var_to_bytes(batch[&"rejected"]) == var_to_bytes(rejected), label + " entire ordered typed rejection original equality") _expect(var_to_bytes(batch[&"ranked"]) == var_to_bytes(ranked), label + " entire ordered typed scoring/ranking original equality") _bulk_records.append({&"case": label, &"input": rows.duplicate(true), &"context": context.duplicate(true), &"patch": patch.duplicate(true), &"actual": batch.duplicate(true), &"accepted_original": accepted, &"rejected_original": rejected, &"ranked_original": ranked}) if not (batch[&"ranked"] as Array).is_empty(): var accepted_before := var_to_bytes(batch[&"accepted"]) var actual: Dictionary = batch[&"ranked"][0] actual[&"ownership_probe"] = true if actual.get(&"path_handle") is Dictionary: actual[&"path_handle"][&"ownership_probe"] = true _expect(var_to_bytes(rows) == input_before, label + " ranked mutation is isolated from caller input") _expect(var_to_bytes(batch[&"accepted"]) == accepted_before, label + " ranked deep copy is isolated from accepted candidates") func _test_bulk_candidates() -> void: _bulk_core = ClassDB.instantiate(&"TheTreeNumericCore") _expect(_bulk_core != null and _bulk_core.has_method(&"guest_candidate_batch"), "exact new batch binding exists") if _bulk_core == null or not _bulk_core.has_method(&"guest_candidate_batch"): return var base := _candidate(&"a", {&"need_relief": {&"hunger": 80, &"leisure": 20}, &"facility_tags": [&"meal", &"leisure", &"meal"], &"path_handle": {&"path": [Vector3i.ZERO, Vector3i(1, 0, 0)], &"target_cell": Vector3i(1, 0, 0)}}) _bulk_compare("ordinary", [base]) _bulk_compare("empty", []) _bulk_compare("skip-nondictionary-and-empty-id", [null, 4, "ignored", {}, {&"facility_id": &""}, base]) var duplicates: Array = [] for i in range(64): var row := base.duplicate(true) row[&"facility_id"] = StringName("b" if i % 3 == 0 else "a") row[&"probe_index"] = i duplicates.append(row) _bulk_compare("equal-sort-keys64", duplicates) var branches := [ {&"need_relief": {&"rest": 1}, &"inputs_available": false}, {&"need_effects": {&"hunger": 1.0}}, {&"need_relief": null}, {&"need_relief": true}, {&"inputs_available": false, &"adult_only": true}, {&"adult_only": true}, {&"required_guest_tags": [&"missing"]}, {&"forbidden_guest_tags": [&"general"]}, {&"allowed_guest_types": [&"other"]}, {&"is_open": false, &"reachable": false}, {&"reachable": false}, {&"travel_minutes": 1001}, {&"price_gold": 10000}, {&"wait_minutes": 120}, {&"risk_level": 100}, {&"illegal_level": 100}, {&"expected_quality": 0}, {&"is_open": false, &"open_at_arrival": true}, {&"credit_allowed": true, &"price_gold": 550}, {&"discretionary": true, &"price_gold": 400}, {&"respect_survival_reserve": false, &"discretionary": true, &"price_gold": 400}, {&"risk": 90, &"risk_level": 0, &"risk_sensitivity": 3}, {&"legal_permission_override": true, &"illegal_level": 100}, {&"need_relief": -100, &"travel_minutes": -2, &"wait_minutes": -3}, {&"ok": false}, {&"ok": 0}, {&"preference": 9223372036854775807, &"group_fit": -9223372036854775808, &"repetition_penalty": -9223372036854775808}, {&"price_gold": 9223372036854775807, &"credit_allowed": true}, {&"risk": 9223372036854775807, &"risk_level": 0, &"risk_sensitivity": 9223372036854775807}, {&"need_relief": {"hunger": 9223372036854775807, "medical": -9223372036854775808}}, {&"novelty": -10, &"urgency": 77, &"price_burden": 100}, ] for i in range(branches.size()): var row := base.duplicate(true) for key: Variant in branches[i]: row[key] = branches[i][key] _bulk_compare("branch-%02d" % i, [row, base]) var string_keys := {} for key: Variant in base: string_keys[String(key)] = base[key] _bulk_compare("string-keys", [string_keys]) _bulk_compare("visited-defaults", [base], {&"visited_facility_ids": [&"a"]}) _bulk_compare("addiction-removes-reserve", [_candidate(&"a", {&"discretionary": true, &"price_gold": 500})], {&"addiction_by_tag": {&"gambling": 75}}) _bulk_compare("wallet-wrap", [base], {&"wallet_gold": 9223372036854775807, &"credit_limit_gold": 9223372036854775807, &"debt_gold": -9223372036854775808}) _bulk_compare("context-gates", [base], {}, {&"absolute_minute": 999, &"wait_hard_limit": 1}) _test_bulk_fallback_and_decision(base) func _test_bulk_fallback_and_decision(base: Dictionary) -> void: for label in ["ordinary", "float-conversion", "reach-callback", "reserve-callback"]: var actual := _bulk_service() var oracle := GuestServiceType.new() _expect(oracle.restore_snapshot(actual.create_snapshot()), label + " original independent Guest state restored") var a_calls: Array = [] var b_calls: Array = [] var a_context := {&"absolute_minute": 10} var b_context := {&"absolute_minute": 10} if label == "reach-callback": a_context[&"reachability_callback"] = func(_guest: GuestRuntime, candidate: Dictionary, _context: Dictionary) -> bool: a_calls.append(candidate[&"facility_id"]); candidate[&"callback_probe"] = true; return true b_context[&"reachability_callback"] = func(_guest: GuestRuntime, candidate: Dictionary, _context: Dictionary) -> bool: b_calls.append(candidate[&"facility_id"]); candidate[&"callback_probe"] = true; return true if label == "reserve-callback": a_context[&"reserve_callback"] = func(_guest_id: StringName, facility_id: StringName, candidate: Dictionary) -> bool: a_calls.append(facility_id); candidate[&"callback_probe"] = true; return true b_context[&"reserve_callback"] = func(_guest_id: StringName, facility_id: StringName, candidate: Dictionary) -> bool: b_calls.append(facility_id); candidate[&"callback_probe"] = true; return true var row := base.duplicate(true) if label == "float-conversion": row[&"travel_minutes"] = 1.75 var input_before := var_to_bytes([row]) var state_before := var_to_bytes(_bulk_state(actual)) var batch: Dictionary = _bulk_core.call(&"guest_candidate_batch", actual, &"bulk", [row], a_context) _expect(bool(batch[&"supported"]) == (label == "ordinary"), label + " supported or whole original fallback domain") _expect(var_to_bytes(_bulk_state(actual)) == state_before and a_calls.is_empty(), label + " probe causes no observable state/callback effects") var got := actual.decide_with_native_candidates(_bulk_core, &"bulk", [row], 10, a_context) var expected := oracle.decide(&"bulk", [row], 10, b_context) _expect(var_to_bytes(got) == var_to_bytes(expected), label + " entire typed decision result matches original") _expect(var_to_bytes(_bulk_state(actual)) == var_to_bytes(_bulk_state(oracle)), label + " entire Guest state/errors/rejection matches original") _expect(a_calls == b_calls, label + " callback count/order preserves original single dispatch") _expect(var_to_bytes([row]) == input_before, label + " decision input ownership preserved") _bulk_records.append({&"decision_case": label, &"actual_result": got, &"original_result": expected, &"actual_state": _bulk_state(actual), &"original_state": _bulk_state(oracle), &"actual_calls": a_calls, &"original_calls": b_calls}) _bulk_core = null func _bulk_sha256(bytes: PackedByteArray) -> String: var digest := HashingContext.new() if digest.start(HashingContext.HASH_SHA256) != OK: return "" if digest.update(bytes) != OK: return "" return digest.finish().hex_encode() func _run() -> void: _test_definition_and_runtime_contract() _test_need_updates_and_single_clamp() _test_need_context_and_adult_gate() _test_shared_need_context_fast_paths() _test_batched_need_updates_match_individual_api() _test_candidate_filtering() _test_integer_utility_and_stable_tie_break() _test_primary_need_priority() _test_state_machine_and_loop_guard() _test_atomic_queue_abandonment() _test_service_interruption_is_idempotent() _test_service_need_effect_schema() _test_path_failure_safe_recovery() _test_exit_persistence_boundary() _test_overdue_departure_snapshot() _test_snapshot_round_trip_and_atomic_rejection() _test_v1_need_migration_and_schema_rejection() _test_deterministic_decision_snapshot() _test_bulk_candidates() var output := OS.get_environment("THE_TREE_RUNTIME_MONITOR_OUTPUT") var bytes := var_to_bytes(_bulk_records) var file := FileAccess.open(output.path_join("fixtures.varbytes"), FileAccess.WRITE) if file == null: quit(98); return file.store_buffer(bytes); file.close() var report := {"passed": _failures == 0, "checks": _checks, "failures": _failures, "pure_case_count": _bulk_cases, "decision_case_count": 4, "original_s3_invocations": 18, "pid": OS.get_process_id(), "fixture_bytes": bytes.size(), "fixture_sha256": _bulk_sha256(bytes), "performance_accepted": false, "unit_accepted": false} file = FileAccess.open(output.path_join("report.json"), FileAccess.WRITE) if file == null: quit(98); return file.store_string(JSON.stringify(report, "\t") + "\n"); file.close() print("Guest bulk local: %d checks, %d failures" % [_checks, _failures]) quit(0 if _failures == 0 else 1)