diff --git a/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.json b/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.json index 342b091..c8501d6 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.json +++ b/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.json @@ -52,7 +52,7 @@ "completed_count": null, "evidence": [], "missing": "original production content missing or undefined", - "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。", + "reason": "欠損: 制作内容は欠損。undefinedは章の範囲・数量のみを指す。章名・順序・場面一覧は原本未定義、D08未決。", "owner": "P00/P15/P17/P19/P20/P28", "atomic_requirement_ids": [ "AR.economy.front_faith", @@ -461,7 +461,7 @@ "completed_count": null, "evidence": [], "missing": "original production content missing or undefined", - "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。", + "reason": "欠損: 制作内容は欠損。undefinedは台詞の範囲・数量のみを指す。本文・話者・場面単位は原本未定義、D08未決。", "owner": "P00/P19/P25", "atomic_requirement_ids": [ "AR.art.anime_portrait", @@ -635,7 +635,7 @@ "completed_count": null, "evidence": [], "missing": "original production content missing or undefined", - "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。", + "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.schedule.B-14.3.observation: uncredited precursor, not required behaviour (dedicated observation mode achievement)。関連基盤コードは存在するが当該ARの証拠には帰属させない。", "owner": "P00/P25/P26", "atomic_requirement_ids": [ "AR.asset.audio_adult", @@ -795,14 +795,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" }, { "path": "scripts/special/peeping_room_service.gd", @@ -812,9 +858,33 @@ "anchor_path": "scripts/special/peeping_room_service.gd", "lines": [ 127, - 162 + 138 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," + "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 140, + 142 + ], + "text": "func record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 155, + 164 + ], + "text": "func controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id,\n\t\t\t&\"target_instance_id\": target_id, &\"source_event_key\": source_event_key, &\"minute\": minute}\n\treturn {&\"ok\": true, &\"reason\": &\"OK\", &\"evidence_id\": evidence_id, &\"duplicated\": duplicated}" }, { "path": "autoload/simulation_runtime.gd", @@ -823,14 +893,14 @@ "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "autoload/simulation_runtime.gd", "lines": [ - 10860, - 10880 + 10863, + 10864 ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")" } ], "missing": "original production content missing or undefined", - "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。", + "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.underground.blackmail: uncredited precursor, not required behaviour (blackmail transaction state and income)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。", "owner": "P16/P19", "atomic_requirement_ids": [ "AR.heroine.amelia.route.corruption", @@ -865,7 +935,7 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion; stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content; observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content", "scoped_support": [ { "kind": "relationship-container", @@ -892,21 +962,21 @@ "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" }, { "kind": "peeping-container", "atomic_requirement_ids": [ - "AR.underground.blackmail", "AR.underground.observation" ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content", "content_status": "missing" } ], "unsupported_atomic_requirement_ids": [ "AR.narrative.route_tones", + "AR.underground.blackmail", "AR.underground.trade_people" ] }, @@ -997,42 +1067,64 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" }, { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", + "anchor_path": "scripts/relationship/relationship_service.gd", "lines": [ - 127, - 162 + 315, + 355 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", - "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。", + "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.route_action.observation_progress: uncredited precursor, not required behaviour (route progress from observation room)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。", "owner": "P18/P19/P26", "atomic_requirement_ids": [ "AR.asset.portrait_brand", @@ -1104,7 +1196,7 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion; stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", @@ -1133,15 +1225,7 @@ "AR.relationship.affection_shield_max", "AR.relationship.three_emotions" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", - "content_status": "missing" - }, - { - "kind": "peeping-container", - "atomic_requirement_ids": [ - "AR.route_action.observation_progress" - ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -1178,6 +1262,7 @@ "AR.route_action.duel_removal", "AR.route_action.item_lust", "AR.route_action.neglect_weakens", + "AR.route_action.observation_progress", "AR.route_action.rival_isolation", "AR.route_action.shield_cap_loss", "AR.route_action.talk_heal", @@ -1401,37 +1486,12 @@ } ], "required_condition": "原本のシナリオ/素材量産/音声制作と受入は未完。", - "status": "partial", + "status": "missing", "required_count": null, "completed_count": null, - "evidence": [ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } - ], + "evidence": [], "missing": "original production content missing or undefined", - "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。", + "reason": "欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.schedule.B-14.3.observation: uncredited precursor, not required behaviour (dedicated observation mode achievement)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。", "owner": "P00/P25/P26", "atomic_requirement_ids": [ "AR.asset.audio_adult", @@ -1465,17 +1525,8 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "scoped_support": [ - { - "kind": "peeping-container", - "atomic_requirement_ids": [ - "AR.schedule.B-14.3.observation" - ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "content_status": "missing" - } - ], + "support_scope": "no dedicated support established", + "scoped_support": [], "unsupported_atomic_requirement_ids": [ "AR.asset.audio_adult", "AR.asset.character_voice", @@ -1493,6 +1544,7 @@ "AR.schedule.B-14.2.tiles", "AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", + "AR.schedule.B-14.3.observation", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record", "AR.schedule.B-14.4.debug", @@ -1569,14 +1621,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -1590,14 +1688,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.anri.route.love" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -1671,14 +1769,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -1692,14 +1836,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.anri.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -1773,14 +1917,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -1794,14 +1984,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.anri.route.corruption" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -1875,14 +2065,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -1896,14 +2132,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.fine.route.love" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -1977,14 +2213,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -1998,14 +2280,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.fine.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2079,14 +2361,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2100,14 +2428,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.fine.route.corruption" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2181,14 +2509,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2202,14 +2576,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.tomari.route.love" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2283,14 +2657,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2304,14 +2724,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.tomari.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2385,14 +2805,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2406,14 +2872,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.tomari.route.corruption" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2487,14 +2953,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2508,14 +3020,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.amelia.route.love" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2589,14 +3101,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2610,14 +3168,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.amelia.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2691,14 +3249,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2712,14 +3316,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.amelia.route.corruption" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2793,14 +3397,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2814,14 +3464,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.liz.route.love" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2895,14 +3545,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -2916,14 +3612,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.liz.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -2997,14 +3693,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -3018,14 +3760,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.liz.route.corruption" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -3099,14 +3841,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -3120,14 +3908,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.mimi.route.love" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -3201,14 +3989,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -3222,14 +4056,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.mimi.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -3303,14 +4137,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -3324,14 +4204,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.mimi.route.corruption" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -3405,14 +4285,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -3426,14 +4352,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.satsuki.route.love" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -3507,14 +4433,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -3528,14 +4500,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.satsuki.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -3609,14 +4581,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -3630,14 +4648,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.heroine.satsuki.route.corruption" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -327405,7 +328423,7 @@ "completed_count": null, "evidence": [], "missing": "original production content missing or undefined", - "reason": "欠損: 利用枠/用途群。既存表現の現物SHAを再取得。汎用描画/仮素材は固有人物・必須差分の完成証明ではない。D09数量/品質/担当未決。", + "reason": "欠損: 利用枠/用途群。既存表現の現物SHAを再取得。汎用描画/仮素材は固有人物・必須差分の完成証明ではない。D09数量/品質/担当未決。 AR.ui.observation_camera_entry: uncredited precursor, not required behaviour (camera icon and dedicated observation screen transition)。関連基盤コードは存在するが当該ARの証拠には帰属させない。", "owner": "P24", "atomic_requirement_ids": [ "AR.ui.observation_camera_entry" @@ -332661,14 +333679,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -332707,7 +333771,7 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", @@ -332734,7 +333798,7 @@ "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -332989,37 +334053,12 @@ } ], "required_condition": "原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。", - "status": "partial", + "status": "missing", "required_count": null, "completed_count": null, - "evidence": [ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } - ], + "evidence": [], "missing": "original production content missing or undefined", - "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", + "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.underground.blackmail: uncredited precursor, not required behaviour (blackmail transaction state and income)。関連基盤コードは存在するが当該ARの証拠には帰属させない。", "owner": "P16/P19", "atomic_requirement_ids": [ "AR.staff.back_routes", @@ -333032,19 +334071,11 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "scoped_support": [ - { - "kind": "peeping-container", - "atomic_requirement_ids": [ - "AR.underground.blackmail" - ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "content_status": "missing" - } - ], + "support_scope": "no dedicated support established", + "scoped_support": [], "unsupported_atomic_requirement_ids": [ "AR.staff.back_routes", + "AR.underground.blackmail", "AR.underground.trade_people" ] }, @@ -333322,14 +334353,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -333371,7 +334448,7 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", @@ -333398,7 +334475,7 @@ "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -333437,14 +334514,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -333479,7 +334602,7 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", @@ -333506,7 +334629,7 @@ "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -333542,9 +334665,33 @@ "anchor_path": "scripts/special/peeping_room_service.gd", "lines": [ 127, - 162 + 138 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," + "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 140, + 142 + ], + "text": "func record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 155, + 164 + ], + "text": "func controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id,\n\t\t\t&\"target_instance_id\": target_id, &\"source_event_key\": source_event_key, &\"minute\": minute}\n\treturn {&\"ok\": true, &\"reason\": &\"OK\", &\"evidence_id\": evidence_id, &\"duplicated\": duplicated}" }, { "path": "autoload/simulation_runtime.gd", @@ -333553,14 +334700,14 @@ "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "autoload/simulation_runtime.gd", "lines": [ - 10860, - 10880 + 10863, + 10864 ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")" } ], "missing": "original production content missing or undefined", - "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", + "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.underground.blackmail: uncredited precursor, not required behaviour (blackmail transaction state and income)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", "owner": "P16/P19", "atomic_requirement_ids": [ "AR.underground.blackmail", @@ -333573,19 +334720,19 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "support_scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content", "scoped_support": [ { "kind": "peeping-container", "atomic_requirement_ids": [ - "AR.underground.blackmail", "AR.underground.observation" ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content", "content_status": "missing" } ], "unsupported_atomic_requirement_ids": [ + "AR.underground.blackmail", "AR.underground.trade_people" ] }, @@ -333874,9 +335021,33 @@ "anchor_path": "scripts/special/peeping_room_service.gd", "lines": [ 127, - 162 + 138 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," + "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 140, + 142 + ], + "text": "func record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 155, + 164 + ], + "text": "func controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id,\n\t\t\t&\"target_instance_id\": target_id, &\"source_event_key\": source_event_key, &\"minute\": minute}\n\treturn {&\"ok\": true, &\"reason\": &\"OK\", &\"evidence_id\": evidence_id, &\"duplicated\": duplicated}" }, { "path": "autoload/simulation_runtime.gd", @@ -333885,10 +335056,10 @@ "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "autoload/simulation_runtime.gd", "lines": [ - 10860, - 10880 + 10863, + 10864 ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")" } ], "missing": "original production content missing or undefined", @@ -333903,14 +335074,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "support_scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content", "scoped_support": [ { "kind": "peeping-container", "atomic_requirement_ids": [ "AR.observation.recorder" ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", + "scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content", "content_status": "missing" } ], @@ -333946,13 +335117,13 @@ "anchor_path": "scripts/guest/guest_service.gd", "lines": [ 355, - 360 + 359 ], - "text": "\t\tif definition.adult_verified:\n\t\t\tvar intimacy_key := &\"intimacy_night\" \\\n\t\t\t\tif bool(_value(context, &\"is_night\", false)) \\\n\t\t\t\telse &\"intimacy_day\"\n\t\t\tdelta_intimacy += int(_value(context, intimacy_key, 0))\n\t\tvar raw_effects: Variant = _value(context, &\"need_effects\", {})" + "text": "\t\tif definition.adult_verified:\n\t\t\tvar intimacy_key := &\"intimacy_night\" \\\n\t\t\t\tif bool(_value(context, &\"is_night\", false)) \\\n\t\t\t\telse &\"intimacy_day\"\n\t\t\tdelta_intimacy += int(_value(context, intimacy_key, 0))" } ], "missing": "original production content missing or undefined", - "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", + "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.events.ntr_night_peak: uncredited precursor, not required behaviour (NTR event night peak)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", "owner": "P04/P15/P19", "atomic_requirement_ids": [ "AR.events.ntr_night_peak", @@ -333968,19 +335139,19 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "night-dependent guest need input only; no event production or peak-frequency implementation", + "support_scope": "adult intimacy need selects intimacy_night or intimacy_day input key from is_night only; no peak values, NTR events or event production", "scoped_support": [ { "kind": "night-input", "atomic_requirement_ids": [ - "AR.events.ntr_night_peak", "AR.guest.need_sexual_night_peak" ], - "scope": "night-dependent guest need input only; no event production or peak-frequency implementation", + "scope": "adult intimacy need selects intimacy_night or intimacy_day input key from is_night only; no peak values, NTR events or event production", "content_status": "missing" } ], "unsupported_atomic_requirement_ids": [ + "AR.events.ntr_night_peak", "AR.guest.night_sleep", "AR.guest.night_underground", "AR.time.night_phase" @@ -334091,10 +335262,10 @@ "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "scripts/operations/operations_coordinator.gd", "lines": [ - 1183, - 1195 + 1190, + 1194 ], - "text": "\tvar category_totals: Dictionary = result[&\"category_totals\"]\n\tvar net_profit := _net_profit(category_totals)\n\tvar previous_profit := net_profit\n\tif _day_summaries.has(completed_day - 1):\n\t\tprevious_profit = int((_day_summaries[completed_day - 1] as Dictionary)[&\"net_profit\"])\n\tvar rolling := _rolling_profit_with(net_profit)\n\tvar arrears := int((result[&\"settlement\"] as Dictionary)[&\"arrears_total\"])\n\tvar prior_streak := 0 if completed_day == _legacy_history_last_day + 1 else _consecutive_insolvency_count\n\tvar consecutive := prior_streak + 1 if net_profit < 0 else 0\n\tvar future_terminal := _terminal_state\n\tif consecutive >= int(_config[&\"bankruptcy_close_count\"]):\n\t\tfuture_terminal = TERMINAL_BANKRUPT\n\tvar reconciliation_difference := int(result[&\"reconciliation_difference\"])" + "text": "\tvar prior_streak := 0 if completed_day == _legacy_history_last_day + 1 else _consecutive_insolvency_count\n\tvar consecutive := prior_streak + 1 if net_profit < 0 else 0\n\tvar future_terminal := _terminal_state\n\tif consecutive >= int(_config[&\"bankruptcy_close_count\"]):\n\t\tfuture_terminal = TERMINAL_BANKRUPT" } ], "missing": "original production content missing or undefined", @@ -334108,14 +335279,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "bankruptcy terminal bookkeeping only; no authored ending", + "support_scope": "consecutive negative-net-profit counter reaches config bankruptcy_close_count and selects TERMINAL_BANKRUPT only; configured value 3 is not established; no authored game-over ending", "scoped_support": [ { "kind": "bankruptcy-bookkeeping", "atomic_requirement_ids": [ "AR.progression.three_deficits_gameover" ], - "scope": "bankruptcy terminal bookkeeping only; no authored ending", + "scope": "consecutive negative-net-profit counter reaches config bankruptcy_close_count and selects TERMINAL_BANKRUPT only; configured value 3 is not established; no authored game-over ending", "content_status": "missing" } ], @@ -335091,14 +336262,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -335134,7 +336351,7 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", @@ -335162,7 +336379,7 @@ "AR.heroine.tomari.route.ntr", "AR.relationship.three_emotions" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -335193,14 +336410,60 @@ "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ], "missing": "original production content missing or undefined", @@ -335214,14 +336477,14 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "support_scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "scoped_support": [ { "kind": "relationship-container", "atomic_requirement_ids": [ "AR.relationship.affection_shield_max" ], - "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion", + "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content", "content_status": "missing" } ], @@ -335699,37 +336962,12 @@ } ], "required_condition": "原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。", - "status": "partial", + "status": "missing", "required_count": null, "completed_count": null, - "evidence": [ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } - ], + "evidence": [], "missing": "original production content missing or undefined", - "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", + "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.route_action.observation_progress: uncredited precursor, not required behaviour (route progress from observation room)。関連基盤コードは存在するが当該ARの証拠には帰属させない。", "owner": "P19", "atomic_requirement_ids": [ "AR.route_action.neglect_weakens", @@ -335741,19 +336979,11 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "scoped_support": [ - { - "kind": "peeping-container", - "atomic_requirement_ids": [ - "AR.route_action.observation_progress" - ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "content_status": "missing" - } - ], + "support_scope": "no dedicated support established", + "scoped_support": [], "unsupported_atomic_requirement_ids": [ "AR.route_action.neglect_weakens", + "AR.route_action.observation_progress", "AR.route_action.underground_weakens" ] }, @@ -336739,37 +337969,12 @@ } ], "required_condition": "原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。", - "status": "partial", + "status": "missing", "required_count": null, "completed_count": null, - "evidence": [ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } - ], + "evidence": [], "missing": "original production content missing or undefined", - "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", + "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.ui.observation_camera_entry: uncredited precursor, not required behaviour (camera icon and dedicated observation screen transition)。関連基盤コードは存在するが当該ARの証拠には帰属させない。", "owner": "P24", "atomic_requirement_ids": [ "AR.ui.observation_camera_entry" @@ -336779,18 +337984,11 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "scoped_support": [ - { - "kind": "peeping-container", - "atomic_requirement_ids": [ - "AR.ui.observation_camera_entry" - ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "content_status": "missing" - } - ], - "unsupported_atomic_requirement_ids": [] + "support_scope": "no dedicated support established", + "scoped_support": [], + "unsupported_atomic_requirement_ids": [ + "AR.ui.observation_camera_entry" + ] }, { "id": "original.line.222", @@ -336808,37 +338006,12 @@ } ], "required_condition": "原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。", - "status": "partial", + "status": "missing", "required_count": null, "completed_count": null, - "evidence": [ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } - ], + "evidence": [], "missing": "original production content missing or undefined", - "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", + "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.ui.observation_capture: uncredited precursor, not required behaviour (screenshot evidence collection)。関連基盤コードは存在するが当該ARの証拠には帰属させない。", "owner": "P24", "atomic_requirement_ids": [ "AR.ui.observation_angle", @@ -336850,19 +338023,11 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "scoped_support": [ - { - "kind": "peeping-container", - "atomic_requirement_ids": [ - "AR.ui.observation_capture" - ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "content_status": "missing" - } - ], + "support_scope": "no dedicated support established", + "scoped_support": [], "unsupported_atomic_requirement_ids": [ "AR.ui.observation_angle", + "AR.ui.observation_capture", "AR.ui.observation_intervention" ] }, @@ -338411,37 +339576,12 @@ } ], "required_condition": "原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。", - "status": "partial", + "status": "missing", "required_count": null, "completed_count": null, - "evidence": [ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } - ], + "evidence": [], "missing": "original production content missing or undefined", - "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。", + "reason": "原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.schedule.B-14.3.observation: uncredited precursor, not required behaviour (dedicated observation mode achievement)。関連基盤コードは存在するが当該ARの証拠には帰属させない。", "owner": "P00", "atomic_requirement_ids": [ "AR.schedule.B-14.3.adult", @@ -338455,20 +339595,12 @@ ], "owner_assignment": "original package deliverables; specific production assignee undefined", "content_status": "missing", - "support_scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "scoped_support": [ - { - "kind": "peeping-container", - "atomic_requirement_ids": [ - "AR.schedule.B-14.3.observation" - ], - "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content", - "content_status": "missing" - } - ], + "support_scope": "no dedicated support established", + "scoped_support": [], "unsupported_atomic_requirement_ids": [ "AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", + "AR.schedule.B-14.3.observation", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record" ] diff --git a/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.md b/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.md index 88e8777..8c54108 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.md +++ b/docs/plans/original-completion-2026-10-02/execution/p26-01/CONTENT_LEDGER.md @@ -17,7 +17,7 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 - 基盤支援なしのAR: ["AR.economy.front_faith", "AR.guest.addiction_all_wealth", "AR.guest.addiction_budget_priority", "AR.guest.underground_addiction", "AR.heroine.amelia.identity", "AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.identity", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.identity", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.identity", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.identity", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.identity", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.identity", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.narrative.protagonist_goal", "AR.narrative.protagonist_past", "AR.narrative.tree_origin", "AR.progression.faith_story", "AR.progression.main_duration", "AR.schedule.B-14.2.bgm", "AR.schedule.B-14.2.parameters", "AR.schedule.B-14.2.portraits", "AR.schedule.B-14.2.scenario", "AR.schedule.B-14.2.tiles"] - 所管単位: ["P00", "P15", "P17", "P19", "P20", "P28"] (固定参照の原P単位定義を参照) - 条件: メインストーリー全章。原本の仕様書章番号をシナリオ章と混同しない。章名・章数・順序・場面一覧は未定義。 -- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 +- 理由: 欠損: 制作内容は欠損。undefinedは章の範囲・数量のみを指す。章名・順序・場面一覧は原本未定義、D08未決。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -189,7 +189,7 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 - 基盤支援なしのAR: ["AR.art.anime_portrait", "AR.art.pixel_map", "AR.art.pixel_sd", "AR.route_action.date_heal", "AR.route_action.duel_removal", "AR.route_action.rival_isolation", "AR.route_action.talk_heal", "AR.schedule.B-14.2.bgm", "AR.schedule.B-14.2.parameters", "AR.schedule.B-14.2.portraits", "AR.schedule.B-14.2.scenario", "AR.schedule.B-14.2.tiles"] - 所管単位: ["P00", "P19", "P25"] (固定参照の原P単位定義を参照) - 条件: 会話/イベント用台詞とシナリオ。本文・話者・行数・場面単位は未定義。UI通知文を完成脚本に数えない。 -- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 +- 理由: 欠損: 制作内容は欠損。undefinedは台詞の範囲・数量のみを指す。本文・話者・場面単位は原本未定義、D08未決。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -278,7 +278,7 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 - 基盤支援なしのAR: ["AR.asset.audio_adult", "AR.asset.character_voice", "AR.asset.dynamic_bgm", "AR.asset.environment_audio", "AR.asset.ui_audio", "AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", "AR.schedule.B-14.3.observation", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record"] - 所管単位: ["P00", "P25", "P26"] (固定参照の原P単位定義を参照) - 条件: キャラクターボイスの収録・実装。話者/台詞/クリップ数/担当未定義。BGMやUI音は代用不可。 -- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 +- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.schedule.B-14.3.observation: uncredited precursor, not required behaviour (dedicated observation mode achievement)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -339,13 +339,13 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 - 状態: partial - 所管: P16/P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion; stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content; observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content - AR: ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.narrative.route_tones", "AR.underground.blackmail", "AR.underground.observation", "AR.underground.trade_people"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}, {"atomic_requirement_ids": ["AR.underground.blackmail", "AR.underground.observation"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.narrative.route_tones", "AR.underground.trade_people"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}, {"atomic_requirement_ids": ["AR.underground.observation"], "content_status": "missing", "kind": "peeping-container", "scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content"}] +- 基盤支援なしのAR: ["AR.narrative.route_tones", "AR.underground.blackmail", "AR.underground.trade_people"] - 所管単位: ["P16", "P19"] (固定参照の原P単位定義を参照) - 条件: 原本表現要求と今回の非露骨な監査範囲との差異を残す。 -- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。 +- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.underground.blackmail: uncredited precursor, not required behaviour (blackmail transaction state and income)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -367,14 +367,60 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" }, { "path": "scripts/special/peeping_room_service.gd", @@ -384,9 +430,33 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 "anchor_path": "scripts/special/peeping_room_service.gd", "lines": [ 127, - 162 + 138 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," + "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 140, + 142 + ], + "text": "func record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 155, + 164 + ], + "text": "func controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id,\n\t\t\t&\"target_instance_id\": target_id, &\"source_event_key\": source_event_key, &\"minute\": minute}\n\treturn {&\"ok\": true, &\"reason\": &\"OK\", &\"evidence_id\": evidence_id, &\"duplicated\": duplicated}" }, { "path": "autoload/simulation_runtime.gd", @@ -395,10 +465,10 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "autoload/simulation_runtime.gd", "lines": [ - 10860, - 10880 + 10863, + 10864 ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")" } ] ``` @@ -446,13 +516,13 @@ D05の過去未解決記録はf4f85bc/379a1ba時点。現行承認は別途固 - 状態: partial - 所管: P18/P19/P26 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion; stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.asset.portrait_brand", "AR.asset.portrait_collar", "AR.asset.portrait_kiss_mark", "AR.asset.portrait_ring", "AR.asset.portrait_sigil", "AR.duel.business", "AR.duel.combat", "AR.duel.loss_route_lock", "AR.duel.third_type", "AR.duel.win_exile", "AR.duel.win_full_shield", "AR.duel.win_subordinate", "AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.history.current_partner", "AR.history.cycle", "AR.history.experience_count", "AR.history.first_partner", "AR.history.parentage", "AR.history.pregnancy_appearance", "AR.history.pregnancy_stats", "AR.relationship.affection_shield_max", "AR.relationship.coassigned_attack", "AR.relationship.contact_after_break", "AR.relationship.lust_reduces_defense", "AR.relationship.ntr_after_break", "AR.relationship.shield_blocks", "AR.relationship.three_emotions", "AR.relationship.threshold_love_loss", "AR.relationship.threshold_shield_loss", "AR.relationship.zero_break", "AR.route_action.corruption_terminal", "AR.route_action.date_heal", "AR.route_action.duel_removal", "AR.route_action.item_lust", "AR.route_action.neglect_weakens", "AR.route_action.observation_progress", "AR.route_action.rival_isolation", "AR.route_action.shield_cap_loss", "AR.route_action.talk_heal", "AR.route_action.underground_weakens", "AR.route_action.work_lust"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.relationship.affection_shield_max", "AR.relationship.three_emotions"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}, {"atomic_requirement_ids": ["AR.route_action.observation_progress"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.asset.portrait_brand", "AR.asset.portrait_collar", "AR.asset.portrait_kiss_mark", "AR.asset.portrait_ring", "AR.asset.portrait_sigil", "AR.duel.business", "AR.duel.combat", "AR.duel.loss_route_lock", "AR.duel.third_type", "AR.duel.win_exile", "AR.duel.win_full_shield", "AR.duel.win_subordinate", "AR.history.current_partner", "AR.history.cycle", "AR.history.experience_count", "AR.history.first_partner", "AR.history.parentage", "AR.history.pregnancy_appearance", "AR.history.pregnancy_stats", "AR.relationship.coassigned_attack", "AR.relationship.contact_after_break", "AR.relationship.lust_reduces_defense", "AR.relationship.ntr_after_break", "AR.relationship.shield_blocks", "AR.relationship.threshold_love_loss", "AR.relationship.threshold_shield_loss", "AR.relationship.zero_break", "AR.route_action.corruption_terminal", "AR.route_action.date_heal", "AR.route_action.duel_removal", "AR.route_action.item_lust", "AR.route_action.neglect_weakens", "AR.route_action.rival_isolation", "AR.route_action.shield_cap_loss", "AR.route_action.talk_heal", "AR.route_action.underground_weakens", "AR.route_action.work_lust"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.relationship.affection_shield_max", "AR.relationship.three_emotions"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] +- 基盤支援なしのAR: ["AR.asset.portrait_brand", "AR.asset.portrait_collar", "AR.asset.portrait_kiss_mark", "AR.asset.portrait_ring", "AR.asset.portrait_sigil", "AR.duel.business", "AR.duel.combat", "AR.duel.loss_route_lock", "AR.duel.third_type", "AR.duel.win_exile", "AR.duel.win_full_shield", "AR.duel.win_subordinate", "AR.history.current_partner", "AR.history.cycle", "AR.history.experience_count", "AR.history.first_partner", "AR.history.parentage", "AR.history.pregnancy_appearance", "AR.history.pregnancy_stats", "AR.relationship.coassigned_attack", "AR.relationship.contact_after_break", "AR.relationship.lust_reduces_defense", "AR.relationship.ntr_after_break", "AR.relationship.shield_blocks", "AR.relationship.threshold_love_loss", "AR.relationship.threshold_shield_loss", "AR.relationship.zero_break", "AR.route_action.corruption_terminal", "AR.route_action.date_heal", "AR.route_action.duel_removal", "AR.route_action.item_lust", "AR.route_action.neglect_weakens", "AR.route_action.observation_progress", "AR.route_action.rival_isolation", "AR.route_action.shield_cap_loss", "AR.route_action.talk_heal", "AR.route_action.underground_weakens", "AR.route_action.work_lust"] - 所管単位: ["P18", "P19", "P26"] (固定参照の原P単位定義を参照) - 条件: 3軸/盾・侵食・3種決闘・プレイヤー行動・履歴/外見の全共通条件。 -- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。 +- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.route_action.observation_progress: uncredited precursor, not required behaviour (route progress from observation room)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -494,38 +564,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" }, { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", + "anchor_path": "scripts/relationship/relationship_service.gd", "lines": [ - 127, - 162 + 315, + 355 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -631,16 +723,16 @@ NTR阻止のための直接的解決手段。 - 種別: category - 識別: null -- 状態: partial +- 状態: missing - 所管: P00/P25/P26 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: no dedicated support established - AR: ["AR.asset.audio_adult", "AR.asset.character_voice", "AR.asset.dynamic_bgm", "AR.asset.environment_audio", "AR.asset.ui_audio", "AR.schedule.B-14.1.ai", "AR.schedule.B-14.1.assets", "AR.schedule.B-14.1.layers", "AR.schedule.B-14.1.mvp", "AR.schedule.B-14.2.bgm", "AR.schedule.B-14.2.parameters", "AR.schedule.B-14.2.portraits", "AR.schedule.B-14.2.scenario", "AR.schedule.B-14.2.tiles", "AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", "AR.schedule.B-14.3.observation", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record", "AR.schedule.B-14.4.debug", "AR.schedule.B-14.4.final", "AR.schedule.B-14.4.mastering", "AR.schedule.B-14.4.ui"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.schedule.B-14.3.observation"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.asset.audio_adult", "AR.asset.character_voice", "AR.asset.dynamic_bgm", "AR.asset.environment_audio", "AR.asset.ui_audio", "AR.schedule.B-14.1.ai", "AR.schedule.B-14.1.assets", "AR.schedule.B-14.1.layers", "AR.schedule.B-14.1.mvp", "AR.schedule.B-14.2.bgm", "AR.schedule.B-14.2.parameters", "AR.schedule.B-14.2.portraits", "AR.schedule.B-14.2.scenario", "AR.schedule.B-14.2.tiles", "AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record", "AR.schedule.B-14.4.debug", "AR.schedule.B-14.4.final", "AR.schedule.B-14.4.mastering", "AR.schedule.B-14.4.ui"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [] +- 基盤支援なしのAR: ["AR.asset.audio_adult", "AR.asset.character_voice", "AR.asset.dynamic_bgm", "AR.asset.environment_audio", "AR.asset.ui_audio", "AR.schedule.B-14.1.ai", "AR.schedule.B-14.1.assets", "AR.schedule.B-14.1.layers", "AR.schedule.B-14.1.mvp", "AR.schedule.B-14.2.bgm", "AR.schedule.B-14.2.parameters", "AR.schedule.B-14.2.portraits", "AR.schedule.B-14.2.scenario", "AR.schedule.B-14.2.tiles", "AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", "AR.schedule.B-14.3.observation", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record", "AR.schedule.B-14.4.debug", "AR.schedule.B-14.4.final", "AR.schedule.B-14.4.mastering", "AR.schedule.B-14.4.ui"] - 所管単位: ["P00", "P25", "P26"] (固定参照の原P単位定義を参照) - 条件: 原本のシナリオ/素材量産/音声制作と受入は未完。 -- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。 +- 理由: 欠損: 個別ID・必要量・完成内容は原本未定義。D08/D09未決。 AR.schedule.B-14.3.observation: uncredited precursor, not required behaviour (dedicated observation mode achievement)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 所有先は引用ARのprimary_packageと原P単位定義。包括P26-03への割当はしない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -662,32 +754,7 @@ NTR阻止のための直接的解決手段。 証拠(空配列は明示的欠損): ```json -[ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } -] +[] ``` ## route.anri.love @@ -697,9 +764,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.anri.route.love"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.anri.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.anri.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -774,14 +841,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -793,9 +906,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.anri.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.anri.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.anri.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -870,14 +983,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -889,9 +1048,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.anri.route.corruption"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.anri.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.anri.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -966,14 +1125,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -985,9 +1190,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.fine.route.love"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.fine.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.fine.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1062,14 +1267,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1081,9 +1332,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.fine.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.fine.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.fine.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1158,14 +1409,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1177,9 +1474,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.fine.route.corruption"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.fine.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.fine.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1254,14 +1551,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1273,9 +1616,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.tomari.route.love"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.tomari.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.tomari.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1350,14 +1693,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1369,9 +1758,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.tomari.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1446,14 +1835,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1465,9 +1900,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.tomari.route.corruption"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.tomari.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.tomari.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1542,14 +1977,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1561,9 +2042,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.amelia.route.love"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1638,14 +2119,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1657,9 +2184,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.amelia.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1734,14 +2261,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1753,9 +2326,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.amelia.route.corruption"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1830,14 +2403,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1849,9 +2468,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.liz.route.love"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.liz.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.liz.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -1926,14 +2545,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -1945,9 +2610,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.liz.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.liz.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.liz.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2022,14 +2687,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -2041,9 +2752,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.liz.route.corruption"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.liz.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.liz.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2118,14 +2829,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -2137,9 +2894,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.mimi.route.love"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.mimi.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.mimi.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2214,14 +2971,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -2233,9 +3036,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.mimi.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.mimi.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.mimi.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2310,14 +3113,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -2329,9 +3178,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.mimi.route.corruption"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.mimi.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.mimi.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2406,14 +3255,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -2425,9 +3320,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.satsuki.route.love"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.satsuki.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.satsuki.route.love"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2502,14 +3397,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -2521,9 +3462,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.satsuki.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.satsuki.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.satsuki.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2598,14 +3539,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -2617,9 +3604,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.satsuki.route.corruption"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.satsuki.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.satsuki.route.corruption"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 人物固有の入口・イベント列・分岐・終点・台詞・立ち絵・音声・履歴/保存と通常到達。 @@ -2694,14 +3681,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -52314,7 +53347,7 @@ NTR阻止のための直接的解決手段。 - 基盤支援なしのAR: ["AR.ui.observation_camera_entry"] - 所管単位: ["P24"] (固定参照の原P単位定義を参照) - 条件: Back-layer entry -- 理由: 欠損: 利用枠/用途群。既存表現の現物SHAを再取得。汎用描画/仮素材は固有人物・必須差分の完成証明ではない。D09数量/品質/担当未決。 +- 理由: 欠損: 利用枠/用途群。既存表現の現物SHAを再取得。汎用描画/仮素材は固有人物・必須差分の完成証明ではない。D09数量/品質/担当未決。 AR.ui.observation_camera_entry: uncredited precursor, not required behaviour (camera icon and dedicated observation screen transition)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -55933,9 +56966,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19/P20/P28 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.progression.all_endings", "AR.progression.encyclopedia_complete", "AR.progression.full_duration"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: ["AR.progression.all_endings", "AR.progression.encyclopedia_complete", "AR.progression.full_duration"] - 所管単位: ["P19", "P20", "P28"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 @@ -55958,14 +56991,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -56148,16 +57227,16 @@ NTR阻止のための直接的解決手段。 - 種別: original-clause - 識別: null -- 状態: partial +- 状態: missing - 所管: P16/P19 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: no dedicated support established - AR: ["AR.staff.back_routes", "AR.underground.blackmail", "AR.underground.trade_people"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.underground.blackmail"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.staff.back_routes", "AR.underground.trade_people"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [] +- 基盤支援なしのAR: ["AR.staff.back_routes", "AR.underground.blackmail", "AR.underground.trade_people"] - 所管単位: ["P16", "P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 -- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 +- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.underground.blackmail: uncredited precursor, not required behaviour (blackmail transaction state and income)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -56170,32 +57249,7 @@ NTR阻止のための直接的解決手段。 証拠(空配列は明示的欠損): ```json -[ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } -] +[] ``` ## original.line.22 @@ -56379,9 +57433,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P17/P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.amelia.identity", "AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.identity", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.identity", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.identity", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.identity", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.identity", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.identity", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: ["AR.heroine.amelia.identity", "AR.heroine.anri.identity", "AR.heroine.fine.identity", "AR.heroine.liz.identity", "AR.heroine.mimi.identity", "AR.heroine.satsuki.identity", "AR.heroine.tomari.identity"] - 所管単位: ["P17", "P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 @@ -56404,14 +57458,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -56423,9 +57523,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.narrative.route_tones"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: ["AR.narrative.route_tones"] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 @@ -56448,14 +57548,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -56467,13 +57613,13 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P16/P19 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content - AR: ["AR.underground.blackmail", "AR.underground.observation", "AR.underground.trade_people"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.underground.blackmail", "AR.underground.observation"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.underground.trade_people"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.underground.observation"], "content_status": "missing", "kind": "peeping-container", "scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content"}] +- 基盤支援なしのAR: ["AR.underground.blackmail", "AR.underground.trade_people"] - 所管単位: ["P16", "P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 -- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 +- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.underground.blackmail: uncredited precursor, not required behaviour (blackmail transaction state and income)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -56495,9 +57641,33 @@ NTR阻止のための直接的解決手段。 "anchor_path": "scripts/special/peeping_room_service.gd", "lines": [ 127, - 162 + 138 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," + "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 140, + 142 + ], + "text": "func record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 155, + 164 + ], + "text": "func controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id,\n\t\t\t&\"target_instance_id\": target_id, &\"source_event_key\": source_event_key, &\"minute\": minute}\n\treturn {&\"ok\": true, &\"reason\": &\"OK\", &\"evidence_id\": evidence_id, &\"duplicated\": duplicated}" }, { "path": "autoload/simulation_runtime.gd", @@ -56506,10 +57676,10 @@ NTR阻止のための直接的解決手段。 "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "autoload/simulation_runtime.gd", "lines": [ - 10860, - 10880 + 10863, + 10864 ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")" } ] ``` @@ -56695,9 +57865,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P19 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content - AR: ["AR.observation.alternate_view", "AR.observation.recorder"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.observation.recorder"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.observation.recorder"], "content_status": "missing", "kind": "peeping-container", "scope": "observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content"}] - 基盤支援なしのAR: ["AR.observation.alternate_view"] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 @@ -56723,9 +57893,33 @@ NTR阻止のための直接的解決手段。 "anchor_path": "scripts/special/peeping_room_service.gd", "lines": [ 127, - 162 + 138 ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," + "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 140, + 142 + ], + "text": "func record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")" + }, + { + "path": "scripts/special/peeping_room_service.gd", + "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", + "bytes": 15448, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/special/peeping_room_service.gd", + "lines": [ + 155, + 164 + ], + "text": "func controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id,\n\t\t\t&\"target_instance_id\": target_id, &\"source_event_key\": source_event_key, &\"minute\": minute}\n\treturn {&\"ok\": true, &\"reason\": &\"OK\", &\"evidence_id\": evidence_id, &\"duplicated\": duplicated}" }, { "path": "autoload/simulation_runtime.gd", @@ -56734,10 +57928,10 @@ NTR阻止のための直接的解決手段。 "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "autoload/simulation_runtime.gd", "lines": [ - 10860, - 10880 + 10863, + 10864 ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" + "text": "\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")" } ] ``` @@ -56749,13 +57943,13 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P04/P15/P19 - 内容状態: missing -- 部分支援範囲: night-dependent guest need input only; no event production or peak-frequency implementation +- 部分支援範囲: adult intimacy need selects intimacy_night or intimacy_day input key from is_night only; no peak values, NTR events or event production - AR: ["AR.events.ntr_night_peak", "AR.guest.need_sexual_night_peak", "AR.guest.night_sleep", "AR.guest.night_underground", "AR.time.night_phase"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.events.ntr_night_peak", "AR.guest.need_sexual_night_peak"], "content_status": "missing", "kind": "night-input", "scope": "night-dependent guest need input only; no event production or peak-frequency implementation"}] -- 基盤支援なしのAR: ["AR.guest.night_sleep", "AR.guest.night_underground", "AR.time.night_phase"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.guest.need_sexual_night_peak"], "content_status": "missing", "kind": "night-input", "scope": "adult intimacy need selects intimacy_night or intimacy_day input key from is_night only; no peak values, NTR events or event production"}] +- 基盤支援なしのAR: ["AR.events.ntr_night_peak", "AR.guest.night_sleep", "AR.guest.night_underground", "AR.time.night_phase"] - 所管単位: ["P04", "P15", "P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 -- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 +- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.events.ntr_night_peak: uncredited precursor, not required behaviour (NTR event night peak)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -56777,9 +57971,9 @@ NTR阻止のための直接的解決手段。 "anchor_path": "scripts/guest/guest_service.gd", "lines": [ 355, - 360 + 359 ], - "text": "\t\tif definition.adult_verified:\n\t\t\tvar intimacy_key := &\"intimacy_night\" \\\n\t\t\t\tif bool(_value(context, &\"is_night\", false)) \\\n\t\t\t\telse &\"intimacy_day\"\n\t\t\tdelta_intimacy += int(_value(context, intimacy_key, 0))\n\t\tvar raw_effects: Variant = _value(context, &\"need_effects\", {})" + "text": "\t\tif definition.adult_verified:\n\t\t\tvar intimacy_key := &\"intimacy_night\" \\\n\t\t\t\tif bool(_value(context, &\"is_night\", false)) \\\n\t\t\t\telse &\"intimacy_day\"\n\t\t\tdelta_intimacy += int(_value(context, intimacy_key, 0))" } ] ``` @@ -56849,9 +58043,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P20 - 内容状態: missing -- 部分支援範囲: bankruptcy terminal bookkeeping only; no authored ending +- 部分支援範囲: consecutive negative-net-profit counter reaches config bankruptcy_close_count and selects TERMINAL_BANKRUPT only; configured value 3 is not established; no authored game-over ending - AR: ["AR.progression.three_deficits_gameover"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.progression.three_deficits_gameover"], "content_status": "missing", "kind": "bankruptcy-bookkeeping", "scope": "bankruptcy terminal bookkeeping only; no authored ending"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.progression.three_deficits_gameover"], "content_status": "missing", "kind": "bankruptcy-bookkeeping", "scope": "consecutive negative-net-profit counter reaches config bankruptcy_close_count and selects TERMINAL_BANKRUPT only; configured value 3 is not established; no authored game-over ending"}] - 基盤支援なしのAR: [] - 所管単位: ["P20"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 @@ -56876,10 +58070,10 @@ NTR阻止のための直接的解決手段。 "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", "anchor_path": "scripts/operations/operations_coordinator.gd", "lines": [ - 1183, - 1195 + 1190, + 1194 ], - "text": "\tvar category_totals: Dictionary = result[&\"category_totals\"]\n\tvar net_profit := _net_profit(category_totals)\n\tvar previous_profit := net_profit\n\tif _day_summaries.has(completed_day - 1):\n\t\tprevious_profit = int((_day_summaries[completed_day - 1] as Dictionary)[&\"net_profit\"])\n\tvar rolling := _rolling_profit_with(net_profit)\n\tvar arrears := int((result[&\"settlement\"] as Dictionary)[&\"arrears_total\"])\n\tvar prior_streak := 0 if completed_day == _legacy_history_last_day + 1 else _consecutive_insolvency_count\n\tvar consecutive := prior_streak + 1 if net_profit < 0 else 0\n\tvar future_terminal := _terminal_state\n\tif consecutive >= int(_config[&\"bankruptcy_close_count\"]):\n\t\tfuture_terminal = TERMINAL_BANKRUPT\n\tvar reconciliation_difference := int(result[&\"reconciliation_difference\"])" + "text": "\tvar prior_streak := 0 if completed_day == _legacy_history_last_day + 1 else _consecutive_insolvency_count\n\tvar consecutive := prior_streak + 1 if net_profit < 0 else 0\n\tvar future_terminal := _terminal_state\n\tif consecutive >= int(_config[&\"bankruptcy_close_count\"]):\n\t\tfuture_terminal = TERMINAL_BANKRUPT" } ] ``` @@ -57558,9 +58752,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P18/P19 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.relationship.three_emotions"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.relationship.three_emotions"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.heroine.amelia.route.corruption", "AR.heroine.amelia.route.love", "AR.heroine.amelia.route.ntr", "AR.heroine.anri.route.corruption", "AR.heroine.anri.route.love", "AR.heroine.anri.route.ntr", "AR.heroine.fine.route.corruption", "AR.heroine.fine.route.love", "AR.heroine.fine.route.ntr", "AR.heroine.liz.route.corruption", "AR.heroine.liz.route.love", "AR.heroine.liz.route.ntr", "AR.heroine.mimi.route.corruption", "AR.heroine.mimi.route.love", "AR.heroine.mimi.route.ntr", "AR.heroine.satsuki.route.corruption", "AR.heroine.satsuki.route.love", "AR.heroine.satsuki.route.ntr", "AR.heroine.tomari.route.corruption", "AR.heroine.tomari.route.love", "AR.heroine.tomari.route.ntr", "AR.relationship.three_emotions"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P18", "P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 @@ -57583,14 +58777,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -57602,9 +58842,9 @@ NTR阻止のための直接的解決手段。 - 状態: partial - 所管: P18 - 内容状態: missing -- 部分支援範囲: shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion +- 部分支援範囲: affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content - AR: ["AR.relationship.affection_shield_max"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.relationship.affection_shield_max"], "content_status": "missing", "kind": "relationship-container", "scope": "shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion"}] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.relationship.affection_shield_max"], "content_status": "missing", "kind": "relationship-container", "scope": "affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content"}] - 基盤支援なしのAR: [] - 所管単位: ["P18"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 @@ -57627,14 +58867,60 @@ NTR阻止のための直接的解決手段。 "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", "bytes": 1571, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/original_relationship_state.gd" + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 6, + 6 + ], + "text": "const FIELDS := [\"subject_id\", \"protagonist_id\", \"rival_id\", \"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 21, + 25 + ], + "text": "\tfor field: String in [\"affection\", \"lust\", \"netorare\", \"shield_current\", \"shield_max\"]:\n\t\tif not (value[field] is int or value[field] is float):\n\t\t\treturn null\n\t\tif value[field] is float and not is_finite(value[field]):\n\t\t\treturn null" + }, + { + "path": "scripts/relationship/original_relationship_state.gd", + "sha256": "d1bfabfd205becf6d3cf1d6b6c477393319b26b0e7504fd227c3714761101616", + "bytes": 1571, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/original_relationship_state.gd", + "lines": [ + 26, + 26 + ], + "text": "\tif value[\"shield_max\"] != value[\"affection\"] or value[\"shield_current\"] < 0 or value[\"shield_current\"] > value[\"shield_max\"]:" }, { "path": "scripts/relationship/relationship_service.gd", "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", "bytes": 27526, "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/relationship/relationship_service.gd" + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 38, + 58 + ], + "text": "func register_original_relationship(payload: Variant) -> CommandResult:\n\tvar state := OriginalStateType.from_snapshot(payload)\n\tif state == null:\n\t\treturn _invalid(\"Original relationship requires complete explicit facts.\")\n\tif not _original_identity_validator.is_valid() or not bool(_original_identity_validator.call(state.create_snapshot())):\n\t\treturn _invalid(\"Original relationship identities are not registered.\")\n\tif _original_records.has(state.subject_id()):\n\t\treturn _duplicate(\"Original relationship subject\", state.subject_id())\n\t_original_records[state.subject_id()] = state.create_snapshot()\n\tlast_error = \"\"\n\treturn _success({&\"subject_id\": state.subject_id()})\n\n\nfunc get_original_relationship(subject_id: StringName) -> Dictionary:\n\tif _original_records.has(subject_id):\n\t\tvar result: Dictionary = _original_records[subject_id].duplicate(true)\n\t\tresult[&\"configured\"] = true\n\t\treturn result\n\treturn {&\"configured\": false, &\"subject_id\": subject_id,\n\t\t&\"protagonist_id\": null, &\"rival_id\": null, &\"affection\": null,\n\t\t&\"lust\": null, &\"netorare\": null, &\"shield_current\": null, &\"shield_max\": null}" + }, + { + "path": "scripts/relationship/relationship_service.gd", + "sha256": "d2f6304aa643b98914c5d65bf3eb673ca8cc427476187f43e76b4b941410b1d3", + "bytes": 27526, + "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", + "anchor_path": "scripts/relationship/relationship_service.gd", + "lines": [ + 315, + 355 + ], + "text": "func request_route_lock(\n\trelationship_id: StringName,\n\trequested_lock: RelationshipState.RouteLock,\n\troute_id: StringName = &\"\",\n\tirreversible_event: bool = false\n) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif requested_lock < RelationshipStateType.RouteLock.NONE or requested_lock > RelationshipStateType.RouteLock.CLOSED:\n\t\treturn _invalid(\"Unknown Route Lock state.\")\n\tif requested_lock in [\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_PENDING,\n\t\tRelationshipStateType.RouteLock.EXCLUSIVE_LOCKED,\n\t] and route_id.is_empty():\n\t\treturn _invalid(\"Exclusive Route Lock requires a route ID.\")\n\tif requested_lock == RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED and not irreversible_event:\n\t\treturn _invalid(\"Exclusive Route cannot lock before explicit confirmation.\", {\n\t\t\t&\"required_state\": &\"EXCLUSIVE_PENDING\",\n\t\t})\n\tvar old_lock := state.route_lock\n\tstate.route_lock = requested_lock\n\tstate.route_id = route_id if requested_lock != RelationshipStateType.RouteLock.NONE else &\"\"\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"old_lock\": old_lock, &\"new_lock\": state.route_lock})\n\n\nfunc confirm_route_lock(relationship_id: StringName, route_id: StringName) -> CommandResult:\n\tvar state := get_relationship(relationship_id)\n\tif state == null:\n\t\treturn _not_found(\"Relationship\", relationship_id)\n\tif state.route_lock != RelationshipStateType.RouteLock.EXCLUSIVE_PENDING:\n\t\treturn _invalid(\"Route is not awaiting exclusive confirmation.\")\n\tif route_id.is_empty() or state.route_id != route_id:\n\t\treturn _invalid(\"Route confirmation does not match the pending route.\")\n\tvar old_lock := state.route_lock\n\tstate.route_lock = RelationshipStateType.RouteLock.EXCLUSIVE_LOCKED\n\troute_lock_changed.emit(relationship_id, old_lock, state.route_lock, state.route_id)\n\tlast_error = \"\"\n\treturn _success({&\"route_id\": route_id, &\"new_lock\": state.route_lock})" } ] ``` @@ -57991,16 +59277,16 @@ NTR阻止のための直接的解決手段。 - 種別: original-clause - 識別: null -- 状態: partial +- 状態: missing - 所管: P19 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: no dedicated support established - AR: ["AR.route_action.neglect_weakens", "AR.route_action.observation_progress", "AR.route_action.underground_weakens"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.route_action.observation_progress"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.route_action.neglect_weakens", "AR.route_action.underground_weakens"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [] +- 基盤支援なしのAR: ["AR.route_action.neglect_weakens", "AR.route_action.observation_progress", "AR.route_action.underground_weakens"] - 所管単位: ["P19"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 -- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 +- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.route_action.observation_progress: uncredited precursor, not required behaviour (route progress from observation room)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -58013,32 +59299,7 @@ NTR阻止のための直接的解決手段。 証拠(空配列は明示的欠損): ```json -[ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } -] +[] ``` ## original.line.157 @@ -58654,16 +59915,16 @@ NTR阻止のための直接的解決手段。 - 種別: original-clause - 識別: null -- 状態: partial +- 状態: missing - 所管: P24 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: no dedicated support established - AR: ["AR.ui.observation_camera_entry"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.ui.observation_camera_entry"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: [] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [] +- 基盤支援なしのAR: ["AR.ui.observation_camera_entry"] - 所管単位: ["P24"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 -- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 +- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.ui.observation_camera_entry: uncredited precursor, not required behaviour (camera icon and dedicated observation screen transition)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -58676,48 +59937,23 @@ NTR阻止のための直接的解決手段。 証拠(空配列は明示的欠損): ```json -[ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } -] +[] ``` ## original.line.222 - 種別: original-clause - 識別: null -- 状態: partial +- 状態: missing - 所管: P24 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: no dedicated support established - AR: ["AR.ui.observation_angle", "AR.ui.observation_capture", "AR.ui.observation_intervention"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.ui.observation_capture"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.ui.observation_angle", "AR.ui.observation_intervention"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [] +- 基盤支援なしのAR: ["AR.ui.observation_angle", "AR.ui.observation_capture", "AR.ui.observation_intervention"] - 所管単位: ["P24"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 -- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 +- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.ui.observation_capture: uncredited precursor, not required behaviour (screenshot evidence collection)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -58730,32 +59966,7 @@ NTR阻止のための直接的解決手段。 証拠(空配列は明示的欠損): ```json -[ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } -] +[] ``` ## original.line.225 @@ -59313,16 +60524,16 @@ NTR阻止のための直接的解決手段。 - 種別: original-clause - 識別: null -- 状態: partial +- 状態: missing - 所管: P00 - 内容状態: missing -- 部分支援範囲: stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content +- 部分支援範囲: no dedicated support established - AR: ["AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", "AR.schedule.B-14.3.observation", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record"] -- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [{"atomic_requirement_ids": ["AR.schedule.B-14.3.observation"], "content_status": "missing", "kind": "peeping-container", "scope": "stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content"}] -- 基盤支援なしのAR: ["AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record"] +- AR別部分支援(列挙ARの基盤断片のみ、制作内容はmissing): [] +- 基盤支援なしのAR: ["AR.schedule.B-14.3.adult", "AR.schedule.B-14.3.balance", "AR.schedule.B-14.3.observation", "AR.schedule.B-14.3.voice_integrate", "AR.schedule.B-14.3.voice_record"] - 所管単位: ["P00"] (固定参照の原P単位定義を参照) - 条件: 原本の必要条件。個別の脚本/台詞/CG/音声/場面数は定義しない。 -- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 scoped_supportに列挙したARの基盤断片のみpartial。他のARは未支援、全制作内容は欠損。 +- 理由: 原本条件を保存。専用制作内容は欠損、場面ID・数量は未定義。下記AR所有先で残作業を追跡。 AR.schedule.B-14.3.observation: uncredited precursor, not required behaviour (dedicated observation mode achievement)。関連基盤コードは存在するが当該ARの証拠には帰属させない。 - 必要数/完成数: 未定義 / 未計数 - 欠損: original production content missing or undefined @@ -59335,32 +60546,7 @@ NTR阻止のための直接的解決手段。 証拠(空配列は明示的欠損): ```json -[ - { - "path": "scripts/special/peeping_room_service.gd", - "sha256": "4dc02bc99f081d63a2518f69c960397d778d577b93d87d57bcac29bc6f108531", - "bytes": 15448, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "scripts/special/peeping_room_service.gd", - "lines": [ - 127, - 162 - ], - "text": "\tif not _rooms.has(room_id): return result(&\"ROOM_MISSING\")\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\t# Required precedence: stopped, power, closed, construction, lost target.\n\tif room[&\"stopped\"]: return result(&\"STOPPED\")\n\tvar target := _facilities.get_instance(room[&\"target_instance_id\"])\n\tif target != null:\n\t\tif not target.power_available: return result(&\"NO_POWER\")\n\t\tif not target.operator_open or not target.is_within_opening_hours(minute): return result(&\"CLOSED\")\n\t\tif _construction.get_facility(target.instance_id).is_empty(): return result(&\"UNDER_CONSTRUCTION\")\n\tif room[&\"link_state\"] == &\"TARGET_LOST\" or target == null: return result(&\"TARGET_LOST\")\n\treturn result()\n\nfunc record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\treturn report if not report[&\"ok\"] else result(&\"RECORDER_ELIGIBILITY_PENDING_D04_D08_P16\")\n\n## CONTROLLED_FIXTURE: explicit test state, never a production resume command.\nfunc controlled_fixture_set_stopped(room_id: StringName, stopped: bool) -> bool:\n\tif not _rooms.has(room_id): return false\n\tdetect_target_loss()\n\tvar room: Dictionary = _rooms[room_id]\n\tif not stopped and room[&\"link_state\"] == &\"TARGET_LOST\": return false\n\troom[&\"stopped\"] = stopped\n\troom[&\"stop_reason\"] = &\"CONTROLLED_FIXTURE\" if stopped else &\"\"\n\treturn true\n\n## CONTROLLED_FIXTURE: sole ledger write entry point, opaque event keys only.\nfunc controlled_fixture_record_evidence(room_id: StringName, source_event_key: StringName, minute: int) -> Dictionary:\n\tvar report := _collection_precondition(room_id, source_event_key, minute)\n\tif not report[&\"ok\"]: return report\n\tvar target_id: StringName = _rooms[room_id][&\"target_instance_id\"]\n\tvar evidence_id := _evidence_id(room_id, target_id, source_event_key)\n\tvar duplicated := _evidence.has(evidence_id)\n\tif not duplicated:\n\t\t_evidence[evidence_id] = {&\"evidence_id\": evidence_id, &\"room_id\": room_id," - }, - { - "path": "autoload/simulation_runtime.gd", - "sha256": "45514aea9367ff678f4dc05166bb9b58121f240d4b5565edeb7ab258e3ded8e0", - "bytes": 616434, - "anchor": "f4f85bc54c39361f9efcd16f67a17835559ca70c", - "anchor_path": "autoload/simulation_runtime.gd", - "lines": [ - 10860, - 10880 - ], - "text": "func _execute_peeping_room(command: SimulationCommand) -> CommandResult:\n\tvar payload := command.payload\n\tvar report: Dictionary\n\tif command.command_type == &\"peeping_room_place\":\n\t\treport = PeepingRooms.result(&\"BUILD_DEFINITION_PENDING_D04\")\n\telif command.command_type == &\"peeping_room_validate\":\n\t\tif typeof(payload.get(&\"origin\")) != TYPE_VECTOR3I or typeof(payload.get(&\"footprint\", Vector2i(2, 1))) != TYPE_VECTOR2I or typeof(payload.get(&\"target_instance_id\", &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telse:\n\t\t\treport = peeping_room_service.validate_placement(payload[&\"origin\"], payload.get(&\"footprint\", Vector2i(2, 1)), StringName(payload.get(&\"target_instance_id\", &\"\")))\n\telse:\n\t\tvar key: StringName = &\"target_instance_id\" if command.command_type == &\"peeping_room_relink\" else &\"source_event_key\"\n\t\tif typeof(payload.get(&\"room_id\")) not in [TYPE_STRING, TYPE_STRING_NAME] or typeof(payload.get(key, &\"\")) not in [TYPE_STRING, TYPE_STRING_NAME]:\n\t\t\treport = PeepingRooms.result(&\"INVALID_PAYLOAD\")\n\t\telif command.command_type == &\"peeping_room_relink\":\n\t\t\treport = peeping_room_service.relink(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")))\n\t\telse:\n\t\t\treport = peeping_room_service.record_evidence(StringName(payload[&\"room_id\"]), StringName(payload.get(key, &\"\")), _runtime_event_minute())\n\tif report[&\"ok\"]:\n\t\treturn CommandResult.succeeded(command.command_id, report)\n\treturn CommandResult.failed(CommandResult.Code.VALIDATION_FAILED, command.command_id, String(report[&\"reason\"]), report)" - } -] +[] ``` ## original.line.258 diff --git a/docs/plans/original-completion-2026-10-02/execution/p26-01/IMPLEMENTATION_REPORT.md b/docs/plans/original-completion-2026-10-02/execution/p26-01/IMPLEMENTATION_REPORT.md index aaf18f2..22d8972 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p26-01/IMPLEMENTATION_REPORT.md +++ b/docs/plans/original-completion-2026-10-02/execution/p26-01/IMPLEMENTATION_REPORT.md @@ -12,13 +12,17 @@ build/owner-handoff/p26-repair3/ の ACTUAL_WHOLE_REVIEW.json、ACTUAL_OPUS_REPA 現在の実承認は a13f7c0b791dd385ff8113c3d321c0e3fe7d7c94 の docs/plans/original-completion-2026-10-02/execution/p04-01-owner-approval-20261018/D05_ACTUAL_HUMAN_APPROVAL.json、SHA256 cd365ded1b777a0327d090709f0a4161f5005562819183455d9f2e106fba3e96。チェッカーはこのgit objectのhashを照合し、4回答の原レコードを台帳に保存する。質問IDは call_5fa8987f83284eb58b685002499cb9df。破壊/完了、日付境界、停止理由、退出順序の承認であり、P04への製品採用・内容完成・P26受入ではない。D08/D09は未解決。 -## 修復5: 証拠のAR別帰属 +## 修復6: 直接読解マップによる証拠のAR別帰属 -今回の変更前に build/owner-handoff/p26-support-attribution-repair/ACTUAL_OPUS_ASTRA_ATTRIBUTION_DIRECTION.json と ACTUAL_WHOLE_REVIEW_DA80360A.json を全文読了し、D05の上記4資料も再確認した。修復5は証拠帰属に限定する。 +今回の変更前に build/owner-handoff/p26-direct-support-r06/ の ACTUAL_OPUS_DIRECT_SOURCE_MAP.json、ACTUAL_WHOLE_REVIEW_F10907D8.json、DIRECT_POLICY_AUTHORITY_SNAPSHOT.json を全フィールド・全ソース本文まで読了した。確定済みの直接読解マップを転記し、証拠帰属だけを修復する。モデル指定はgpt-6.1-solのまま。新しい意味判断・仕様・承認は加えない。 -結合した引用文のキーワードからpartialを付ける処理を削除した。SUPPORT_POLICYは証拠種別→許容ARの閉じた対応表である。関係状態は21ルートと感情3軸/盾最大値の明示状態・保存だけ、覗きは記録係/観察/証拠収集に関する列挙ARの停止中コンテナだけ、夜間は2 ARの欲求入力だけ、赤字は終端計算ARだけを支援する。人物のidentity/技能や任意のrelationship/route_action全域へは拡張しない。視点・角度・介入そのものを支援する証拠とはしない。 +SUPPORT_POLICYの4種をマップの許容リストに限定する。relationship-containerは21人物ルートARとAR.relationship.three_emotions / affection_shield_max、peeping-containerはAR.underground.observation / AR.observation.recorder、night-inputはAR.guest.need_sexual_night_peak、bankruptcy-bookkeepingはAR.progression.three_deficits_gameoverだけ。以前のキーワードpartial処理の廃止、voice修復、全先行修復は保持する。 -各行のscoped_supportは対象AR・証拠種別・限定範囲・content_status=missingを明記する。unsupported_atomic_requirement_idsはその行で基盤支援がない残りのARを列挙する(用途行の既存placeholder/code-drawingは従来どおり別記)。L9は21ルートのコンテナだけpartialで、全エンド/図鑑/所要時間は未支援。L257とclause.productionは観察工程のコンテナだけpartialで、ボイス収録/実装を含む他ARは未支援。voice.all、endings全3行、encyclopedia.allはmissing、証拠なし。声に関するどのARも対応表に入れない。行数・AR対応・引用・制作数量は増減させない。 +各行のscoped_supportは対象AR・証拠種別・限定範囲・content_status=missingを明記する。unsupported_atomic_requirement_idsはその行で基盤支援がない残りのARを列挙する(用途行の既存placeholder/code-drawingは従来どおり別記)。L9は21ルートのコンテナだけpartialで、全エンド/図鑑/所要時間は未支援。L21 / L156 / L221 / L222 / L257とclause.productionは支援が空になるためmissing、evidence=[]。L34は観察状態、L53は記録フィールド、L65は客欲求入力、L72は赤字終端計算だけpartialを保持する。voice.all、endings全3行、encyclopedia.allはmissing、証拠なし。声に関するどのARも対応表に入れない。行数・AR対応・引用・制作数量は増減させない。 + +独立したEXCLUDED_ATTRIBUTIONS表で、AR.ui.observation_camera_entry(カメラアイコン/専用画面遷移)、AR.ui.observation_capture(スクリーンショット)、AR.underground.blackmail(取引状態/収支)、AR.route_action.observation_progress(観察部屋のルート進行確認)、AR.schedule.B-14.3.observation(専用観察モード達成)、AR.events.ntr_night_peak(NTRイベント夜ピーク)を拒否する。関連コードは uncredited precursor, not required behaviour と理由文に記す。コードの不存在は主張せず、これらARに証拠pinを帰属させない。SUPPORT_POLICYへの再追加も、行のscoped_support主張も独立層で拒否する。6個の個別負例は双方を注入し、許容ARの正例と復旧後の正例を伴う。破損ポリシーで再生成した台帳も拒否する。 + +chapters.all / dialogue.allはstatus=undefinedを保持し、制作内容は欠損、undefinedは範囲・数量のみと理由文で明示する。owner精度の追加判断は引き続きdeferred。 verify_authorityはexpectedやcanonicalを呼ばず、提出された各claimのARと行の種類、固定出典・抜粋全文、支援/未支援ARの分割、状態と範囲文を検査する。有効なSHAでも無関係な証拠、無根拠なpartial、声への同一引用行の観察証拠の流用は拒否する。負例はmissingの音声/立ち絵/エンド/図鑑への証拠注入、混合行内の支援AR拡張、正しい夜間支援への無関係な証拠追加を含む。route、L65、L53の実際のpartialを正例にする。既存負例は維持し、AR削除負例だけ新しい分割フィールドも整合して削除する。 @@ -44,11 +48,11 @@ verify_authorityはexpectedやcanonicalを呼ばず、提出された各claimの ## 現物の部分支援と欠損 -scripts/relationship/original_relationship_state.gd の明示値検証と relationship_service.gd の保存コンテナを直接参照する。route行と対応する原文行はpartialであり、content_status=missingを別記する。更新・攻撃・閾値・固有物語を実装済みとはしない。 +scripts/relationship/original_relationship_state.gd:6、21–25、26でaffection/lust/netorareと有限値検証、shield_max==affection / 0<=shield_current<=shield_maxを引用する。relationship_service.gd:38–58はsubject_idキーの原本記録登録、315–355は別の汎用route_lock/route_id記録だけ。元ルートID・自然到達・内容はない。whole-file pinをこの抜粋へ狭める。21 route行はpartial、content_status=missingを保持し、更新・攻撃・閾値・固有物語を実装済みとはしない。 -scripts/special/peeping_room_service.gd:127–162 と autoload/simulation_runtime.gd:10860–10880 を直接引用する。停止・対象参照・証拠キーの基盤はあるが、製品配置はBUILD_DEFINITION_PENDING_D04、記録はRECORDER_ELIGIBILITY_PENDING_D04_D08_P16で止まる。閉じた対応表にあるARのscoped_supportだけがこの基盤を指し、視界、専用画面、スクリーンショット、介入や制作イベントを証明しない。L13の自律観察/介入、L53の専用視点、L222の角度/介入にはこの証拠を帰属させない。 +scripts/special/peeping_room_service.gd:127–138はstopped/link_state/targetと前提優先順、140–142は製品記録のRECORDER_ELIGIBILITY_PENDING_D04_D08_P16、155–164はfixture専用書込みのevidence_id/room_id/target_instance_id/source_event_key/minuteを引用する。autoload/simulation_runtime.gd:10863–10864は配置のBUILD_DEFINITION_PENDING_D04だけ。通常入口・記録係配置は欠損。視界、専用画面、スクリーンショット、ルート確認、取引、介入や制作イベントへ帰属させない。 -scripts/guest/guest_service.gd:355–360 は夜間の欲求入力の切替のみ。L65のNTRイベント内容の制作証拠ではない。scripts/operations/operations_coordinator.gd:1183–1195 の赤字連続による終端計算は存在するが、完成シナリオ/画像/声ではない。L196の専用代物弁済イベントは現物制作証拠なしとしてmissing。数量/シーン列はundefinedのまま。 +scripts/guest/guest_service.gd:355–359はadult intimacy needのis_nightによるintimacy_night/intimacy_day入力選択だけ。ピーク値・NTRイベントの制作証拠はない。scripts/operations/operations_coordinator.gd:1190–1194は負のnet_profit連続カウンタがconfig bankruptcy_close_countに達するとTERMINAL_BANKRUPTを選ぶ処理だけ。設定値が3だとは主張せず、著作されたゲームオーバー内容は欠損。L196の専用代物弁済イベントは現物制作証拠なしとしてmissing。数量/シーン列はundefinedのまま。 P19/P22の旧状態をそのまま合否にしない。P19の正確な21セルと自然到達未完成の事実を版固定し、現在の関係ソースも独立参照する。P22全614用途レコードと全296mediaを保存し、表現先の現物SHAを監査アンカーへ再結合する。表現型からcode-drawing / placeholder / missingを区別し、歴史的inventoryのSHAと現在アンカーのSHAを別々に保持する。全assetsのパス/SHAも保存する。P22-03はdraft/unaccepted reference only。 @@ -64,7 +68,7 @@ authorities()は提出行や旧監査の合否を使わず、BASELINE本文の このworkerはJSON/Markdownの生成処理と読取による実装確認だけを行った。p26-ledger / p26-negative / p26-source-binding、--check、--source-binding-only、unittestは実行していない。PASSは主張しない。正式試験はRunnerが契約の3コマンドを実行する。 -修復5の生成後の読取比較では762行、1309 AR処置、675関連ARを保持し、全行のID・引用・ARリンクは開始時と同一。全required_count/completed_countはnull。JSONの変更した最上位領域はrowsとatomic_dispositionsのみで、D05の4回答を含む他の領域は同一。JSONとMDはexpected/markdownによる決定的生成であり、試験実行結果ではない。生成後に変更したcheckerの独立検証と負例はRunnerでの実行待ち。 +修復6の生成後の読取比較では762行、1309 AR処置、675関連ARを保持し、全行のID・引用・ARリンクは開始時と同一。全required_count/completed_countはnull。JSONの変更した最上位領域はrowsのみで、D05の4回答、atomic_dispositions、source pinsを含む他領域は同一。JSONとMDはexpected/markdownによる決定的生成であり、試験実行結果ではない。生成後に変更したcheckerの独立検証と負例はRunnerでの実行待ち。今回の実装担当指示「試験はRunnerが正式実行します」に従い、登録済み3チェックはworker未実行、結果は未取得。 ## 新Sと受入の残ゲート diff --git a/docs/plans/original-completion-2026-10-02/execution/p26-01/check_content_ledger.py b/docs/plans/original-completion-2026-10-02/execution/p26-01/check_content_ledger.py index dce2aa4..6614e37 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p26-01/check_content_ledger.py +++ b/docs/plans/original-completion-2026-10-02/execution/p26-01/check_content_ledger.py @@ -42,25 +42,38 @@ SUPPORT_POLICY = { 'ars': frozenset({'AR.relationship.three_emotions', 'AR.relationship.affection_shield_max'} | {'AR.heroine.' + p + '.route.' + r for p, _ in PEOPLE for r in ROUTES}), - 'sources': [('scripts/relationship/original_relationship_state.gd', None), - ('scripts/relationship/relationship_service.gd', None)], - 'scope': 'shared explicit relationship state/validation/save container only; no updates, attacks, thresholds, authored content or natural route completion'}, + 'sources': [('scripts/relationship/original_relationship_state.gd', (6, 6)), + ('scripts/relationship/original_relationship_state.gd', (21, 25)), + ('scripts/relationship/original_relationship_state.gd', (26, 26)), + ('scripts/relationship/relationship_service.gd', (38, 58)), + ('scripts/relationship/relationship_service.gd', (315, 355))], + 'scope': 'affection/lust/netorare fields and finite-number validation; shield_max==affection and 0<=shield_current<=shield_max invariant; subject_id-keyed original record registration; separate generic route_lock/route_id record only, with no original route IDs, natural reach or content'}, 'peeping-container': { - 'ars': frozenset({'AR.observation.recorder', 'AR.underground.observation', - 'AR.underground.blackmail', 'AR.route_action.observation_progress', - 'AR.ui.observation_camera_entry', 'AR.ui.observation_capture', - 'AR.schedule.B-14.3.observation'}), - 'sources': [('scripts/special/peeping_room_service.gd', (127, 162)), - ('autoload/simulation_runtime.gd', (10860, 10880))], - 'scope': 'stopped room/target reference and fixture evidence-key container only; production placement/recorder eligibility pending; no view, camera UI, screenshot, intervention, transaction or authored content'}, + 'ars': frozenset({'AR.observation.recorder', 'AR.underground.observation'}), + 'sources': [('scripts/special/peeping_room_service.gd', (127, 138)), + ('scripts/special/peeping_room_service.gd', (140, 142)), + ('scripts/special/peeping_room_service.gd', (155, 164)), + ('autoload/simulation_runtime.gd', (10863, 10864))], + 'scope': 'observation state half only: stopped/link_state/target and precondition precedence; recorder ledger fields evidence_id/room_id/target_instance_id/source_event_key/minute with fixture-only writes; production record_evidence returns RECORDER_ELIGIBILITY_PENDING_D04_D08_P16, placement returns BUILD_DEFINITION_PENDING_D04; no normal entry, recorder placement, view, camera UI, screenshot, route progress, dedicated mode, intervention, transaction or authored content'}, 'night-input': { - 'ars': frozenset({'AR.events.ntr_night_peak', 'AR.guest.need_sexual_night_peak'}), - 'sources': [('scripts/guest/guest_service.gd', (355, 360))], - 'scope': 'night-dependent guest need input only; no event production or peak-frequency implementation'}, + 'ars': frozenset({'AR.guest.need_sexual_night_peak'}), + 'sources': [('scripts/guest/guest_service.gd', (355, 359))], + 'scope': 'adult intimacy need selects intimacy_night or intimacy_day input key from is_night only; no peak values, NTR events or event production'}, 'bankruptcy-bookkeeping': { 'ars': frozenset({'AR.progression.three_deficits_gameover'}), - 'sources': [('scripts/operations/operations_coordinator.gd', (1183, 1195))], - 'scope': 'bankruptcy terminal bookkeeping only; no authored ending'}, + 'sources': [('scripts/operations/operations_coordinator.gd', (1190, 1194))], + 'scope': 'consecutive negative-net-profit counter reaches config bankruptcy_close_count and selects TERMINAL_BANKRUPT only; configured value 3 is not established; no authored game-over ending'}, +} + +# Independent exclusions from the direct source-read map. Never derive these +# from SUPPORT_POLICY: a policy re-add must itself be rejected. +EXCLUDED_ATTRIBUTIONS = { + 'AR.ui.observation_camera_entry': 'camera icon and dedicated observation screen transition', + 'AR.ui.observation_capture': 'screenshot evidence collection', + 'AR.underground.blackmail': 'blackmail transaction state and income', + 'AR.route_action.observation_progress': 'route progress from observation room', + 'AR.schedule.B-14.3.observation': 'dedicated observation mode achievement', + 'AR.events.ntr_night_peak': 'NTR event night peak', } @@ -262,7 +275,8 @@ def expected(root): 'evidence': evidence or [], 'missing': 'original production content missing or undefined', 'reason': reason, 'owner': owner}) add('chapters.all', 'chapter', [(8,), (26,), (27,30), (256,)], - 'メインストーリー全章。原本の仕様書章番号をシナリオ章と混同しない。章名・章数・順序・場面一覧は未定義。', 'D08') + 'メインストーリー全章。原本の仕様書章番号をシナリオ章と混同しない。章名・章数・順序・場面一覧は未定義。', 'D08', + reason='欠損: 制作内容は欠損。undefinedは章の範囲・数量のみを指す。章名・順序・場面一覧は原本未定義、D08未決。') add('endings.all', 'ending', [(9,), (135,)], '全エンドを要求。個別エンドID・本数・到達条件は未定義。', 'D08', 'missing') add('endings.bad', 'ending', [(135,)], @@ -274,7 +288,8 @@ def expected(root): add('encyclopedia.all', 'encyclopedia', [(9,)], '図鑑コンプ。対象集合・項目ID・解放条件・必要項目数は未定義。', 'D08', 'missing') add('dialogue.all', 'dialogue', [(155,), (230,), (256,)], - '会話/イベント用台詞とシナリオ。本文・話者・行数・場面単位は未定義。UI通知文を完成脚本に数えない。', 'P26-02') + '会話/イベント用台詞とシナリオ。本文・話者・行数・場面単位は未定義。UI通知文を完成脚本に数えない。', 'P26-02', + reason='欠損: 制作内容は欠損。undefinedは台詞の範囲・数量のみを指す。本文・話者・場面単位は原本未定義、D08未決。') add('portraits.all', 'portrait', [(160,161), (230,), (235,), (242,)], 'メイン/サブ人物の表情・衣装・破損・汚れ・刻印・妊婦外見・ルート別描き分け。差分枚数未定義。', 'P26-03', 'missing') add('voice.all', 'voice', [(252,), (257,)], @@ -382,6 +397,10 @@ def expected(root): row['evidence'] += support_pins(root, kind) supported_ids = {a for claim in row['scoped_support'] for a in claim['atomic_requirement_ids']} row['unsupported_atomic_requirement_ids'] = sorted(set(matches) - supported_ids) + excluded = sorted(set(matches) & EXCLUDED_ATTRIBUTIONS.keys()) + if excluded: + row['reason'] += ' ' + '; '.join(a + ': uncredited precursor, not required behaviour (' + + EXCLUDED_ATTRIBUTIONS[a] + ')' for a in excluded) + '。関連基盤コードは存在するが当該ARの証拠には帰属させない。' if row['scoped_support']: row['status'] = 'partial' row['support_scope'] = '; '.join(c['scope'] for c in row['scoped_support']) @@ -434,6 +453,9 @@ def expected(root): def verify_authority(candidate, root): """Non-canonical coverage/ownership/citation checks, callable on their own.""" + for policy in SUPPORT_POLICY.values(): + require(not (set(policy['ars']) & EXCLUDED_ATTRIBUTIONS.keys()), + 'excluded attribution in SUPPORT_POLICY') lines, required, atoms, relevant, packages = authorities(root) seen_lines, seen_atoms = set(), set() row_ids = {r['id'] for r in candidate['rows']} @@ -477,6 +499,8 @@ def verify_authority(candidate, root): policy = SUPPORT_POLICY[kind] require(support_family(row), 'support incompatible with requirement family') targets = claim['atomic_requirement_ids'] + require(not (set(targets) & EXCLUDED_ATTRIBUTIONS.keys()), + 'excluded attribution in row claim') require(type(targets) is list and targets and len(targets) == len(set(targets)) and set(targets) <= set(ids) & policy['ars'], 'support incompatible with AR') require(claim['scope'] == policy['scope'] and claim['content_status'] == 'missing', diff --git a/docs/plans/original-completion-2026-10-02/execution/p26-01/test_content_ledger.py b/docs/plans/original-completion-2026-10-02/execution/p26-01/test_content_ledger.py index f606827..04220b4 100644 --- a/docs/plans/original-completion-2026-10-02/execution/p26-01/test_content_ledger.py +++ b/docs/plans/original-completion-2026-10-02/execution/p26-01/test_content_ledger.py @@ -182,12 +182,23 @@ class LedgerTests(unittest.TestCase): rows = {r['id']: r for r in self.submitted['rows']} audit.verify_authority(self.submitted, ROOT) for identity, kind in [('route.anri.love', 'relationship-container'), + ('original.line.138', 'relationship-container'), + ('original.line.140', 'relationship-container'), ('original.line.65', 'night-input'), - ('original.line.53', 'peeping-container')]: + ('original.line.53', 'peeping-container'), + ('original.line.34', 'peeping-container'), + ('original.line.72', 'bankruptcy-bookkeeping')]: with self.subTest(control=identity): self.assertEqual(rows[identity]['status'], 'partial') self.assertEqual(rows[identity]['content_status'], 'missing') self.assertIn(kind, {c['kind'] for c in rows[identity]['scoped_support']}) + allowed_controls = { + 'AR.relationship.three_emotions', 'AR.relationship.affection_shield_max', + 'AR.underground.observation', 'AR.observation.recorder', + 'AR.guest.need_sexual_night_peak', 'AR.progression.three_deficits_gameover', + } | {'AR.heroine.' + p + '.route.' + r for p, _ in audit.PEOPLE for r in audit.ROUTES} + self.assertEqual({a for row in rows.values() for c in row['scoped_support'] + for a in c['atomic_requirement_ids']}, allowed_controls) for identity in ('voice.all', 'portraits.all', 'endings.all', 'encyclopedia.all'): self.assertEqual(rows[identity]['status'], 'missing') self.assertEqual(rows[identity]['evidence'], []) @@ -197,13 +208,16 @@ class LedgerTests(unittest.TestCase): row.update(status='partial', support_scope='backend only', evidence=copy.deepcopy(rows['original.line.53']['evidence'])) self.independent_reject(inject, 'unqualified partial support') - # Even a well-formed observation claim linked on the SAME source line - # cannot be attached to a voice summary. + # Preserve the same-line voice attack: the old observation schedule AR + # shares L257 with voice, even though it is now independently excluded. def voice_claim(d): voice = next(r for r in d['rows'] if r['id'] == 'voice.all') - mixed = rows['original.line.257'] + mixed = rows['original.line.53'] for key in ('status', 'support_scope', 'scoped_support', 'evidence'): voice[key] = copy.deepcopy(mixed[key]) + atom = 'AR.schedule.B-14.3.observation' + self.assertIn(atom, voice['atomic_requirement_ids']) + voice['scoped_support'][0]['atomic_requirement_ids'] = [atom] self.independent_reject(voice_claim, 'support incompatible with requirement family') # An original-clause row is an eligible family, but its debt-settlement # ARs still cannot receive a peeping-container claim. @@ -226,6 +240,11 @@ class LedgerTests(unittest.TestCase): self.assertIn(atom, rows[identity]['unsupported_atomic_requirement_ids']) def expand(d): row = next(r for r in d['rows'] if r['id'] == identity) + if not row['scoped_support']: + donor = rows['original.line.53'] + for key in ('status', 'support_scope', 'scoped_support', 'evidence'): + row[key] = copy.deepcopy(donor[key]) + row['scoped_support'][0]['atomic_requirement_ids'] = [] row['scoped_support'][0]['atomic_requirement_ids'].append(atom) row['unsupported_atomic_requirement_ids'].remove(atom) self.independent_reject(expand, 'support incompatible with AR') @@ -234,6 +253,57 @@ class LedgerTests(unittest.TestCase): ['evidence'].extend(copy.deepcopy(rows['original.line.53']['evidence'])), 'unrelated or unscoped support evidence') + def excluded_attribution_rejected(self, atom, line, kind, control_atom, control_line): + # Fixed cases below are independent of both policy and exclusion table. + audit.verify_authority(self.submitted, ROOT) + rows = {r['id']: r for r in self.submitted['rows']} + control = rows['original.line.' + str(control_line)] + self.assertTrue(any(c['kind'] == kind and control_atom in c['atomic_requirement_ids'] + for c in control['scoped_support'])) + target = rows['original.line.' + str(line)] + self.assertIn(atom, target['unsupported_atomic_requirement_ids']) + def inject(d): + row = next(r for r in d['rows'] if r['id'] == target['id']) + claim = {'kind': kind, 'atomic_requirement_ids': [atom], + 'scope': audit.SUPPORT_POLICY[kind]['scope'], 'content_status': 'missing'} + row.update(status='partial', content_status='missing', scoped_support=[claim], + support_scope=claim['scope'], evidence=audit.support_pins(ROOT, kind), + unsupported_atomic_requirement_ids=sorted(set(row['atomic_requirement_ids']) - {atom})) + self.independent_reject(inject, 'excluded attribution in row claim') + policy = copy.deepcopy(audit.SUPPORT_POLICY) + policy[kind]['ars'] = policy[kind]['ars'] | {atom} + with patch.object(audit, 'SUPPORT_POLICY', policy): + with self.assertRaisesRegex(ValueError, 'excluded attribution in SUPPORT_POLICY'): + audit.verify_authority(self.submitted, ROOT) + # Even regeneration under a corrupted policy cannot legitimize it. + with self.assertRaisesRegex(ValueError, 'excluded attribution in SUPPORT_POLICY'): + audit.verify_authority(audit.expected(ROOT), ROOT) + audit.verify_authority(self.submitted, ROOT) + + def test_excluded_camera_entry(self): + self.excluded_attribution_rejected('AR.ui.observation_camera_entry', 221, + 'peeping-container', 'AR.underground.observation', 34) + + def test_excluded_screenshot_capture(self): + self.excluded_attribution_rejected('AR.ui.observation_capture', 222, + 'peeping-container', 'AR.observation.recorder', 53) + + def test_excluded_blackmail(self): + self.excluded_attribution_rejected('AR.underground.blackmail', 21, + 'peeping-container', 'AR.observation.recorder', 53) + + def test_excluded_observation_route_progress(self): + self.excluded_attribution_rejected('AR.route_action.observation_progress', 156, + 'peeping-container', 'AR.underground.observation', 34) + + def test_excluded_dedicated_observation_mode(self): + self.excluded_attribution_rejected('AR.schedule.B-14.3.observation', 257, + 'peeping-container', 'AR.observation.recorder', 53) + + def test_excluded_ntr_event_night_peak(self): + self.excluded_attribution_rejected('AR.events.ntr_night_peak', 65, + 'night-input', 'AR.guest.need_sexual_night_peak', 65) + if __name__ == '__main__': parser = argparse.ArgumentParser()