From 1de44af7cc6c5dc1aa2c0bc6255577e49220a767 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 13:46:17 +0000 Subject: [PATCH] chore(repo): archive historical docs under Docs/archive, drop tracked pycache Move closed audits, task briefs, design rounds, perf reports, the OPSTACK plan/progress logs and WORK-NEXT.md into Docs/archive/ (git mv, history kept). Whitelist Docs/ in the strict .gitignore, ignore Tools/**/__pycache__/, and remove the tracked .pyc. Repoint references in the kept docs and in non-test source comments to the new paths. --- .gitignore | 7 ++++++- ARCHITECTURE.md | 6 +++--- CODEMAP.md | 4 ++-- COMPOSER-NOTES.md | 6 +++--- .../archive/AUDIT-2026-07.md | 0 .../archive/AUDIT-2026-08-CODEX.md | 0 .../archive/AUDIT-COLD-2026-09-14.md | 0 .../archive/AUDIT-SOL-2026-09-11.md | 0 .../archive/CODEX-TASK-001-tile-skip-stats.md | 0 .../CODEX-TASK-002-column-memo-thrash.md | 0 .../CODEX-TASK-003-extrareach-perlin-bound.md | 0 .../CODEX-TASK-004-minmax-radius-envelope.md | 0 .../CODEX-TASK-005-tile-scan-sampler-extent.md | 0 ...-TASK-006-cave-morphology-radius-envelope.md | 0 .../archive/CODEX-TASK-007-generation-pause.md | 0 ...EX-TASK-008-column-memo-and-t1d-diagnosis.md | 0 .../CODEX-TASK-1-PROFILER-BATCH-RESEARCH.md | 0 .../archive/CODEX-TASK-2-PERF-REPORT.md | 0 .../archive/DESIGN-SOL-2026-09-15-CODE.md | 0 .../archive/DESIGN-SOL-2026-09-15.md | 0 .../archive/INVESTIGATION-2026-08-SOL.md | 0 .../archive/OPSTACK-DECOMPOSITION.md | 0 .../archive/OPSTACK-HANDOFF.md | 0 OPSTACK-PLAN.md => Docs/archive/OPSTACK-PLAN.md | 0 .../archive/OPSTACK-PROGRESS.md | 0 .../archive/OPSTACK-PROMPT.md | 0 .../archive/PERF-ATTRIBUTION.md | 0 PERF-SAMPLED.md => Docs/archive/PERF-SAMPLED.md | 0 WORK-NEXT.md => Docs/archive/WORK-NEXT.md | 0 Source/VoxelForge/Public/VoxelDensityOp.h | 2 +- .../VoxelForge/Public/VoxelStrateDefinition.h | 2 +- Source/VoxelForge/VoxelForge.Build.cs | 2 +- .../AnalyzeVoxelForgePerfProbes.cpython-312.pyc | Bin 26900 -> 0 bytes fable-idea.md | 6 +++--- 34 files changed, 20 insertions(+), 15 deletions(-) rename AUDIT-2026-07.md => Docs/archive/AUDIT-2026-07.md (100%) rename AUDIT-2026-08-CODEX.md => Docs/archive/AUDIT-2026-08-CODEX.md (100%) rename AUDIT-COLD-2026-09-14.md => Docs/archive/AUDIT-COLD-2026-09-14.md (100%) rename AUDIT-SOL-2026-09-11.md => Docs/archive/AUDIT-SOL-2026-09-11.md (100%) rename CODEX-TASK-001-tile-skip-stats.md => Docs/archive/CODEX-TASK-001-tile-skip-stats.md (100%) rename CODEX-TASK-002-column-memo-thrash.md => Docs/archive/CODEX-TASK-002-column-memo-thrash.md (100%) rename CODEX-TASK-003-extrareach-perlin-bound.md => Docs/archive/CODEX-TASK-003-extrareach-perlin-bound.md (100%) rename CODEX-TASK-004-minmax-radius-envelope.md => Docs/archive/CODEX-TASK-004-minmax-radius-envelope.md (100%) rename CODEX-TASK-005-tile-scan-sampler-extent.md => Docs/archive/CODEX-TASK-005-tile-scan-sampler-extent.md (100%) rename CODEX-TASK-006-cave-morphology-radius-envelope.md => Docs/archive/CODEX-TASK-006-cave-morphology-radius-envelope.md (100%) rename CODEX-TASK-007-generation-pause.md => Docs/archive/CODEX-TASK-007-generation-pause.md (100%) rename CODEX-TASK-008-column-memo-and-t1d-diagnosis.md => Docs/archive/CODEX-TASK-008-column-memo-and-t1d-diagnosis.md (100%) rename CODEX-TASK-1-PROFILER-BATCH-RESEARCH.md => Docs/archive/CODEX-TASK-1-PROFILER-BATCH-RESEARCH.md (100%) rename CODEX-TASK-2-PERF-REPORT.md => Docs/archive/CODEX-TASK-2-PERF-REPORT.md (100%) rename DESIGN-SOL-2026-09-15-CODE.md => Docs/archive/DESIGN-SOL-2026-09-15-CODE.md (100%) rename DESIGN-SOL-2026-09-15.md => Docs/archive/DESIGN-SOL-2026-09-15.md (100%) rename INVESTIGATION-2026-08-SOL.md => Docs/archive/INVESTIGATION-2026-08-SOL.md (100%) rename OPSTACK-DECOMPOSITION.md => Docs/archive/OPSTACK-DECOMPOSITION.md (100%) rename OPSTACK-HANDOFF.md => Docs/archive/OPSTACK-HANDOFF.md (100%) rename OPSTACK-PLAN.md => Docs/archive/OPSTACK-PLAN.md (100%) rename OPSTACK-PROGRESS.md => Docs/archive/OPSTACK-PROGRESS.md (100%) rename OPSTACK-PROMPT.md => Docs/archive/OPSTACK-PROMPT.md (100%) rename PERF-ATTRIBUTION.md => Docs/archive/PERF-ATTRIBUTION.md (100%) rename PERF-SAMPLED.md => Docs/archive/PERF-SAMPLED.md (100%) rename WORK-NEXT.md => Docs/archive/WORK-NEXT.md (100%) delete mode 100644 Tools/__pycache__/AnalyzeVoxelForgePerfProbes.cpython-312.pyc diff --git a/.gitignore b/.gitignore index 782bb75..4c5a6e0 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,13 @@ # The guarded single-entry test harness is source, not generated output. !/Tools/ !/Tools/** +/Tools/**/__pycache__/ + +# Closed / historical documents. +!/Docs/ +!/Docs/** !VoxelForge.uplugin -# Keep every design / doc markdown at any depth (AUDIT P1 — these were untracked) +# Keep every design / doc markdown at any depth !*.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 4eca0ae..490607e 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -130,7 +130,7 @@ in §10. ⚠️ **The `switch` above is no longer the only density path.** All 8 archetypes also exist as **operator stacks**, selected per strate by `bUseOperatorStack` and evaluated instead of the `switch`; each is bit-identical to the function in -its row. The design lives in `OPSTACK-PLAN.md` / `OPSTACK-DECOMPOSITION.md`, the symbol index in +its row. The design lives in `Docs/archive/OPSTACK-PLAN.md` / `Docs/archive/OPSTACK-DECOMPOSITION.md`, the symbol index in `CODEMAP §3.2d` — not repeated here. What matters for *this* document: the archetype table describes what the world IS, and both paths compute it. @@ -521,7 +521,7 @@ flat floor. **There is no connector to the origin landing room at `(0,0)`.** The those radial roads after a playtest (`d97373c`, 2026-09-08: they cut straight through everything); room joins are flattened to walkable height instead. A source-fit landing therefore stays local to the room it was fitted into (`GeneratePassages`, the `VF_BuildPassageLanding` calls). -⚠️ Open gap (Sol's code review, `DESIGN-SOL-2026-09-15-CODE.md` §1.3/§2.4): when the footing query +⚠️ Open gap (Sol's code review, `Docs/archive/DESIGN-SOL-2026-09-15-CODE.md` §1.3/§2.4): when the footing query declines, the landing falls back to the historical random reach, and nothing proves that pose joins the walk network. The canonical capability gate covers one scenario, not every seed or mix. Proposed fix, not built: retry deterministically at other candidate spots instead of falling back. @@ -833,7 +833,7 @@ driven by `EditorBrush*` props. = 0; `=1` restores it as an A/B instrument). Measured on the headless game path with nested refinement off, the classifier plus its exact validation cost more than they saved. Mode 0 had ready p95 182 vs 190-195 ms, generation p95 125-127 vs 139-141 ms, and 18% fewer density calls, - with 841/841 tiles triangle-identical (WORK-NEXT.md). Proving a 33³ core uniform costs almost + with 841/841 tiles triangle-identical (Docs/archive/WORK-NEXT.md). Proving a 33³ core uniform costs almost as much as meshing 35³. The history below explains why it existed. Its soundness tests still guard it. - **Trivial-empty tile reject (T1.d) — v2 SHIPPED (2026-07-05); v1 was reverted 2026-06-26.** diff --git a/CODEMAP.md b/CODEMAP.md index 77fafd4..376a740 100644 --- a/CODEMAP.md +++ b/CODEMAP.md @@ -138,7 +138,7 @@ remains `0`, and lateral regions remain gated off. ### 3.2b Density operator stack contract — `Public/VoxelDensityOp.h` (plain C++, no UHT) **Production path behind a per-strate opt-in** — the stack is built/evaluated by `GetDensityAt` for all eight archetypes when `bUseOperatorStack` is enabled, while the legacy `switch` remains the -reference path for opt-out strates. See [OPSTACK-PLAN.md](OPSTACK-PLAN.md) for the decomposition. +reference path for opt-out strates. See [Docs/archive/OPSTACK-PLAN.md](Docs/archive/OPSTACK-PLAN.md) for the decomposition. | Symbol | Notes | |--------|-------| @@ -711,7 +711,7 @@ Bourke). Cube corner/edge layout documented at top (lines 7-37). Rarely needs ed --- ### 3.12 Automation tests — `Private/Tests/` (added 2026-07-27, `#if WITH_DEV_AUTOMATION_TESTS`) -The plugin's first tests (`OPSTACK-PLAN.md` Phase 0.5). Run them from the editor's +The plugin's first tests (`Docs/archive/OPSTACK-PLAN.md` Phase 0.5). Run them from the editor's **Session Frontend → Automation**, filter `VoxelForge`. | File | Test name | What it proves | diff --git a/COMPOSER-NOTES.md b/COMPOSER-NOTES.md index 0f84e3f..714360e 100644 --- a/COMPOSER-NOTES.md +++ b/COMPOSER-NOTES.md @@ -36,7 +36,7 @@ composer fills in; nobody opens it in the editor any more. ### This is op-stack "Phase 3", and it is REOPENED -The 2026-08-16 `OPSTACK-HANDOFF.md` says in bold *"Do not start Phase 3."* **That is superseded.** +The 2026-08-16 `Docs/archive/OPSTACK-HANDOFF.md` says in bold *"Do not start Phase 3."* **That is superseded.** Asked what the world was missing, Jahni described exactly Phase 3 plus a composer above it. It is **not** a restart of the refactor. The eight operators are live, composable, and production. What @@ -1490,7 +1490,7 @@ roughness and should stay late in the stack. Kept because each cost real time or would otherwise be repeated. -- ⛔ **"Do not start Phase 3" is SUPERSEDED.** `OPSTACK-HANDOFF.md` still says it; believe this file. +- ⛔ **"Do not start Phase 3" is SUPERSEDED.** `Docs/archive/OPSTACK-HANDOFF.md` still says it; believe this file. - ⛔ **Jahni does not want to author strates either.** The composer must invent them. An earlier reading had him authoring strates while the system arranged them — one level too shallow, and it shaped a whole afternoon of wrong design. @@ -1553,7 +1553,7 @@ build succeeded (14 actions). The full headless suite reported **22 succeeded, 0 determinism, box-verdict, and connectivity checks stayed green. The 4b→4h fuse was deliberately not applied after the intervening-channel audit above. -**⭐ This closes the pending-verification thread opened by `OPSTACK-HANDOFF.md`.** That file flagged +**⭐ This closes the pending-verification thread opened by `Docs/archive/OPSTACK-HANDOFF.md`.** That file flagged commits `4d33321` (Sol's boundary fold) and `91585ea` as *built but NOT re-verified*, with two acceptance conditions. Both now met: - **`violations` = 0** everywhere. Measured: TunnelNetwork at production defaults **12 of 40 tiles diff --git a/AUDIT-2026-07.md b/Docs/archive/AUDIT-2026-07.md similarity index 100% rename from AUDIT-2026-07.md rename to Docs/archive/AUDIT-2026-07.md diff --git a/AUDIT-2026-08-CODEX.md b/Docs/archive/AUDIT-2026-08-CODEX.md similarity index 100% rename from AUDIT-2026-08-CODEX.md rename to Docs/archive/AUDIT-2026-08-CODEX.md diff --git a/AUDIT-COLD-2026-09-14.md b/Docs/archive/AUDIT-COLD-2026-09-14.md similarity index 100% rename from AUDIT-COLD-2026-09-14.md rename to Docs/archive/AUDIT-COLD-2026-09-14.md diff --git a/AUDIT-SOL-2026-09-11.md b/Docs/archive/AUDIT-SOL-2026-09-11.md similarity index 100% rename from AUDIT-SOL-2026-09-11.md rename to Docs/archive/AUDIT-SOL-2026-09-11.md diff --git a/CODEX-TASK-001-tile-skip-stats.md b/Docs/archive/CODEX-TASK-001-tile-skip-stats.md similarity index 100% rename from CODEX-TASK-001-tile-skip-stats.md rename to Docs/archive/CODEX-TASK-001-tile-skip-stats.md diff --git a/CODEX-TASK-002-column-memo-thrash.md b/Docs/archive/CODEX-TASK-002-column-memo-thrash.md similarity index 100% rename from CODEX-TASK-002-column-memo-thrash.md rename to Docs/archive/CODEX-TASK-002-column-memo-thrash.md diff --git a/CODEX-TASK-003-extrareach-perlin-bound.md b/Docs/archive/CODEX-TASK-003-extrareach-perlin-bound.md similarity index 100% rename from CODEX-TASK-003-extrareach-perlin-bound.md rename to Docs/archive/CODEX-TASK-003-extrareach-perlin-bound.md diff --git a/CODEX-TASK-004-minmax-radius-envelope.md b/Docs/archive/CODEX-TASK-004-minmax-radius-envelope.md similarity index 100% rename from CODEX-TASK-004-minmax-radius-envelope.md rename to Docs/archive/CODEX-TASK-004-minmax-radius-envelope.md diff --git a/CODEX-TASK-005-tile-scan-sampler-extent.md b/Docs/archive/CODEX-TASK-005-tile-scan-sampler-extent.md similarity index 100% rename from CODEX-TASK-005-tile-scan-sampler-extent.md rename to Docs/archive/CODEX-TASK-005-tile-scan-sampler-extent.md diff --git a/CODEX-TASK-006-cave-morphology-radius-envelope.md b/Docs/archive/CODEX-TASK-006-cave-morphology-radius-envelope.md similarity index 100% rename from CODEX-TASK-006-cave-morphology-radius-envelope.md rename to Docs/archive/CODEX-TASK-006-cave-morphology-radius-envelope.md diff --git a/CODEX-TASK-007-generation-pause.md b/Docs/archive/CODEX-TASK-007-generation-pause.md similarity index 100% rename from CODEX-TASK-007-generation-pause.md rename to Docs/archive/CODEX-TASK-007-generation-pause.md diff --git a/CODEX-TASK-008-column-memo-and-t1d-diagnosis.md b/Docs/archive/CODEX-TASK-008-column-memo-and-t1d-diagnosis.md similarity index 100% rename from CODEX-TASK-008-column-memo-and-t1d-diagnosis.md rename to Docs/archive/CODEX-TASK-008-column-memo-and-t1d-diagnosis.md diff --git a/CODEX-TASK-1-PROFILER-BATCH-RESEARCH.md b/Docs/archive/CODEX-TASK-1-PROFILER-BATCH-RESEARCH.md similarity index 100% rename from CODEX-TASK-1-PROFILER-BATCH-RESEARCH.md rename to Docs/archive/CODEX-TASK-1-PROFILER-BATCH-RESEARCH.md diff --git a/CODEX-TASK-2-PERF-REPORT.md b/Docs/archive/CODEX-TASK-2-PERF-REPORT.md similarity index 100% rename from CODEX-TASK-2-PERF-REPORT.md rename to Docs/archive/CODEX-TASK-2-PERF-REPORT.md diff --git a/DESIGN-SOL-2026-09-15-CODE.md b/Docs/archive/DESIGN-SOL-2026-09-15-CODE.md similarity index 100% rename from DESIGN-SOL-2026-09-15-CODE.md rename to Docs/archive/DESIGN-SOL-2026-09-15-CODE.md diff --git a/DESIGN-SOL-2026-09-15.md b/Docs/archive/DESIGN-SOL-2026-09-15.md similarity index 100% rename from DESIGN-SOL-2026-09-15.md rename to Docs/archive/DESIGN-SOL-2026-09-15.md diff --git a/INVESTIGATION-2026-08-SOL.md b/Docs/archive/INVESTIGATION-2026-08-SOL.md similarity index 100% rename from INVESTIGATION-2026-08-SOL.md rename to Docs/archive/INVESTIGATION-2026-08-SOL.md diff --git a/OPSTACK-DECOMPOSITION.md b/Docs/archive/OPSTACK-DECOMPOSITION.md similarity index 100% rename from OPSTACK-DECOMPOSITION.md rename to Docs/archive/OPSTACK-DECOMPOSITION.md diff --git a/OPSTACK-HANDOFF.md b/Docs/archive/OPSTACK-HANDOFF.md similarity index 100% rename from OPSTACK-HANDOFF.md rename to Docs/archive/OPSTACK-HANDOFF.md diff --git a/OPSTACK-PLAN.md b/Docs/archive/OPSTACK-PLAN.md similarity index 100% rename from OPSTACK-PLAN.md rename to Docs/archive/OPSTACK-PLAN.md diff --git a/OPSTACK-PROGRESS.md b/Docs/archive/OPSTACK-PROGRESS.md similarity index 100% rename from OPSTACK-PROGRESS.md rename to Docs/archive/OPSTACK-PROGRESS.md diff --git a/OPSTACK-PROMPT.md b/Docs/archive/OPSTACK-PROMPT.md similarity index 100% rename from OPSTACK-PROMPT.md rename to Docs/archive/OPSTACK-PROMPT.md diff --git a/PERF-ATTRIBUTION.md b/Docs/archive/PERF-ATTRIBUTION.md similarity index 100% rename from PERF-ATTRIBUTION.md rename to Docs/archive/PERF-ATTRIBUTION.md diff --git a/PERF-SAMPLED.md b/Docs/archive/PERF-SAMPLED.md similarity index 100% rename from PERF-SAMPLED.md rename to Docs/archive/PERF-SAMPLED.md diff --git a/WORK-NEXT.md b/Docs/archive/WORK-NEXT.md similarity index 100% rename from WORK-NEXT.md rename to Docs/archive/WORK-NEXT.md diff --git a/Source/VoxelForge/Public/VoxelDensityOp.h b/Source/VoxelForge/Public/VoxelDensityOp.h index 9d06bc9..33b0975 100644 --- a/Source/VoxelForge/Public/VoxelDensityOp.h +++ b/Source/VoxelForge/Public/VoxelDensityOp.h @@ -1,6 +1,6 @@ // VoxelDensityOp.h // LE CONTRAT de la pile d'opérateurs de densité / THE density operator stack CONTRACT. -// Phase 1 de OPSTACK-PLAN.md. The contract is implemented by the opt-in stack path in +// Phase 1 de Docs/archive/OPSTACK-PLAN.md. The contract is implemented by the opt-in stack path in // UVoxelGenerator::GetDensityAt; the legacy archetype switch remains for non-opt-in strates. // // ───────────────────────────────────────────────────────────────────────────────────────── diff --git a/Source/VoxelForge/Public/VoxelStrateDefinition.h b/Source/VoxelForge/Public/VoxelStrateDefinition.h index 8c98433..26c7d1c 100644 --- a/Source/VoxelForge/Public/VoxelStrateDefinition.h +++ b/Source/VoxelForge/Public/VoxelStrateDefinition.h @@ -128,7 +128,7 @@ public: * * ⚠️ Do NOT flip this on a strate mid-session and expect the old and new geometry to agree to * the bit — they differ by ~1-2 ULP with ZERO isosurface crossings, so the shape is identical - * but the floats are not (`AUDIT-2026-07.md §C10`). Regenerate the world after changing it + * but the floats are not (`Docs/archive/AUDIT-2026-07.md §C10`). Regenerate the world after changing it * rather than letting old and new tiles sit side by side. * * Pile d'opérateurs (expérimental) : génère cette strate via la pile composable au lieu du diff --git a/Source/VoxelForge/VoxelForge.Build.cs b/Source/VoxelForge/VoxelForge.Build.cs index ede695e..bf83ca7 100644 --- a/Source/VoxelForge/VoxelForge.Build.cs +++ b/Source/VoxelForge/VoxelForge.Build.cs @@ -26,7 +26,7 @@ public class VoxelForge : ModuleRules // // Precise resolves to "/fp:precise" on MSVC and "-ffp-contract=off" on Clang — both // IEEE-754 compliant with no FMA contraction, so the two toolchains agree BY CONSTRUCTION - // rather than by luck. That is the fix for AUDIT-2026-07.md C9. + // rather than by luck. That is the fix for Docs/archive/AUDIT-2026-07.md C9. // // COST: /fp:precise forbids the reassociation and contraction /fp:fast allowed, on a // noise-heavy hot path. Expect a measurable perf regression and check it against diff --git a/Tools/__pycache__/AnalyzeVoxelForgePerfProbes.cpython-312.pyc b/Tools/__pycache__/AnalyzeVoxelForgePerfProbes.cpython-312.pyc deleted file mode 100644 index b967c3c84f1bc042052e3dc21c5869714d220e93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26900 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