소스 검색

Accept only complete msg-6 packets as mission observations again

A partially decoded packet no longer feeds mission observations.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
stan 4 일 전
부모
커밋
90a9d8885b

+ 0 - 30
Sunrise/src/server/activity/host_runtime_internal.h

@@ -312,36 +312,6 @@ void reset_client_messages() noexcept;
 
 // The mission-input unit owns these. Every reducer that accepts a client input calls into them.
 
-/** One accepted client input with the exact values its program will read. */
-struct MissionInputRecord final {
-    MissionInputEvent view{};
-    middleware::bap::activity_message::sense_update::DecodedPacket sense{};
-    ClientMessageSnapshot clientMessage{};
-    bool hasSense{};
-    bool hasClientMessage{};
-};
-
-/** What one msg-6 receipt claimed about its packet, as retained beside the decoded values. */
-struct SenseEnvelope final {
-    std::uint64_t sourceGeneration{};
-    std::uint64_t clientMessageSequence{};
-    state::activity::receipts::Verdict verdict{};
-    middleware::bap::activity_message::sense_update::DecodeStatus decodeStatus{};
-    std::uint32_t groupsSeen{};
-    std::uint32_t groupsDecoded{};
-    std::uint32_t groupsSkipped{};
-    std::uint32_t objectsSeen{};
-    std::uint32_t objectsDecoded{};
-};
-
-/** @return True when every exposed object is complete inside one safely framed packet. */
-[[nodiscard]] bool usable_sense_observation_packet(
-    const SenseEnvelope& envelope,
-    const middleware::bap::activity_message::sense_update::DecodedPacket& packet) noexcept;
-
-/** Accepted rows in feed order; the Host lock guards it. */
-extern std::vector<MissionInputRecord> g_missionInputs;
-
 /** Assigns one exact binding's ordered client mission-input sequence. */
 void stamp_mission_sequence(Event& event) noexcept;
 

+ 12 - 18
Sunrise/src/server/activity/host_runtime_mission_inputs.cpp

