diff --git a/docs/research/2026-08-20-vtank-plugin-milestone-handoff.md b/docs/research/2026-08-20-vtank-plugin-milestone-handoff.md new file mode 100644 index 00000000..358a3c57 --- /dev/null +++ b/docs/research/2026-08-20-vtank-plugin-milestone-handoff.md @@ -0,0 +1,211 @@ +# 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.