5.6 KiB
D&D Item-Event Artifact Contract
This document defines the durable D&D item-event artifact and its production boundaries. It records source-grounded discoveries and possession changes; it does not maintain an inventory or ledger.
Artifact Identity
| Property | Value |
|---|---|
| Extractor key | dnd/item-events |
| Extract capability | dnd.item_events |
| Artifact kind | dnd/item-event-list |
| Schema ID | notarius.dnd.item_events |
| Schema name | notarius_dnd_item_events_v1 |
| Schema version | v1 |
| Media type | application/json |
| Normalizer key | dnd/item-events |
The payload is one strict JSON object containing a required events array,
which may be empty. Objects reject unknown fields.
Event Shape And Categories
Every event has name, kind, and a non-empty source_refs array. quantity
is optional and, when present, is a positive integer. from and to are
optional display values whose presence depends on kind.
| Field | Rule |
|---|---|
name |
Non-empty, transcript-supported display value. |
kind |
One of the categories below. |
quantity |
Optional positive integer; omitted when the source does not establish a count. |
from |
Holder that loses possession when the category permits it. |
to |
Holder that gains possession when the category permits it. |
source_refs |
One or more current-source references. |
| Kind | Meaning and holder rule |
|---|---|
discovered |
The party learns of or encounters an item without established possession; neither holder is present. |
acquired |
A party member or party gains possession; to is required and from is absent. |
lost |
A party member or party ceases to possess an item without consuming it; from is required and to is absent. |
consumed |
Use depletes, expends, or destroys an item; from is required and to is absent. |
transferred |
Possession moves between distinct party members; both holders are required and neither may be party. |
party is the reserved display holder for collective party possession when an
individual holder is not established. Its comparison is case- and
Unicode-insensitive. Transfers require distinct normalized holder values.
Giving an item to an NPC, spending currency, selling an item, or another move
outside party possession is lost, not transferred or consumed. Monetary
spending, purchases, and payments are always lost. Currency is consumed only
when the source explicitly describes its physical destruction or expenditure as
a non-payment component. Ordinary non-depleting use is not an event.
Currency is represented as an ordinary event name plus an explicit quantity when the transcript supplies one. Each denomination remains separate. The artifact never converts denominations, infers a missing count, calculates a balance, or sums nearby events.
Source Evidence And Normalization
Each source reference contains source_id, start_unit_id, and end_unit_id.
It must identify an ordered range in the current source document. During
extraction, every cited range must also be wholly contained in the current
accepted chunk. Campaign references may disambiguate names, but never provide
event evidence.
The deterministic normalizer trims only display-edge whitespace in names and holders, canonicalizes source-reference order and exact duplicate references, then orders events by earliest valid source position and stable tie-breakers over name, kind, holders, quantity, and complete evidence. It removes only events with the same normalized fields and complete valid evidence sequence. Invalid evidence is never collapsed. It does not rename, singularize, resolve aliases, infer holders or quantities, or merge nearby events.
The default extraction validation chain is JSON syntax, item-event shape, source references, durable JSON Schema, then advisory source relatedness. The normalization chain adds normalized invariants after shape validation and before source references and schema validation. Relatedness warnings are advisory so contextual names and currency notation do not reject otherwise valid evidence.
Representative JSON
{
"events": [
{
"name": "Hidden Cache",
"kind": "discovered",
"source_refs": [{"source_id": "session-7", "start_unit_id": 1, "end_unit_id": 1}]
},
{
"name": "Silver Pieces",
"kind": "acquired",
"quantity": 20,
"to": "party",
"source_refs": [{"source_id": "session-7", "start_unit_id": 2, "end_unit_id": 2}]
},
{
"name": "Torch",
"kind": "lost",
"from": "party",
"source_refs": [{"source_id": "session-7", "start_unit_id": 3, "end_unit_id": 3}]
},
{
"name": "Healing Potion",
"kind": "consumed",
"from": "Aria",
"source_refs": [{"source_id": "session-7", "start_unit_id": 4, "end_unit_id": 4}]
},
{
"name": "Moonblade",
"kind": "transferred",
"from": "Aria",
"to": "Borin",
"source_refs": [{"source_id": "session-7", "start_unit_id": 5, "end_unit_id": 5}]
}
]
}
Production Boundary
The extractor requires chunks and source.transcript, and accepts optional
glossary, party, players, and deprecated roster campaign references for
disambiguation only. It has no generated NPC, scene-description, or item-registry
dependency. The append-order merger preserves chunk order, and the normalizer
has no reference slots.
The normalized lane is emitted as lanes/<lane-id>.json by the JSON output
module. See Configuration for
the selectable keys and default chains, and the
JSON output contract for bundle paths.