diff --git a/editor/src/AllocationOwnershipTraceHooks.h b/editor/src/AllocationOwnershipTraceHooks.h index 1d68256..099b7a8 100644 --- a/editor/src/AllocationOwnershipTraceHooks.h +++ b/editor/src/AllocationOwnershipTraceHooks.h @@ -39,8 +39,8 @@ public: if (!error) return false; error->clear(); if (!hasRequiredDebugIds(allocationId, sessionId)) return fail(error, "allocation_or_session_missing"); - if (address == 0) return fail(error, "allocation_address_invalid"); - if (sizeBytes == 0) return fail(error, "allocation_size_invalid"); + if (!isNonZeroU64(address)) return fail(error, "allocation_address_invalid"); + if (!isNonZeroU64(sizeBytes)) return fail(error, "allocation_size_invalid"); if (owner.empty()) return fail(error, "allocation_owner_missing"); if (activeOwners_.count(allocationId) != 0) return fail(error, "allocation_id_active_duplicate"); diff --git a/editor/src/DebugValidationUtil.h b/editor/src/DebugValidationUtil.h index a24d4ab..d42e638 100644 --- a/editor/src/DebugValidationUtil.h +++ b/editor/src/DebugValidationUtil.h @@ -1,12 +1,23 @@ #pragma once // Sprint 30 refactor: shared debug validation helpers +#include #include inline bool hasRequiredDebugIds(const std::string& a, const std::string& b) { return !a.empty() && !b.empty(); } +inline bool hasRequiredDebugIds(const std::string& a, + const std::string& b, + const std::string& c) { + return hasRequiredDebugIds(a, b) && !c.empty(); +} + inline bool isPositiveLine(int line) { return line > 0; } + +inline bool isNonZeroU64(std::uint64_t value) { + return value > 0; +} diff --git a/editor/src/LeakCorruptionSignalBridge.h b/editor/src/LeakCorruptionSignalBridge.h index f4b8e4d..cec3871 100644 --- a/editor/src/LeakCorruptionSignalBridge.h +++ b/editor/src/LeakCorruptionSignalBridge.h @@ -47,9 +47,9 @@ public: if (!error) return false; error->clear(); if (!hasRequiredDebugIds(signal.signalId, signal.sessionId)) return fail(error, "signal_or_session_missing"); - if (signal.allocationId.empty()) return fail(error, "allocation_id_missing"); + if (!hasRequiredDebugIds(signal.signalId, signal.sessionId, signal.allocationId)) return fail(error, "allocation_id_missing"); if (signal.message.empty()) return fail(error, "signal_message_missing"); - if (signal.timestamp == 0) return fail(error, "signal_timestamp_invalid"); + if (!isNonZeroU64(signal.timestamp)) return fail(error, "signal_timestamp_invalid"); if (containsSignal(signal.signalId)) return fail(error, "signal_duplicate"); signals_.push_back(signal); diff --git a/editor/src/MemorySnapshotModel.h b/editor/src/MemorySnapshotModel.h index 69266d6..c27fbd5 100644 --- a/editor/src/MemorySnapshotModel.h +++ b/editor/src/MemorySnapshotModel.h @@ -74,11 +74,11 @@ public: *error = "region_id_missing"; return false; } - if (region.startAddress == 0) { + if (!isNonZeroU64(region.startAddress)) { *error = "region_start_address_invalid"; return false; } - if (region.sizeBytes == 0) { + if (!isNonZeroU64(region.sizeBytes)) { *error = "region_size_invalid"; return false; } @@ -97,7 +97,7 @@ public: std::string* error) { if (!snapshot || !error) return false; error->clear(); - if (reference.fromAddress == 0 || reference.toAddress == 0) { + if (!isNonZeroU64(reference.fromAddress) || !isNonZeroU64(reference.toAddress)) { *error = "reference_address_invalid"; return false; } @@ -112,7 +112,7 @@ public: static const MemoryRegionRecord* findRegionByAddress(const MemorySnapshot& snapshot, std::uint64_t address) { - if (address == 0) return nullptr; + if (!isNonZeroU64(address)) return nullptr; for (const auto& region : snapshot.regions) { const std::uint64_t regionEnd = region.startAddress + region.sizeBytes; if (address >= region.startAddress && address < regionEnd) return ®ion; @@ -123,7 +123,7 @@ public: static std::vector outgoingReferences(const MemorySnapshot& snapshot, std::uint64_t fromAddress) { std::vector filtered; - if (fromAddress == 0) return filtered; + if (!isNonZeroU64(fromAddress)) return filtered; for (const auto& reference : snapshot.references) { if (reference.fromAddress == fromAddress) filtered.push_back(reference); } diff --git a/editor/src/PerformanceProbeOverlay.h b/editor/src/PerformanceProbeOverlay.h index 7d89116..e978cf2 100644 --- a/editor/src/PerformanceProbeOverlay.h +++ b/editor/src/PerformanceProbeOverlay.h @@ -32,8 +32,8 @@ public: if (!hasRequiredDebugIds(sample.sampleId, sample.sessionId)) return fail(error, "sample_or_session_missing"); if (sample.bufferId.empty()) return fail(error, "sample_buffer_missing"); if (!isPositiveLine(sample.line)) return fail(error, "sample_line_invalid"); - if (sample.durationMicros == 0) return fail(error, "sample_duration_invalid"); - if (sample.timestamp == 0) return fail(error, "sample_timestamp_invalid"); + if (!isNonZeroU64(sample.durationMicros)) return fail(error, "sample_duration_invalid"); + if (!isNonZeroU64(sample.timestamp)) return fail(error, "sample_timestamp_invalid"); if (containsSample(sample.sampleId)) return fail(error, "sample_duplicate"); samples_.push_back(sample); diff --git a/editor/src/TimeTravelDebugEventBuffer.h b/editor/src/TimeTravelDebugEventBuffer.h index e487aec..e30f92f 100644 --- a/editor/src/TimeTravelDebugEventBuffer.h +++ b/editor/src/TimeTravelDebugEventBuffer.h @@ -27,8 +27,8 @@ public: error->clear(); if (!hasRequiredDebugIds(event.eventId, event.sessionId)) return fail(error, "event_or_session_missing"); if (event.type.empty()) return fail(error, "event_type_missing"); - if (event.timestamp == 0) return fail(error, "event_timestamp_invalid"); - if (event.instructionPointer == 0) return fail(error, "event_ip_invalid"); + if (!isNonZeroU64(event.timestamp)) return fail(error, "event_timestamp_invalid"); + if (!isNonZeroU64(event.instructionPointer)) return fail(error, "event_ip_invalid"); if (containsId(event.eventId)) return fail(error, "event_duplicate"); events_.push_back(event); diff --git a/progress.md b/progress.md index 466a26e..8c58e9f 100644 --- a/progress.md +++ b/progress.md @@ -10517,3 +10517,42 @@ into phase/sprint pass states with closure diagnostics. - **New tests in this sprint plan:** 112/112 passing - **Phase 31a (564-568):** 56/56 passing - **Phase 31b (569-573):** 56/56 passing + +### Sprint 31 End Refactor Pass (Architecture Compliance) +**Status:** PASS (112/112 tests revalidated) + +Performed a focused post-sprint architecture pass to standardize primitive +validation paths across Sprint 31 memory/observability modules while keeping +all components header-only and within file-size constraints. + +**Files modified:** +- `editor/src/DebugValidationUtil.h` - expanded shared validation helpers: + - three-id presence check overload + - shared non-zero `uint64` guard helper +- `editor/src/MemorySnapshotModel.h` - switched address/size/reference guards to shared non-zero utility +- `editor/src/AllocationOwnershipTraceHooks.h` - switched allocation address/size guards to shared non-zero utility +- `editor/src/LeakCorruptionSignalBridge.h` - switched timestamp guard to shared non-zero utility and standardized allocation-id presence validation path +- `editor/src/TimeTravelDebugEventBuffer.h` - switched timestamp/instruction-pointer guards to shared non-zero utility +- `editor/src/PerformanceProbeOverlay.h` - switched duration/timestamp guards to shared non-zero utility + +**Verification run:** +- `cmake --build editor/build-native --target step564_test step565_test step566_test step567_test step568_test step569_test step570_test step571_test step572_test step573_test` - PASS +- `./editor/build-native/step564_test` - PASS (12/12) +- `./editor/build-native/step565_test` - PASS (12/12) +- `./editor/build-native/step566_test` - PASS (12/12) +- `./editor/build-native/step567_test` - PASS (12/12) +- `./editor/build-native/step568_test` - PASS (8/8) +- `./editor/build-native/step569_test` - PASS (12/12) +- `./editor/build-native/step570_test` - PASS (12/12) +- `./editor/build-native/step571_test` - PASS (12/12) +- `./editor/build-native/step572_test` - PASS (12/12) +- `./editor/build-native/step573_test` - PASS (8/8) + +**Architecture gate check:** +- `editor/src/DebugValidationUtil.h` within header-size limit (`23` <= `600`) +- `editor/src/MemorySnapshotModel.h` within header-size limit (`149` <= `600`) +- `editor/src/AllocationOwnershipTraceHooks.h` within header-size limit (`150` <= `600`) +- `editor/src/LeakCorruptionSignalBridge.h` within header-size limit (`154` <= `600`) +- `editor/src/TimeTravelDebugEventBuffer.h` within header-size limit (`86` <= `600`) +- `editor/src/PerformanceProbeOverlay.h` within header-size limit (`110` <= `600`) +- Shared validation centralization reduces repeated primitive guards and keeps module boundaries aligned with `ARCHITECTURE.md`