# Provenance Data Model and Query Patterns

Reference material for `search_provenance`. Consult this page when you need to interpret raw provenance text, understand the data model, or construct specialised query patterns.

## Provenance Text Format (AAM Standard)

The Rijksmuseum's provenance text follows the AAM (American Alliance of Museums) standard for provenance notation:

- Semicolon-delimited events: each ownership change is separated by `;` — `Owner A, City, date; Owner B, City, date`
- Chronological order: earliest known owner first, current holder last
- Bare names = ownership: a name without a transfer keyword (e.g. `Pieter Six (1618–1707), Amsterdam`) indicates an ownership period — classified as `collection`
- Ellipsis = gap: `…` or `...` marks a gap in the documented chain
- Curly braces = citations: `{Bredius 1935, p. 47}` are bibliographic references, not provenance events
- Question mark = uncertainty: `? sale, Amsterdam, 1804` — the transfer or attribution is uncertain
- Cross-references: `(see also SK-A-3137)` links to pendant or companion works that share provenance
- Life dates: `Name (1650–1720)` — dates in parentheses after a name are birth–death years, not event dates

The Rijksmuseum extends the AAM standard with Dutch-language keywords (`schenking` = gift, `bruikleen` = loan, `verwerving` = acquisition, `aangekocht` = purchased) and institutional conventions (`Inv.` = inventory reference, `L.` = Lugt collector mark number).

## Transfer Types (CMOA/PLOD-aligned Vocabulary)

Transfer types follow the CMOA Art Tracks thesaurus (Carnegie Museum of Art), aligned with the PLOD framework (Art Institute of Chicago).

Type | Category | Description
--- | --- | ---
`sale` | ownership | Sale, purchase, or auction (includes "purchased by", "acquired from"). Includes unsold lots — check `unsold` flag.
`by_descent` | ownership | Inheritance to a named relative (son, daughter, nephew, heir, etc.)
`widowhood` | ownership | Inheritance specifically to a widow or widower
`inheritance` | ownership | Generic inheritance (no specific relationship identified)
`bequest` | ownership | Testamentary gift
`gift` | ownership | Donation, gift, or presentation
`commission` | ownership | Commissioned creation
`exchange` | ownership | Exchange or swap
`confiscation` | ownership | Seized by authority
`theft` | ownership | Stolen
`looting` | ownership | Looted (wartime)
`recuperation` | ownership | Recovered by Allied forces (post-WWII, distinct from restitution)
`restitution` | ownership | Legally returned to original owner
`collection` | ownership | Bare-name ownership period (AAM convention — no transfer keyword)
`inventory` | ownership | Documented in an estate inventory or attestation
`loan` | custody | On loan (temporary custody, no ownership change)
`deposit` | custody | On deposit or in storage
`transfer` | ambiguous | Administrative or intra-organisational transfer
`unknown` | ambiguous | Parser could not classify (includes cross-references)

Extensions beyond CMOA: `recuperation` (physical recovery vs legal return), `collection` (AAM bare-name convention), `inventory` (attestation events).

### Event Flags

Flag | On type | Meaning
--- | --- | ---
`unsold: true` | `sale` | Auction lot was unsold, bought in, or withdrawn. No ownership transfer occurred. Filter these when analysing actual sales.
`batchPrice: true` | any with price | The price is an en bloc / batch total for multiple artworks, not an individual price. Always filter these when ranking or comparing prices — they massively distort rankings (e.g. fl. 6,350,000 for 393 Mannheimer objects).

Inheritance granularity: use `by_descent` for works inherited by named relatives, `widowhood` for widow/widower inheritance specifically, or `inheritance` for the generic case. To catch all inheritance-related transfers: `transferType: ["by_descent", "widowhood", "inheritance"]`.

## Party Roles and Positions

Each party in a provenance event has a role (what they did) and a position (their side of the transfer):

