Batch 42 · R2f full-config document and file owner¶
2026-10-26, dev-0.9.0-bootloader, starting HEAD 21953fc4. Implementation c947f248 contains four C# files/four metadata files; documentation/evidence follows separately. All existing runtime code remains unchanged. No push or player build.
Concrete boundary¶
ConfigDocument owns full JSON with the validated input wrapper; GameConfig is only a fresh typed view. Explicit settings patches compare a view baseline, merge changed known fields, reject same-field staleness and retain unknown/nested/precise untouched values. Input edits replace only the validated input section when its own baseline matches, so a stale draft's audio/root data cannot overwrite current settings. Ordinary settings patches reject legacy-control-list edits and graphics-object removal. This is not yet the compatibility adapter for current preset UI.
ConfigFileStore takes a supplied absolute path/definition without choosing a Steam identity/environment, creating folders or invoking normal SaveService. Load/snapshots do not mark dirty or save; Stage is explicit. Candidate revision tokens reject stale/foreign branches without retaining every old document. Store operations require their owning thread and reject write-time reentry. Dirty reload requires explicit discard. See the config contract.
Saving acquires an exclusive create-new adjacent lock, checks source bytes, writes/flushing/verifies a unique candidate, creates/verifies a byte-exact original backup, rechecks source bytes, then uses native Replace or non-overwriting Move and verifies publication. Unsupported replacement has no delete-original fallback. Failed writes keep pending data dirty; an uncertain publication retains recovery state and requires explicit reconciliation. Backups and unknown locks are not deleted automatically. Known field types/DTO representability are checked, with no live catalog/range correction. Loaded/apply policies and production SaveManager/SaveService/GameSettings remain unmigrated.
Executed evidence and failures¶
Required Unity 6000.2.8f1, Input System 1.17.0, direct -batchmode -nographics -executeMethod TinyChaos.EditorTools.ConfigPersistenceChecks.RunBatch42, explicit project/private-log paths and no immediate -quit. The synchronous entry owns process exit. Edit Mode only: no scene entry, device/user creation or normal profile IO.
Initial 7 passed / 3 failed, exit1: G05/G08 candidate-verification errors escaped the failed-write result because this runtime's InvalidDataException was outside the existing IO filter; G09 a non-finite edit hit Newtonsoft numeric comparison before validation and escaped as OverflowException. The adapter now classifies verification failures explicitly and validates/rejects invalid numeric edits before patching. Same suite then passed 10/10, exit0. Review also added a write-time reentry guard and an expanded actual IO-callback check; final expanded suite remains 10/10, exit0.
| Group | Final actual result |
|---|---|
| G01 | PASS: load/view/preparing edits performs no write/dirty transition; fresh views cannot mutate authority; unchanged precise decimals, dates, nested/root/legacy extensions survive patches; old reader sees expected values. |
| G02 | PASS: accepted remap merges without overwriting newer settings; stale input and same-field settings edits reject; unrelated current changes survive; legacy control edits cannot bypass the input owner. |
| G03 | PASS: real native Linux replacement/reload for UTF-8 no BOM/BOM, UTF-16 LE/BE BOM and UTF-32 LE/BE BOM; original backups are byte-exact, next output is UTF-8 no BOM, a fresh owner loads both edits/remaps, SDK action-copy application works, and a second save retains earlier recovery files. |
| G04 | PASS: missing file has no automatic default write; explicit creation works; empty/truncated/malformed/invalid-encoding/unsupported-input/read-failed files remain unwritten and cannot stage defaults as recovery. |
| G05 | PASS: injected candidate write/verify, backup write/verify, replace and lock/permission failures preserve original bytes and the dirty candidate; retry after removing each fault saves successfully. |
| G06 | PASS: two loaded writers cannot overwrite newer bytes; dirty reload is explicit; unknown lock content survives failed acquire; a late external write is preserved as a conflict. |
| G07 | PASS: error after actual publication or unreadable published verification yields Indeterminate, retains exact recovery bytes/dirty state and cannot blindly retry over changed content; explicit reload reconciles actual committed data. |
| G08 | PASS: unsupported replacement does not delete/fallback over original; cleanup errors do not mask a failed write or verified publication; store deletion requests target only its candidate paths. |
| G09 | PASS: malformed known field types/ranges of integer representation reject; missing non-input fields are not materialized; non-finite edits, graphics removal and accepted-root unrelated data cannot corrupt a candidate. |
| G10 | PASS: exclusive creation preserves an existing file; stale/foreign candidates and worker mutation reject; promoting one store does not mutate another's authority; reentrant stage/load/discard/save from a real candidate-write callback reject without losing the intended publication. |
IO errors, permission/full-disk and publication/read failures are injected around real temporary files, not actual OS permission denial, disk exhaustion or power interruption. Native replacement success is Linux/Editor evidence only. No Windows/player/IL2CPP, filesystem power-loss durability, arbitrary external-writer compare-and-swap, stale-lock recovery or backup retention policy is certified. Locks coordinate stores using the same path; old writers/aliases can bypass them. Production rollout remains gated.
Existing-category CS8785 generator and CS0252 StabilizationChecks warnings remain; final log has no compiler errors or unexpected runtime exceptions. Older gameplay/input suites were not rerun because their files/callers and authored definitions are byte-unchanged and the adapter is not wired into production. Private logs /tmp/tinychaos-batch42-editor.log (7/10), /tmp/tinychaos-batch42-editor-final.log (10/10) and /tmp/tinychaos-batch42-editor-verified.log (expanded 10/10), with stdout, stay outside Git. Successful fixtures delete only their unique temporary directories; failed synthetic fixtures remain outside Git. No real config contents/preferences or raw logs are committed.
Preservation and exact implementation manifest¶
Pre-run capture /tmp/tinychaos-batch42-preserve-42a4fd13aa/ contains 2,871 project file bytes/hashes, 8,172 Unity/profile hashes and recoverable preference bytes. All 2,871 prior project files and all 54 prior unique implementation paths match. Original 608-source pins retain 606 matches plus only batch 37's two documented package exceptions. Existing action IDs, scenes/prefabs/build lists/settings and source/metadata remain unchanged. The unresolved audio deletions and generated Addressables Linux metadata remain excluded.
Unity inserted only com.unity.toolchain.linux-x86_64 in manifest/lock; reviewed generated copies were archived and exact captured bytes restored, retaining Input System 1.17.0. Shared prefs changed only two automatic Editor session keys; those were archived/restored from capture after key-level comparison. Normal game profile coverage is one prefs file, byte-unchanged throughout; no new profile/save/config appeared. Five external licensing/package/metrics bookkeeping files changed and remain, so the entire Unity profile tree is not claimed unchanged.
Only four new metadata files had empty-field trailing whitespace normalized, preserving unique GUIDs. Inventory appends four reviewed scripts (254 total) without rewriting earlier 250 rows; gates append ten groups (105 total), preserving the earlier 95 and all 27 open workstream follow-ups. The 22-row legacy input consumer map is unchanged. ARCH-01 stays active.
| Path | Kind | SHA-256 |
|---|---|---|
| Assets/Script/TinyChaos/Services/Save/ConfigDocument.cs | config document/file adapter | b21ec00a2e1bdc2917b5b7097347400cd4e9c5ac7501405577905b423cf031c9 |
| Assets/Script/TinyChaos/Services/Save/ConfigDocument.cs.meta | metadata | 369ebebf0a06b2a0de5f4445c555ac95a469e8a5de8c6e67414ab625d118d261 |
| Assets/Script/TinyChaos/Services/Save/ConfigFileStore.cs | config document/file adapter | 53722a78141f0a202f5aae4b90c47766a54cc70ede9da744facfa4dbdcc1e7b4 |
| Assets/Script/TinyChaos/Services/Save/ConfigFileStore.cs.meta | metadata | 31a27bc413fdc44bc575d43b2b5c85e2ae2c9ca31b930ddaf4d88d271e0a0c6f |
| Assets/Script/TinyChaos/Services/Save/ConfigFileOperations.cs | config document/file adapter | a8f1c30753af88b69ad2ec1ff4984e43050c6e26dbd6ae1604fa6f23a3a3188d |
| Assets/Script/TinyChaos/Services/Save/ConfigFileOperations.cs.meta | metadata | 979446c141d174aecd3d6408ab0d0b6edca121afbfa3cbeed27c6c430c04e474 |
| Assets/Script/External/Editor/ConfigPersistenceChecks.cs | Editor IO checks | 57e32f4928fb19e3ddd81f86900c48dd3eea93314c6b1aa140802b7ee068fe86 |
| Assets/Script/External/Editor/ConfigPersistenceChecks.cs.meta | metadata | 11cc3383ccf1b645bf0a26f4ef08ba6c7939342397aaf1434ad9fae2bcea3c62 |
Final static review passes: 803 local documentation links resolve, all 53 issue IDs route once, 254 inventory paths match project scripts, and all prior 250 inventory/95 gate rows remain byte-preserved. The implementation commit contains exactly the eight reviewed additions and matching tested hashes, without documentation or unrelated changes. Whitespace checks pass.
Next and commit boundaries¶
Next is the config-owner compatibility handoff: explicit legacy preset commands, unknown-record retention, and loaded/apply versus deliberate edit/persist ownership before routing current callers. Ordinary WithSettings deliberately rejects control changes; bypassing it with whole-root replacement would restore a second input authority. Verify affected entry points through injected disposable paths rather than constructing normal SaveService directories for tests. Then migrate one caller slice, keeping error/uncertainty propagation and Windows/recovery/retention gates explicit. UI/setup/recovery, legacy-feel/physical checks and actor integration follow dependencies. GAME-01 and Tutorial remain deferred.
Eight implementation additions form one commit, with this documentation/evidence/status/contract/inventory work in its own commit. No push. Production persistence and R2/F1/gameplay completion remain unfinished.