docs: handoff for the VTank-class plugin automation milestone
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>
This commit is contained in:
parent
c254fea83d
commit
690f21889e
1 changed files with 211 additions and 0 deletions
211
docs/research/2026-08-20-vtank-plugin-milestone-handoff.md
Normal file
211
docs/research/2026-08-20-vtank-plugin-milestone-handoff.md
Normal file
|
|
@ -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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue