Expose asset timestamp probe boundary

This commit is contained in:
2026-06-12 16:54:42 +02:00
parent b9b0663546
commit a6b01c2d12
5 changed files with 48 additions and 15 deletions

View File

@@ -242,6 +242,11 @@ agent or engineer to remove them without reconstructing context from chat.
`plan_asset_file_load` wrapper still performs the retained `stat` probe for
mtime platforms until asset/file watching is owned by injected storage
services.
- 2026-06-12: DEBT-0054 was narrowed again. The retained mtime probe is now an
explicit `pp_platform_api::probe_asset_file_timestamp` boundary with missing
and existing file coverage, and `plan_asset_file_load_for_platform` consumes
that probe instead of owning the `stat` call inline. Injected file-watch or
storage services still need to own the live probe before the debt closes.
- 2026-06-05: DEBT-0056 was narrowed. `src/asset.h` no longer exposes Android
SDK types or forward declarations; retained Android asset-manager and asset
handles are stored as opaque pointers and cast only inside `src/asset.cpp`,

View File

@@ -644,6 +644,8 @@ mobile platform keyboard bridges continue.
`pano_cli plan-cursor-visibility` exposes the app-core cursor visibility
decision used by live canvas cursor requests before retained desktop platform
cursor bridges continue.
`pp_platform_api::probe_asset_file_timestamp` now owns the retained asset mtime
probe used by layout reload planning, with missing/existing file coverage.
`pano_cli plan-clipboard-read` and `pano_cli plan-clipboard-write` expose the
app-core clipboard text decisions used by live clipboard get/set requests
before retained platform clipboard bridges continue.

View File

@@ -5,6 +5,19 @@
namespace pp::platform {
AssetFileTimestampProbe probe_asset_file_timestamp(std::string_view absolute_path)
{
struct stat file_info {};
const std::string path(absolute_path);
if (stat(path.c_str(), &file_info) != 0)
return {};
return {
true,
static_cast<std::int64_t>(file_info.st_mtime),
};
}
AssetFileLoadDecision plan_asset_file_load_with_probe(
PlatformFamily family,
bool already_loaded,
@@ -43,25 +56,11 @@ AssetFileLoadDecision plan_asset_file_load_for_platform(
{});
}
struct stat file_info {};
const std::string path(absolute_path);
if (stat(path.c_str(), &file_info) != 0)
{
return plan_asset_file_load_with_probe(
family,
already_loaded,
previous_last_write_time,
{});
}
return plan_asset_file_load_with_probe(
family,
already_loaded,
previous_last_write_time,
{
true,
static_cast<std::int64_t>(file_info.st_mtime),
});
probe_asset_file_timestamp(absolute_path));
}
AssetFileLoadDecision plan_asset_file_load(

View File

@@ -18,6 +18,9 @@ struct AssetFileTimestampProbe {
std::int64_t last_write_time = 0;
};
[[nodiscard]] AssetFileTimestampProbe probe_asset_file_timestamp(
std::string_view absolute_path);
[[nodiscard]] AssetFileLoadDecision plan_asset_file_load_with_probe(
PlatformFamily family,
bool already_loaded,

View File

@@ -799,6 +799,27 @@ void asset_file_load_policy_preserves_platform_reload_behavior(pp::tests::Harnes
std::filesystem::remove(temp_path);
}
void asset_file_load_policy_exposes_timestamp_probe(pp::tests::Harness& harness)
{
const auto temp_path = std::filesystem::temp_directory_path()
/ "panopainter-platform-api-timestamp-probe.xml";
std::filesystem::remove(temp_path);
const auto missing = pp::platform::probe_asset_file_timestamp(temp_path.string());
PP_EXPECT(harness, !missing.file_exists);
{
std::ofstream file(temp_path);
file << "<layouts />";
}
const auto existing = pp::platform::probe_asset_file_timestamp(temp_path.string());
PP_EXPECT(harness, existing.file_exists);
PP_EXPECT(harness, existing.last_write_time > 0);
std::filesystem::remove(temp_path);
}
void asset_file_load_policy_preserves_family_reload_behavior(pp::tests::Harness& harness)
{
const auto missing_desktop = pp::platform::plan_asset_file_load_with_probe(
@@ -1074,6 +1095,9 @@ int main()
harness.run(
"asset file load policy preserves platform reload behavior",
asset_file_load_policy_preserves_platform_reload_behavior);
harness.run(
"asset file load policy exposes timestamp probe",
asset_file_load_policy_exposes_timestamp_probe);
harness.run(
"asset file load policy preserves family reload behavior",
asset_file_load_policy_preserves_family_reload_behavior);