Role | Position | Context
--- | --- | ---
`buyer` | receiver | Sale events
`seller` | sender | Sale events
`donor` | sender | Gift events
`recipient` | receiver | Gift, transfer, deposit events
`heir` | receiver | Bequest, inheritance events
`lender` | sender | Loan events
`borrower` | receiver | Loan events
`patron` | receiver | Commission events
`collector` | receiver | Collection events
`dealer` / `intermediary` / `auctioneer` | agent | Facilitated without owning

Positions (`sender`/`receiver`/`agent`) are derived from roles via deterministic mapping, with LLM enrichment for ambiguous cases. The `positionMethod` field tracks how each party's position was determined: `role_mapping` (deterministic), `llm_enrichment` (LLM-classified), or `llm_disambiguation` (LLM-resolved merged party text).

Coverage: ~86K parties extracted across ~101K events. Not all events have named parties — bare-name `collection` events and cross-references often lack structured party data.

## Date Representation

Dates use qualified single years with temporal bounds, similar to the EDTF (Extended Date/Time Format) approach:

Expression | `dateYear` | `dateQualifier` | Interpretation
--- | --- | --- | ---
`1808` | 1808 | — | Exact year
`c. 1700` | 1700 | `circa` | Approximate (±10 years in Layer 2)
`before 1800` / `by 1800` | 1800 | `before` | Terminal bound only
`after 1945` | 1945 | `after` | Start bound only
`1560-70` | 1565 | — | Midpoint of range
`possibly 1767` | 1767 | `circa` | Uncertain attribution
`1858 or earlier` | 1858 | `before` | Terminal bound

## Historical Currencies

Prices are stored in their original historical currency — no inflation adjustment or cross-currency conversion is performed. Supported currency values:

`guilders`, `pounds`, `francs`, `livres`, `napoléons`, `guineas`, `belgian_francs`, `deutschmarks`, `reichsmarks`, `swiss_francs`, `euros`, `dollars`, `yen`, `marks`, `louis_d_or`.

Pre-decimal notations (£.s.d, fl. X:Y:-) are converted to decimal equivalents of the base currency unit.

Note on batch prices: en bloc prices (a batch sold together, e.g. the entire Mannheimer collection for fl. 6,350,000) are attributed to every individual item in the batch. These events are flagged with `batchPrice: true` — always filter them out when ranking or comparing prices.

## Enrichment Provenance

Every record carries provenance-of-provenance metadata tracking how it was determined:

- `parseMethod`: how the event was parsed (`peg`, `regex_fallback`, `cross_ref`, `credit_line`)
- `categoryMethod`: how the transfer type/category was determined (`type_mapping` = parser, `llm_enrichment` = LLM, `rule:transfer_is_ownership` = validated rule)
- `positionMethod` (on parties): how the party position was determined (`role_mapping` = parser, `type_mapping` = from transfer type, `llm_enrichment` = LLM, `llm_disambiguation` = LLM-decomposed merged text)
- `enrichmentReasoning`: the LLM's reasoning for any non-deterministic decision

When results contain LLM-enriched records, `search_provenance` provides a URL to an enrichment review page showing the full methodology and reasoning for each decision. Always show this URL to the user.

### Querying by enrichment method

    # Artworks where transfer type was classified by LLM (170 events)
    search_provenance(categoryMethod="llm_enrichment", maxResults=10)

    # Artworks where party position was assigned by LLM
    search_provenance(positionMethod="llm_enrichment", maxResults=10)

    # Artworks where merged party text was decomposed by LLM (204 splits)
    search_provenance(positionMethod="llm_disambiguation", maxResults=10)

For collection-wide distribution of methods:

    collection_stats(dimension="categoryMethod")
    collection_stats(dimension="positionMethod")
    collection_stats(dimension="parseMethod")

## Parse Method Values

The `parseMethod` field records how each provenance record was processed:

Value | Share | Description
--- | --- | ---
`peg` | ~80% | PEG grammar parser — highest confidence
`cross_ref` | ~20% | Cross-reference links
`credit_line` | ~0.1% | Inferred from the museum's credit line field when the provenance chain lacked acquisition information
`regex_fallback` | — | Legacy, currently unused

`credit_line` events are particularly useful: they recover acquisition context (donor name, purchase fund) that the provenance text omits.

## Provenance Facets

`search_provenance` supports `facets: true`, returning 5 facet dimensions alongside chain results:

- transferType: distribution of transfer types in matching events
- decade: temporal distribution of matching events
- location: geographic distribution (city-level, top 20)
- transferCategory: ownership vs custody vs ambiguous
- partyPosition: sender vs receiver vs agent

All entries include `count` and `percentage`.

    # Faceted overview of wartime confiscations
    search_provenance(transferType="confiscation", dateFrom=1933, dateTo=1945, facets=true)

    # Faceted overview of a dealer's activity
    search_provenance(party="Goudstikker", facets=true)

    # Faceted audit of LLM-classified events
    search_provenance(categoryMethod="llm_enrichment", facets=true)

## Tested Query Patterns

### Collector profiling

    # All works associated with a collector across all event types
    search_provenance(party="Mannheimer", maxResults=50)

    # Collector as seller specifically
    search_provenance(party="Goupil", maxResults=20)
    # Then filter results: role="seller" + position="sender" to map direction of trade

    # Ownership durations for a family name
    search_provenance(layer="periods", ownerName="Six",
                      sortBy="duration", sortOrder="desc", maxResults=20)

### Acquisition channel analysis

    # creditLineQuery searches the credit-line field of artworks that have NO parsed provenance
    # Standalone fallback mode: all other filters (type, creator, …) are ignored
    search_provenance(creditLineQuery="Drucker-Fraser")
    search_provenance(creditLineQuery="Vereniging Rembrandt")
    # Matches return in creditLineResults (not results) — unstructured, lower-confidence source

### Wartime provenance

    # Anti-join: confiscated but never restituted
    search_provenance(transferType="confiscation",
                      excludeTransferType="restitution", maxResults=20)

    # Works with documented gaps + events in the wartime period
    search_provenance(hasGap=true, creator="Rembrandt",
                      dateFrom=1933, dateTo=1945, maxResults=20)

    # Recuperation events (Allied recovery, distinct from legal restitution)
    search_provenance(transferType="recuperation", maxResults=20)

### Price and market history

    # Most expensive recorded transactions in guilders
    # Check batchPrice on results — true means en bloc total, not individual price
    search_provenance(hasPrice=true, currency="guilders",
                      sortBy="price", sortOrder="desc", maxResults=20)

    # Price history for a specific work
    search_provenance(objectNumber="SK-A-2344", layer="events")
    # Check unsold flag: unsold lots have prices but no sale occurred

### Multi-generation family collections

    search_provenance(transferType=["by_descent", "widowhood"],
                      layer="periods", minDuration=50,
                      sortBy="duration", sortOrder="desc", maxResults=20)

### Chronological exploration

    # Earliest documented provenance events in the collection
    search_provenance(dateFrom=1400, dateTo=1500, sortBy="dateYear",
                      sortOrder="asc", maxResults=20)

### Decade-level time series

Use `collection_stats` for single-call time series — no manual pagination loop needed:

    # Sale events per decade 1600–1900
    collection_stats(dimension="provenanceDecade", transferType="sale",
                     dateFrom=1600, dateTo=1900)

    # Half-century bins
    collection_stats(dimension="provenanceDecade", transferType="sale",
                     dateFrom=1600, dateTo=1900, binWidth=50)

    # Confiscation events by decade (wartime distribution)
    collection_stats(dimension="provenanceDecade", transferType="confiscation")
    # Reveals 1790s + 1940s bimodal pattern (French Revolution + WWII)