@@ -18,17 +18,21 @@
 #include "host_runtime_internal.h"
 
 namespace sunrise::server::activity::host {
-namespace detail {
-
-/** The feed is unbounded; it holds every accepted row until its program commits it. */
-std::vector<MissionInputRecord> g_missionInputs{};
-
-} // namespace detail
-
 namespace {
 
 using namespace detail;
 
+/** One accepted client input with the exact values its program will read. */
+struct MissionInputRecord final {
+    MissionInputEvent view{};
+    middleware::bap::activity_message::sense_update::DecodedPacket sense{};
+    ClientMessageSnapshot clientMessage{};
+    bool hasSense{};
+    bool hasClientMessage{};
+};
+
+/** The feed is unbounded; it holds every accepted row until its program commits it. */
+std::vector<MissionInputRecord> g_missionInputs{};
 std::uint64_t g_missionInputSequence{};
 
 /** @return True when this event kind enters the ordered mission-input feed. */
@@ -229,17 +233,7 @@ bool mission_input_sense_snapshot(std::uint64_t sequence,
     if (copied) {
         const Event& event = selected->view.event;
         const sense::DecodedPacket& packet = selected->sense;
-        copied =
-            usable_sense_observation_packet({.sourceGeneration = event.sourceGeneration,
-                                             .clientMessageSequence = event.clientMessageSequence,
-                                             .verdict = event.verdict,
-                                             .decodeStatus = event.senseDecodeStatus,
-                                             .groupsSeen = event.groupsSeen,
-                                             .groupsDecoded = event.groupsDecoded,
-                                             .groupsSkipped = event.groupsSkipped,
-                                             .objectsSeen = event.objectsSeen,
-                                             .objectsDecoded = event.objectsDecoded},
-                                            packet);
+        copied = sense::observation_packet(packet);
         if (copied) {
             output.revision = event.sequence;
             output.sourceGeneration = event.sourceGeneration;

+ 8 - 67
Sunrise/src/server/activity/host_runtime_sense.cpp

@@ -21,62 +21,6 @@
 #include "host_runtime_internal.h"
 
 namespace sunrise::server::activity::host {
-namespace detail {
-
-/**
- * Tests whether every exposed object is complete inside one safely framed packet. A partial decode
- * must carry a partial receipt, and an unsafe or malformed sibling refuses the whole packet.
- */
-bool usable_sense_observation_packet(
-    const SenseEnvelope& envelope,
-    const middleware::bap::activity_message::sense_update::DecodedPacket& packet) noexcept {
-    const auto& [sourceGeneration,
-                 clientMessageSequence,
-                 verdict,
-                 decodeStatus,
-                 groupsSeen,
-                 groupsDecoded,
-                 groupsSkipped,
-                 objectsSeen,
-                 objectsDecoded] = envelope;
-    namespace sense = middleware::bap::activity_message::sense_update;
-    if (sourceGeneration == 0 || clientMessageSequence == 0
-        || !((decodeStatus == sense::DecodeStatus::complete
-              && verdict == state::activity::receipts::Verdict::framed)
-             || (decodeStatus == sense::DecodeStatus::partial
-                 && verdict == state::activity::receipts::Verdict::partial))
-        || decodeStatus != packet.status || !sense::observation_packet(packet)
-        || groupsSeen != packet.groupsSeen || groupsDecoded != packet.groupsDecoded
-        || groupsSkipped != packet.groupsSkipped || objectsSeen != packet.objectsSeen
-        || objectsDecoded != packet.objectsDecoded || packet.objectsDecoded == 0
-        || packet.objectCount > packet.objectsSeen || packet.groupsDecoded > packet.groupsSeen
-        || packet.groupsSkipped > packet.groupsSeen
-        || packet.groupsDecoded != packet.groupsSeen - packet.groupsSkipped) {
-        return false;
-    }
-    for (std::size_t index = 0; index < packet.objectCount; ++index) {
-        const sense::DecodedObject& object = packet.objects[index];
-        if (object.status == sense::ObjectStatus::unsafeCount) {
-            return false;
-        }
-        if (object.status != sense::ObjectStatus::decoded) {
-            continue;
-        }
-        for (std::size_t prior = 0; prior < index; ++prior) {
-            const sense::DecodedObject& other = packet.objects[prior];
-            if (other.status == sense::ObjectStatus::decoded
-                && other.registryKey == object.registryKey && other.objectTag == object.objectTag
-                && other.senseSchema == object.senseSchema && other.schemaRow == object.schemaRow
-                && other.slotIndex == object.slotIndex && other.slotType == object.slotType) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-} // namespace detail
-
 namespace {
 
 using namespace detail;
@@ -107,17 +51,14 @@ packet_has_sense_key(const middleware::bap::activity_message::sense_update::Deco
 
 /** @return True when the envelope closed and each decoded object's storage is bounded. */
 [[nodiscard]] bool valid_sense_observation_input(const SenseInput& input) noexcept {
-    return detail::usable_sense_observation_packet(
-        {.sourceGeneration = input.sourceGeneration,
-         .clientMessageSequence = input.clientMessageSequence,
-         .verdict = input.verdict,
-         .decodeStatus = input.decodeStatus,
-         .groupsSeen = input.groupsSeen,
-         .groupsDecoded = input.groupsDecoded,
-         .groupsSkipped = input.groupsSkipped,
-         .objectsSeen = input.objectsSeen,
-         .objectsDecoded = input.objectsDecoded},
-        input.decoded);
+    namespace sense = middleware::bap::activity_message::sense_update;
+    const auto& packet = input.decoded;
+    return input.sourceGeneration != 0 && input.clientMessageSequence != 0
+           && input.verdict == state::activity::receipts::Verdict::framed
+           && input.decodeStatus == packet.status && sense::observation_packet(packet)
+           && input.groupsSeen == packet.groupsSeen && input.groupsDecoded == packet.groupsDecoded
+           && input.groupsSkipped == packet.groupsSkipped && input.objectsSeen == packet.objectsSeen
+           && input.objectsDecoded == packet.objectsDecoded;
 }
 
 /** Mixes one fixed-width value into the local scene change guard. */