Describe staged source verification boundaries accurately

This commit is contained in:
Emil
2026-09-24 04:04:39 +03:00
parent 523dbd76a4
commit bf51ff0ec4
6 changed files with 26 additions and 13 deletions
+6 -2
View File
@@ -114,13 +114,17 @@ Development и release Player содержат runtime, выбранные иг
## 10. P1 — проверяемая итерация gameplay ## 10. P1 — проверяемая итерация gameplay
Для native-сборки источником истины остаются CMake/Ninja и их dependency graph. Для native-сборки источником истины остаются CMake/Ninja и их dependency graph.
BuildService снимает неизменяемый snapshot `Scripts`, отделяет Debug от Release и BuildService сохраняет проверяемую копию `Scripts` по хешу содержимого,
отделяет Debug от Release и
запоминает версионированный fingerprint рецепта, исходников, Lua-деклараций, запоминает версионированный fingerprint рецепта, исходников, Lua-деклараций,
toolchain, шейдерных и runtime-входов. Повторное использование schema/package toolchain, шейдерных и runtime-входов. Повторное использование schema/package
разрешено лишь после проверки полного manifest и схемы; испорченная или устаревшая разрешено лишь после проверки полного manifest и схемы; испорченная или устаревшая
генерация не выдаётся за cache hit. Переключение указателя на успешную генерацию генерация не выдаётся за cache hit. Переключение указателя на успешную генерацию
атомарно; сбой сборки оставляет предыдущую доступной, но Inspector помечает атомарно; сбой сборки оставляет предыдущую доступной, но Inspector помечает
метаданные устаревшими. Экспорт отдельно проверяет asset generations. метаданные устаревшими. Исходный каталог и копия повторно хешируются после native
build и перед повторным использованием кэша или публикацией. Это обнаруживает сохранившееся изменение;
запись и восстановление прежних байтов другим процессом того же пользователя во
время чтения компилятором не исключены. Экспорт отдельно проверяет asset generations.
Структурированные сообщения компилятора/Lua дополняют сырой лог. Для исходников Структурированные сообщения компилятора/Lua дополняют сырой лог. Для исходников
проекта Editor и MCP вызывают один `faset_source_open` с относительным путём и проекта Editor и MCP вызывают один `faset_source_open` с относительным путём и
+6 -4
View File
@@ -469,18 +469,20 @@ GPU coverage remain untested.
## Post-MVP checkpoint — P1 gameplay iteration ## Post-MVP checkpoint — P1 gameplay iteration
P1 adds a complete-input native build stamp and an immutable `Scripts` snapshot. P1 adds a complete-input native build stamp and a content-addressed `Scripts` copy.
The package key binds configuration, recipe, source, Lua declaration, toolchain, The package key binds configuration, recipe, source, Lua declaration, toolchain,
shader and runtime artifacts. A second unchanged build reuses a verified schema shader and runtime artifacts. A second unchanged build reuses a verified schema
and package generation without invoking SchemaExporter; CMake/Ninja still verify and package generation without invoking SchemaExporter; CMake/Ninja still verify
the native graph. Malformed/corrupt generations, modified headers/tools and the native graph. Malformed/corrupt generations, modified headers/tools and
source races cannot publish a false hit. Failed jobs preserve the previous detected source mismatches cannot publish a false hit. The live tree and staged
successful pointer, while Inspector metadata becomes stale. copy are rehashed after native build and before reuse/publication; a same-user
write-and-restore during compiler reads remains outside this check. Failed jobs
preserve the previous successful pointer, while Inspector metadata becomes stale.
Compiler and Lua output now produce bounded structured Console diagnostics with Compiler and Lua output now produce bounded structured Console diagnostics with
raw logs retained. Source opening accepts only project `Scripts` files and passes raw logs retained. Source opening accepts only project `Scripts` files and passes
literal file/line/column arguments to the configured external editor. A real literal file/line/column arguments to the configured external editor. A real
compile failure revealed that compiler paths pointed to the immutable snapshot; compile failure revealed that compiler paths pointed to the staged copy;
`d7a7a7c` maps only the verified snapshot subtree back to project-relative `d7a7a7c` maps only the verified snapshot subtree back to project-relative
source. The same correction retains a later actionable error after 250 unrelated source. The same correction retains a later actionable error after 250 unrelated
warnings. Four runnable C++/Lua × 2D/3D starters are available in launcher and warnings. Four runnable C++/Lua × 2D/3D starters are available in launcher and
+4 -3
View File
@@ -28,7 +28,7 @@ Player is observed by the Editor, which keeps its logs and authoring state.
An unchanged second build still asks CMake/Ninja to verify their dependency graph. An unchanged second build still asks CMake/Ninja to verify their dependency graph.
When the native outputs, gameplay sources, toolchain, shaders and runtime inputs When the native outputs, gameplay sources, toolchain, shaders and runtime inputs
match the validated package, **Jobs** reports `schema_cache_hit` and match the validated package, **Jobs** reports `schema_cache_hit` and
`generation_reused` as true and returns the same immutable generation without a `generation_reused` as true and returns the same verified generation without a
second SchemaExporter run or package copy. A changed `.cpp`, header, Lua declaration, second SchemaExporter run or package copy. A changed `.cpp`, header, Lua declaration,
build recipe or relevant tool invalidates that reuse. A damaged cached package is build recipe or relevant tool invalidates that reuse. A damaged cached package is
not treated as a hit. The job also exposes elapsed phases and a build fingerprint; not treated as a hit. The job also exposes elapsed phases and a build fingerprint;
@@ -64,9 +64,10 @@ Development builds use **Debug**. Exports default to **Release** and use a separ
CMake cache. The BuildService API also accepts `RelWithDebInfo` for exports. Exporting CMake cache. The BuildService API also accepts `RelWithDebInfo` for exports. Exporting
does not change the configuration of your development Player. does not change the configuration of your development Player.
Each successful export creates an immutable directory under Each successful export creates a versioned directory under
`Exports/MyGame/generations/<generation>`. `current.json` points to the active `Exports/MyGame/generations/<generation>`. `current.json` points to the active
generation. Distribute the **whole generation directory**, not just the executable. generation. The Editor leaves published generations untouched. Distribute the
**whole generation directory**, not just the executable.
If building, cooking or verification fails, the previous pointer and package remain If building, cooking or verification fails, the previous pointer and package remain
available. Cancelling a job does not delete earlier exports. available. Cancelling a job does not delete earlier exports.
+1 -1
View File
@@ -36,7 +36,7 @@ Add explicit entry scripts to `project.faset.json`:
This is a manifest fragment, not a complete project file. Each entry must return one This is a manifest fragment, not a complete project file. Each entry must return one
`faset.behavior` table with a unique custom TypeId. All sources live beneath `Scripts` `faset.behavior` table with a unique custom TypeId. All sources live beneath `Scripts`
and are captured as an immutable build/export snapshot. Paths must be project-relative; and are copied into a content-verified build/export snapshot. Paths must be project-relative;
symlinks and paths outside `Scripts` are rejected. Auxiliary modules do not need to symlinks and paths outside `Scripts` are rejected. Auxiliary modules do not need to
appear in the entry list. appear in the entry list.
@@ -45,7 +45,7 @@ The run also imported the small Blender bundle cold and cached in 49 and 52 ms,
respectively; Editor process startup dominates that tiny asset sample, so those respectively; Editor process startup dominates that tiny asset sample, so those
two values do not establish import-cache speedup. The raw two values do not establish import-cache speedup. The raw
[failed-build job](raw/build_failure-01-stdout.txt) exposed a navigation defect: [failed-build job](raw/build_failure-01-stdout.txt) exposed a navigation defect:
the compiler named the immutable source snapshot, and the original structured the compiler named the staged source copy, and the original structured
diagnostic omitted `file`. A later fix maps only the verified staged `Scripts` diagnostic omitted `file`. A later fix maps only the verified staged `Scripts`
subtree to project-relative source. A [real failed-build replay](diagnostic-replay.json) subtree to project-relative source. A [real failed-build replay](diagnostic-replay.json)
with the corrected Editor returns `Scripts/Gameplay.cpp`, line 73, column 2. with the corrected Editor returns `Scripts/Gameplay.cpp`, line 73, column 2.
@@ -54,6 +54,12 @@ Windows drives; `build_schema_publication` verifies that an error after 250
third-party warnings survives the 200-row diagnostic limit. These are separate third-party warnings survives the 200-row diagnostic limit. These are separate
from this unmodified measurement. from this unmodified measurement.
Follow-up `54d1bae` rehashes both the live source and the staged copy after
native build and before reuse/publication. A fixture changes the staged C++
header during schema export; the build fails and retains the last-good pointer.
The copy is content-verified at those boundaries, not sealed against a same-user
write-and-restore during compiler reads.
The [3,000-frame lifecycle profile](raw/cpp-3000-frame-lifecycle.json) completed The [3,000-frame lifecycle profile](raw/cpp-3000-frame-lifecycle.json) completed
with zero Vulkan validation errors. Maximum explicit Vulkan allocation was with zero Vulkan validation errors. Maximum explicit Vulkan allocation was
15,787,008 bytes in both frames 101–200 and 2901–3000, a measured growth of zero; 15,787,008 bytes in both frames 101–200 and 2901–3000, a measured growth of zero;
+2 -2
View File
@@ -23,8 +23,8 @@ BuildInputs capture_build_inputs(const BuildConfig& config, const scripting::Lua
std::optional<std::string> configured_cmake_value(const BuildConfig& config, std::optional<std::string> configured_cmake_value(const BuildConfig& config,
std::string_view key); std::string_view key);
// Copy a content-addressed, immutable Scripts tree for the native compiler. // Copy a content-addressed Scripts tree for the native compiler. BuildService
// Returning the same path for equal source bytes preserves Ninja incrementality. // rehashes it at phase boundaries; returning the same path preserves Ninja incrementality.
std::filesystem::path stage_gameplay_sources(const BuildConfig& config, std::filesystem::path stage_gameplay_sources(const BuildConfig& config,
const BuildInputs& inputs, const BuildInputs& inputs,
const scripting::LuaProject& lua, const scripting::LuaProject& lua,