# Handoff — VTank-class plugin automation milestone **Written 2026-08-20 for a fresh session picking this up cold.** You are inheriting a completed requirements-research phase and an unstarted implementation. Nothing has been built yet. The research is thorough and was done at `xhigh` effort against primary sources — **read it before designing anything, and do not re-derive it.** This document tells you where everything is, what has changed since the research was written, and what to do first. --- ## 1. Start here, in this order | # | Path | Why | |---|---|---| | 1 | [`docs/research/2026-07-29-vtank-plugin-automation-requirements.md`](2026-07-29-vtank-plugin-automation-requirements.md) | **The research.** 384 lines. Full VTank capability inventory, the implied host-API surface, mapping to acdream, and the 5-step milestone. | | 2 | [`docs/plans/2026-07-29-post-vulkan-work-intake.md`](../plans/2026-07-29-post-vulkan-work-intake.md) | Where the milestone is filed (C-bucket candidate), line 35. | | 3 | `claude-memory/project_plugin_requirement.md` (see note below) | Why plugins are a day-1 architectural constraint, not a nice-to-have. | | 4 | `CLAUDE.md` § "Code Structure Rules" rule 3, and § "UI strategy" | The binding constraints on this work (see §6 below). | Rows 1–2 are committed to the repo. Paths verified 2026-08-20. > **`claude-memory/` is a junction, not tracked content.** It resolves in the > main checkout (`C:\Users\erikn\source\repos\acdream`) but **not inside a git > worktree**, and `git ls-files claude-memory/` returns nothing. The files > really live under > `C:\Users\erikn\.claude\projects\C--Users-erikn-source-repos-acdream\memory\`. > If you are working in a worktree and a `claude-memory/...` path does not > resolve, that is why — read it from the main checkout or the real path. --- ## 2. The architectural conclusion — do not relitigate VTank's meta state machine, expression language and loot-rule engine are **plugin-land, not host-land.** VTank itself was built on Decal's primitives; acdream ships the equivalent primitive layer and a VTank-like engine then becomes an acdream plugin — potentially file-compatible with `.met` / `.nav` / `.utl`, whose encodings the research already decodes. The second conclusion: **the K2 headless-bot triad is already the right substrate.** Synchronous borrowed reads, generation-gated typed commands with attempt semantics, and an ordered delta stream are exactly what a VTank-class engine needs, and VTank's 293 ms meta tick maps cleanly onto `Tick`. So this milestone is largely a bridging and query-surface exercise, not new architecture. --- ## 3. The five steps (dependency-ordered) 1. **Plugin↔Runtime bridge — the enabler, gates everything else.** Mirror the K2 triad into BCL-only `Plugin.Abstractions`: per-plugin `Tick(view, commands)`, generation-gated command groups, ordered event observer. This upgrades plugins to headless-bot parity. 2. **Entity/property query surface.** Names, classification, weenie type, physics position on entity snapshots; query verbs; per-object property bags in the retail key space; ID-request command + ID-arrived event. 3. **Spell/enchantment surface.** Enumerable active enchantments (spell id, layer, seconds remaining), can-cast prediction, explicit cast-on-target, cast-outcome events. 4. **Interaction/transaction commands.** use-by-id, apply-on, give, container take-specific, salvage, vendor buy/sell — over the existing one-transaction gate, with receipts as events. 5. **Nav/move-to layer.** Point-goal movement with arrival/stuck/off-course events plus a server-confirmed-arrival variant, follow-entity, jump. (1) gates all. (2) and (3) are independent once (1) lands. (5) is last and is **the only genuinely new machinery** — everything else is exposure of state that already exists Runtime-side. --- ## 4. What changed since the research was written The research is dated 2026-07-29. Three weeks and several campaigns have landed since, and **three of its "gap" rows have closed**. Verified today: | Research said | Reality on 2026-08-20 | |---|---| | "vendor = M4 Slices 5–6 in flight" | **Landed**, user-accepted 2026-08-08. `RuntimeVendorRangeQuery`, `VendorShopItemMaterializer`. The six-slice world-interaction program is COMPLETE. | | "Fellowship state: not in Runtime views yet" | **Landed.** Campaign FA code-complete 2026-08-12: `RuntimeFellowshipState`, `RuntimeAllegianceState`. | | (not mentioned — postdates it) | Secure trade shipped 2026-08-14: `RuntimeTradeState`. | **Net effect: step 4's substrate is materially stronger than when the plan was written.** Re-read §3 of the research against the live tree before scoping — its gap table is the one part that has aged. Still true, verified today: - `WorldEntitySnapshot` is still exactly four fields — `(uint Id, uint SourceId, Vector3 Position, Quaternion Rotation)`. The step-2 gap is real and unchanged. - `IPluginHost` still exposes only `{ HasUi, Log, State, Events, Selection, Ui }`. - There is **no** enchantment-enumerating view; the state lives in `RuntimeCharacterState` / `GameRuntimeGameplayViews`. - There is **no** point-goal movement primitive. Movement is WASD-intent-shaped. --- ## 5. Every file you will need, verified 2026-08-20 **The plugin API you are extending** (BCL-only — see §6): ``` src/AcDream.Plugin.Abstractions/IPluginHost.cs <- the surface to grow src/AcDream.Plugin.Abstractions/IGameState.cs src/AcDream.Plugin.Abstractions/IEvents.cs src/AcDream.Plugin.Abstractions/ISelectionService.cs src/AcDream.Plugin.Abstractions/IUiRegistry.cs <- AddMarkupPanel; already a better-typed "Meta Views" src/AcDream.Plugin.Abstractions/IAcDreamPlugin.cs src/AcDream.Plugin.Abstractions/IPluginLogger.cs src/AcDream.Plugin.Abstractions/WorldEntitySnapshot.cs <- the 4-field snapshot to enrich ``` **The Runtime surface you are mirroring** (all three interfaces are `public`): ``` src/AcDream.Runtime/GameRuntimeViews.cs :259 public interface IGameRuntimeView src/AcDream.Runtime/GameRuntimeCommands.cs :489 public interface IGameRuntimeCommands src/AcDream.Runtime/GameRuntimeEvents.cs :100 public interface IRuntimeEventObserver src/AcDream.Runtime/GameRuntimeGameplayViews.cs gameplay projections incl. enchantments ``` **The pattern to copy** — note `IHeadlessBotPolicy` is `internal` to `AcDream.Headless`, so you are mirroring the *shape*, not re-exporting the type: ``` src/AcDream.Headless/Policies/HeadlessBotPolicy.cs :8 internal interface IHeadlessBotPolicy :12 void Tick(IGameRuntimeView, IGameRuntimeCommands) ``` **Runtime gameplay state owners** (what step 2–4 will expose): ``` src/AcDream.Runtime/Gameplay/RuntimeCharacterState.cs vitals/skills/spellbook/enchantments src/AcDream.Runtime/Gameplay/RuntimeInventoryState.cs src/AcDream.Runtime/Gameplay/RuntimeActionState.cs selection/combat/cast intent, transaction gate src/AcDream.Runtime/Gameplay/RuntimeFellowshipState.cs (new since research) src/AcDream.Runtime/Gameplay/RuntimeAllegianceState.cs (new since research) src/AcDream.Runtime/Gameplay/RuntimeTradeState.cs (new since research) src/AcDream.Runtime/Gameplay/RuntimeVendorRangeQuery.cs src/AcDream.Runtime/Gameplay/VendorShopItemMaterializer.cs ``` **Plugin loading/hosting**: ``` src/AcDream.Core/Plugins/PluginLoader.cs src/AcDream.Core/Plugins/LoadedPlugin.cs src/AcDream.Core/Plugins/PluginAssemblyLoadContext.cs src/AcDream.Plugins.Smoke/SmokePlugin.cs <- the worked example ``` **Domain background** (read on demand — junction, see the note in §1): ``` claude-memory/project_modern_runtime_architecture.md Slice-J ownership truth claude-memory/project_linux_headless_bots.md Slice K; the BINDING #368 contract claude-memory/project_interaction_pipeline.md use / pickup / appraisal flow ``` --- ## 6. Constraints that bind this work 1. **`AcDream.Plugin.Abstractions` is BCL-only.** No App namespaces, no Runtime types leaking through, no third-party packages. Plugin gameplay UI goes through `IUiRegistry.AddMarkupPanel` and nothing else. This is what keeps plugins insulated from presentation churn — see CLAUDE.md rule 3. 2. **Hosts give Runtime ONE of everything** — the BINDING #368 contract in `claude-memory/project_linux_headless_bots.md`. Read it before adding a second anything. 3. **Every C-bucket item gets a brainstormed spec before code** — the intake doc's own sequencing note, and the roadmap rules in CLAUDE.md. Use `superpowers:brainstorming`, then `superpowers:writing-plans`. 4. **This is not the active milestone.** M4 "Live in the world" is current. This is filed as a post-M4 C-bucket candidate. Confirm with the user that they want it started before doing anything beyond the spec — CLAUDE.md's one-active-milestone rule exists specifically to prevent this kind of drift. 5. **No workarounds without explicit approval**, and any retail deviation introduced gets its row in `docs/architecture/retail-divergence-register.md` in the same commit. --- ## 7. First action Read the research end to end, then re-verify its §3 gap table against the live tree (three rows are already stale — see §4). Then bring the user a brainstormed spec for **step 1 only**. Step 1 gates everything else, it is the smallest coherent slice, and getting the bridge shape wrong is the one mistake that would be expensive to undo. Do not start with the nav layer, however tempting — it is step 5 for a reason. Route automation needs combat and loot reads to decide when to move. --- ## 8. Provenance - Research commit: `6077ce4d` — *"docs: VTank requirements research — the plugin-automation milestone model"*, 2026-07-29, authored Fable 5, `xhigh`. - Originating session: `local_dce33067-349e-45dd-916f-479bfae6cbc6`, titled **"graphics"**, branch `claude/git-sync-status-5fb1d2`, worktree `peaceful-blackburn-5333f0`. The misleading title is why it could not be found by search — the VTank research was one strand of a session about something else entirely. - Related sessions, if the VTank *content* is ever needed rather than the acdream plan: `local_79a15007` (`repos/metas` — authoring VTank `.af` metaf scripts) and `local_19297181` (`dereth-workspace` — code consuming `ILootRuleProcessor` / VirindiTank loot rules). - The research's own source list — Wayback wiki snapshots plus `metaf`, `virindi-public-clone`, `ACE.BaseMod`, `vtank-routes`, `vtank-loot-profiles` — is at the end of the research doc. The live virindi.net wiki is **unreachable** (self-signed TLS; the HTTP wiki returns a database error), so use the Wayback snapshots cited there rather than trying the live site.