The requirements research from 2026-07-29 was nearly lost: it lives in a
session titled "graphics" because it was one strand of a session about
something else, and could not be found again by any search. The research
itself was committed (6077ce4d) and survived; this makes it findable and
usable by a session picking the work up cold.
Contents: reading order, the architectural conclusion not to relitigate
(VTank's meta FSM, expressions and loot engine are plugin-land, not
host-land; the K2 headless triad is already the right substrate), the
five dependency-ordered steps, every relevant file path, and the project
rules that bind the work.
Two things the handoff adds beyond relaying the research. First, a
changed-since section: three of the research's "gap" rows have closed —
vendor landed 2026-08-08, fellowship 2026-08-12, secure trade 2026-08-14 —
so step 4's substrate is materially stronger than when the plan was
written, and §3's gap table is the part that has aged. Second, every path
is verified against the live tree as of today rather than copied forward:
WorldEntitySnapshot is still exactly four fields, IPluginHost is unchanged,
there is still no enchantment-enumerating view and no point-goal movement
primitive, and IHeadlessBotPolicy is internal to AcDream.Headless so step 1
mirrors its shape rather than re-exporting the type.
All 30 path references were checked programmatically. Also records that
claude-memory/ is a junction that resolves in the main checkout but not
inside a worktree, which would otherwise read as a broken pointer.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
11 KiB
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 |
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 |
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, andgit ls-files claude-memory/returns nothing. The files really live underC:\Users\erikn\.claude\projects\C--Users-erikn-source-repos-acdream\memory\. If you are working in a worktree and aclaude-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)
- Plugin↔Runtime bridge — the enabler, gates everything else. Mirror the
K2 triad into BCL-only
Plugin.Abstractions: per-pluginTick(view, commands), generation-gated command groups, ordered event observer. This upgrades plugins to headless-bot parity. - 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.
- Spell/enchantment surface. Enumerable active enchantments (spell id, layer, seconds remaining), can-cast prediction, explicit cast-on-target, cast-outcome events.
- 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.
- 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:
WorldEntitySnapshotis still exactly four fields —(uint Id, uint SourceId, Vector3 Position, Quaternion Rotation). The step-2 gap is real and unchanged.IPluginHoststill 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
AcDream.Plugin.Abstractionsis BCL-only. No App namespaces, no Runtime types leaking through, no third-party packages. Plugin gameplay UI goes throughIUiRegistry.AddMarkupPaneland nothing else. This is what keeps plugins insulated from presentation churn — see CLAUDE.md rule 3.- 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. - 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, thensuperpowers:writing-plans. - 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.
- No workarounds without explicit approval, and any retail deviation
introduced gets its row in
docs/architecture/retail-divergence-register.mdin 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", branchclaude/git-sync-status-5fb1d2, worktreepeaceful-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.afmetaf scripts) andlocal_19297181(dereth-workspace— code consumingILootRuleProcessor/ 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.