fix(vt): F host-composed VtankProfiles storage replaces raw path string
Item F (slice-1 fix round). IPluginHost.VtankProfileDirectory handed the plugin a raw string path and told it to fall back to its own System.IO-based portable default when null — a plugin reading and resolving filesystem paths itself, which is exactly the seam the rest of IPluginHost.Storage deliberately avoids (Core.Plugins.ScopedPluginHost scopes/validates every key; the plugin never sees a path). - IPluginHost: VtankProfileDirectory (string?) deleted; new VtankProfiles (IPluginStorage, defaults to NoOpPluginStorage) added — a second, UNSCOPED storage instance (unlike Storage, which Core scopes per plugin manifest id) rooted at a host-composed VTank-compatible directory. - ScopedPluginHost.VtankProfiles forwards _inner.VtankProfiles directly (no scoping — it names one shared external location, not per-plugin data). New PluginSessionTests.ScopedHostForwardsVtankProfilesUnscoped proves the forwarded instance is the exact same object (Assert.Same), not a wrapper. - AppPluginHost/Program.cs: new vtankProfiles constructor parameter, composed as FilePluginStorage(runtimeOptions.VtankProfileDirectoryOverride ?? Path.Combine(applicationPaths.DataDirectory, "vtank")). - RuntimeOptions.VtankProfileDirectoryOverride: new init-only property parsed from ACDREAM_VTANK_PROFILE_DIR (row added to docs/launch-options.md, side-effects column states the redirect is the only effect and documents the NullIfEmpty whitespace-not-special-cased quirk it shares with every other path-override flag). New RuntimeOptionsTests.VtankProfileDirectoryOverrideIsNullUnlessSet. - FilePluginStorage.List(prefix): empty prefix now means "the storage root itself" instead of throwing (Resolve() rejects empty/whitespace keys, which is correct for every OTHER caller but wrong for "list everything" — VtankProfileDirectory needs exactly that). - Headless: HeadlessPluginHost gained the same VtankProfiles property/constructor param, threaded through HeadlessPluginSession.Create -> HeadlessSessionHost -> HeadlessProcessHost, composed from the new HeadlessPathSet.VtankProfilesDirectory (<DataDirectory>/vtank, no ACDREAM_VTANK_PROFILE_DIR-equivalent override — Headless path overrides are HeadlessPathOverrides/CLI flags, not env vars). A small AcDream.Headless.Plugins.FilePluginStorage duplicates the App implementation byte-for-byte (Headless does not reference AcDream.App and no shared "platform plugins" library exists yet to host one copy; documented as a reasonable future consolidation, not required here). - VtankProfileDirectory.cs rewritten: Resolve/PortableDefault deleted outright (no more System.IO, no plugin-owned portable-default fallback); ListSettingsProfiles/ListNavigationProfiles/ListMetaProfiles now take IPluginStorage and enumerate through EnumerateFileNames, which calls storage.List(string.Empty) and skips any key containing '/' (VTank's profile directory is flat; a nested key from some other IPluginStorage implementation is not a profile file). VtankProfileDirectoryTests rewritten against an in-memory IPluginStorage fake instead of real temp directories; new NestedPathKeysAreNotTreatedAsProfileFiles pins that skip. The prior Resolve/PortableDefault-specific tests (Linux-path guarantee, host-override-vs-portable-default) are superseded by RuntimeOptionsTests.VtankProfileDirectoryOverrideIsNullUnlessSet plus the RuntimeOptions.FromEnvironment Path.Combine-only composition in Program.cs. - docs/architecture/acdream-architecture.md: one sentence in the Storage/List(prefix) paragraph naming VtankProfiles as the second, unscoped storage. No production caller of VtankProfileDirectory's listing methods exists yet (A2's foundation is not wired into MossTankProfileStore/ MossTankMetaProfileStore/MossTankRouteProfileStore's own selection — per that slice's own ledger note), so this is a contract + plumbing change with no MossTank runtime behavior change. MossTank suite: 562/562. Core.Tests (Plugin filter): 50/50. App.Tests (Plugin|LaunchOptions|RuntimeOptions filter): 135/135. Headless.Tests: 173/174 (the one failure, HeadlessCredentialResolverTests. LinuxRejectsGroupOrOtherCredentialPermissions, is a pre-existing Linux-only lane gate that throws PlatformNotSupportedException on this Windows host — unrelated to this change). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
8de69b9741
commit
2040f2bcfb
18 changed files with 318 additions and 164 deletions
|
|
@ -238,6 +238,7 @@ $env:ACDREAM_FRAME_HISTORY = "$scratch\frames.csv"
|
|||
| `ACDREAM_VULKAN_FORCE_UNSUPPORTED` | `=<feature-name>` (case-insensitive property name, e.g. `MultiDrawIndirect`) | Test knob (Slice V5): clears one named required Vulkan feature from the capability record to synthetically fail the gate, so the `NotSupportedException` → exit-code-4 → report path can be exercised on hardware that actually supports everything. | Deliberately breaks Vulkan startup when set to a matched feature name — this is a "make it fail on purpose" gate-testing flag, never appropriate for a normal or measurement run. | `null` → real capabilities used unmodified | `RuntimeOptions.VulkanForcedUnsupportedFeature` → `VulkanCapabilityRecord.Without` (`VulkanCapabilityRecord.cs:113-119`), consumed at `VulkanGraphicsContext.cs:339` |
|
||||
| `ACDREAM_VULKAN_PROBE` | `=1` | Runs the standalone Vulkan capability-probe/bring-up harness (opens its own window, runs the capability gate, presents synthetic V6c/V6d verification scenes, captures one screenshot) **instead of** the real client composition host, then exits. | This flag ALONE gates entry (`GameWindow.cs:828`); the former `ACDREAM_RENDER_BACKEND=vulkan` co-requisite died with the OpenGL backend (its class doc was corrected 2026-08-24). | `false` → normal composition host | `RuntimeOptions.VulkanCapabilityProbe` → `GameWindow.cs:828` → `VulkanBringUpHost` |
|
||||
| `ACDREAM_VULKAN_PROBE_FRAMES` | `=<int>` (non-negative) | Bounds the bring-up probe harness to N presented frames so it can run unattended in CI, instead of presenting until a human closes the window. | The frame budget never cuts a pending screenshot capture short — the loop stays open until the screenshot has been attempted even past the budget, so an unattended run's whole product (a PNG) is guaranteed. Zero (unset/unparseable/explicit `0`) keeps the interactive wait-for-close behavior. | `0` → interactive (wait for window close) | `RuntimeOptions.VulkanCapabilityProbeFrames` → `VulkanBringUpHost.cs:141-249` |
|
||||
| `ACDREAM_VTANK_PROFILE_DIR` | `=<path>` | Overrides the directory `IPluginHost.VtankProfiles` (a VTank-compatible plugin's real `.usd`/`.ast`/`.af` profile storage — see `AcDream.Plugins.MossTank.VtankProfileDirectory`) is rooted at, composed as a `FilePluginStorage`. Set it to a real installed VTank's own profile folder (e.g. `C:\Games\VirindiPlugins\VirindiTank`) for direct interop. | Redirects only that one plugin-storage root; no other startup behavior changes. An unset/empty-string value is treated as "no override" (`NullIfEmpty`); whitespace-only is NOT special-cased (matches every other `NullIfEmpty`-read flag, e.g. `ACDREAM_AC_DIR`/`ACDREAM_UI_PROBE_SCRIPT`) and would be used as a literal (almost certainly invalid) root. | unset → `<ApplicationPathSet.DataDirectory>/vtank` | `RuntimeOptions.VtankProfileDirectoryOverride` → `Program.cs` (composes `AppPluginHost`'s `vtankProfiles` argument). The Headless host has no equivalent override (its path overrides are `HeadlessPathOverrides`, not env vars) and always uses `HeadlessPathSet.VtankProfilesDirectory` (`<DataDirectory>/vtank`). |
|
||||
| `ACDREAM_DUMP_MOVE_TRUTH` | `=1` | Emits one `move-truth OUT` line per outbound movement record (MoveToState / AutonomousPosition): local resolved position vs the wire position/cell, ground contact, velocity (`MovementTruthDiagnosticController`). | **Automation apparatus, NOT a spent probe** — the canonical nine-stop soak (`tools/run-connected-r6-soak.ps1`) hard-gates on ≥2 of these lines per destination as its proof that production input produced outbound movement traffic; deleting it fails the soak at every stop (#437, deleted-and-restored 2026-08-24). Print volume follows the outbound send cadence. | off | `RuntimeOptions.DumpMoveTruth` → `GameWindow.cs` → `MovementTruthDiagnosticController` |
|
||||
|
||||
## Permanent diagnostics
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue