Phase J (2026-08-03) bumped lib-core.composition 0.3.0->0.4.0 and
lib-core.crafting 0.3.0->0.5.0, but only vagrant-skeleton and
lib-core.crafting themselves were updated. Dependent manifests kept the
old pins, so dep-fetcher saw disagreeing pins on the same lib and
refused to start both spine-prototype (ENGINE_ERR_LIB_DEP_MISSING,
rc=19) and vagrant-skeleton ("dep check failed", conflict on
lib-core.composition + lib-core.crafting).
Unify all pins on the on-disk versions. No code changes required:
composition 0.4.0 is purely additive (the quality/condition loud-error
was removed; no signature changed), and crafting-display only consumes
crafting.can_craft + crafting.list_recipes, both still present, and
never referenced the `form` field retired by ADR-0055.
README "Requires:" lines synced to match the manifests (Gate 3).
milestone-check.sh: GREEN (build, ctest, smoke, devwrap-ci,
test-all-modules + anomaly scan). vagrant-skeleton headless run clean
at 60 CI frames.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lib-core.inventory-list
List-container inventory over the engine.entity tree. Attaches items
as synthetic children under slot names item.1, item.2, ... and
manages the composition tag-index so items are hidden from the renderable
index while inside a container.
Version: 0.1.0 Lib-ID: lib-core.inventory-list Requires: lib-core.composition 0.4.0 Tags: inventory, entity, composition, list-container
Topology
graph LR
this["lib-core.inventory-list"]
comp["lib-core.composition"]
engine["engine.*"]
this --> comp
this --> engine
Scope (v0.1.0)
Thin list-container inventory spine. Items must be stack_mode="individual".
No weight, volume, or grid constraints (Phase F/G). No stackable items (Phase C+).
Supported:
add(container, item)— attach item to container under synthetic slotremove(container, item)— detach item, return itcontents(container)— ordered list of items currently in containercontains(container, item)— membership checkcount(container)— number of items
Deferred (Loud-Error or not applicable):
- Stack items (
stack_mode != "individual") → Loud-Error in v0.1 - Capacity / weight / volume constraints → Phase F/G
addLoud-Errort, wenn das Container-Template ein Phase-F/G-Constraint-Feld deklariert (weight_max/volume_max/grid/accepts_fluid/accepts_gas/restrictions)
API
inventory.add(container, item)
Syntax: inventory.add(container: entity, item: entity) -> void
Example:
local inventory = require("lib-core.inventory-list")
inventory.add(backpack, sword)
-- sword is now a child of backpack under "item.1"
-- sword is removed from the renderable index
Description: Validates that container is a composition-entity with
container={kind="list"} (Loud-Error if not). Validates item has
stack_mode property (Loud-Error if missing) and stack_mode == "individual"
(Loud-Error otherwise). Detaches item from its current parent if any,
attaches to container under the next synthetic slot (item.<n>), and
calls composition.set_tag(item, "renderable", false) to remove the item
from the renderable index.
inventory.remove(container, item) -> item
Syntax: inventory.remove(container: entity, item: entity) -> entity
Example:
local dropped = inventory.remove(backpack, sword)
-- sword detached from backpack; renderable tag restored
-- caller re-parents dropped into world + sets position
Description: Finds item in container's children (Loud-Error if not
present), detaches it via entity.detach, calls
composition.set_tag(item, "renderable", true), returns item.
inventory.contents(container) -> {item, ...}
Syntax: inventory.contents(container: entity) -> {entity, ...}
Example:
for _, it in ipairs(inventory.contents(backpack)) do
print(it:get_property("name"))
end
Description: Returns all items currently in container, ordered by
insertion order (numeric suffix of synthetic slot names). Filters children
by the item-recognition rule: child must have a stack_mode property.
Non-item children (future use) are silently excluded.
inventory.contains(container, item) -> bool
Syntax: inventory.contains(container: entity, item: entity) -> bool
Example:
local has_rock = inventory.contains(backpack, rock)
Description: Returns true if item is currently a child of
container under a synthetic slot.
inventory.count(container) -> number
Syntax: inventory.count(container: entity) -> number
Example:
local n = inventory.count(backpack)
Description: Returns the number of items currently in container.
Equivalent to #inventory.contents(container).
Notes
Synthetic Slot Naming
Items are stored under slot names item.<n> where n is a
monotonically-increasing integer per container. The counter is not
persisted — on any cold call next_slot scans existing children for
item.<n> patterns and takes max(n) + 1. This makes slot naming
reconstruction-safe after engine reload without any additional state.
Item-Recognition Rule
An entity is recognized as an item if it has a stack_mode property
(any non-nil, non-empty string value). The stack_mode must be
"individual" for add to succeed in v0.1. This rule is consistent
with the template convention for item templates (declaring stack_mode
in their properties block).
set_tag Interaction
add calls composition.set_tag(item, "renderable", false), which
removes the item from lib-core.composition's list_by_tag("renderable")
index. remove calls set_tag(item, "renderable", true) to restore it.
This ensures items in inventory are invisible to the render system without
any per-frame filtering.