Files
cnx_vinyl/docs/catalogue-intelligence.md
T
grabowski 3d9bb9af53 Own catalogue in a second company; models self-hosted on premises
Decisions (Alexander, 26 Oct 2026): a second company, not the plant
company, holds the catalogue; it owns and licenses titles; language
models are self-hosted on premises.

catalogue-intelligence.md reworked: the catalogue company is a customer
of the plant at arm's length (orders through intake and portal, the
plant's price list, standby pressing offered to every customer, no
moved dates, no data either way, metal in the archive on customer
terms; Revenue Code section 71 bis, 200M THB disclosure threshold per
the OECD profile), its own ERPNext site, the run-size rule on the
plant's price instead of its direct cost, its own advisor instance on
hardware it controls, phasing, cost borne by it, risks, open decisions
(shareholders and Poy Records, working capital, standby terms, where its
systems run).

Mirrors: README (planning bullet, project status), roadmap item 28,
digital-factory (tool rule, language-model row in the open-source
table), artist-platform (standby pressing proposal, pre-orders),
production-timeline, revenue-model, plant-assistant (self-hosted on
premises; catalogue data removed; advisor as a separate instance).
2026-10-27 09:38:32 +07:00

30 KiB

Own Catalogue: Sales Map, Demand Forecast and Market Advisor

The idea (Alexander, 26 October 2026): with a catalogue of its own to press, sales by shop, region and location can drive a model that says what to press next. That needs three things: a catalogue dashboard with a map of where the records sell, a demand model that turns those sales into press decisions, and an advisor agent that points at market opportunities.

Decided the same day (Alexander):

  • A second company holds the catalogue, not the plant company. It owns titles and licenses titles, and has its records pressed at the plant as a customer.
  • It owns and licenses: owned masters and licensed reissues are both in scope.
  • Language models are self-hosted, on premises, for the catalogue company's advisor as for the plant assistant; no hosted AI service.

This document plans the catalogue company's tools on the same open-source stack the plant runs, and the line between the two companies. It is a planning position: every figure without a source is an estimate. Nothing here is in the plant's business plan: the catalogue company's orders would reach the plant as ordinary customer orders, and its capital is its own.

Why a catalogue company next to the plant

  • It can fill press time the plan does not sell. At the planned 60 % specials, specials run only on the Duplex system, and the Classic runs at about two thirds of its ~128 records an hour (revenue model). The spare third is 21 to 48 records an hour; at the plan's 60 to 70 % effectiveness, 16 hours and 300 days that is ~60,000 to 160,000 records a year (estimate), black and solid colours only. At the calculator's planning rate the launch plant is balanced and that spare time disappears, so the catalogue company's runs are fillers for idle hours, not a reason to buy presses.
  • A repress at the plant is short. The father and mother of every side are archived, so a repress skips cutting and the three artist gates and takes ~7 to 11 working days; a mother gives about ten stamper sets and a father 5 to 10 mothers (production timeline). A label that orders from a plant abroad presses big runs months ahead and carries the stock. A label next to a plant with its metal in the archive can press small runs often, against measured demand. That is what makes a demand model worth having: it is asked every few weeks, for a few hundred records, not once a year for thousands.
  • There is a market for Thai catalogue abroad, and it runs through Japan. EM Records (Osaka) reissues luk thung and molam compiled by Soi48, many of them first official reissues (EM1185LP, EM1198DLP); Bangkok's ZudRangMa Records co-released an Angkanang Kunchai compilation with EM Records and Soi48 that launched in Japan with the singer present (Bangkok Post). Japanese labels shipped 3.38 million records in 2025, and Japan is short of pressing capacity (revenue model). Contract pressing for Japanese labels now competes with ResurRec's new Japan plant; selling Thai catalogue into Japan does not.
  • The reverse has been done. P-Vine, a Japanese label, built its own plant (VGAP, 2024) because domestic plants took six months to a year and pressing abroad about six months, too slow for new releases. P-Vine also said that, having made records themselves, it found the ~¥4,000 a new record sells for "tight" (Phile-web, 15 October 2024, BRUTUS, 2025). A catalogue earns the retail or wholesale price, and carries stock, rights and marketing in exchange.

What the split does (our reading). Stock, licence advances, royalty accounting and the risk of a title that does not sell sit in the catalogue company, not in the plant company, its BOI promotion or the capital plan its shareholders fund (total investment). The plant stays a neutral supplier to every label, including this one.

What the catalogue company holds

Kind What it is
Owned titles Masters the company owns. Poy Records' releases are the obvious first ones (SST in Frankfurt cut lacquers for POY003, 005, 006 and 013, equipment suppliers); whether they move into the new company, or Poy Records becomes that company, is open
Licensed titles Masters licensed for vinyl: territories, term, sell-off period, royalty per unit, advance and recoupment

Which titles, in which territories and until when, is the first list to write; nothing below can be tested without it.

Arm's length between the two companies

The catalogue company is a customer of the plant like any label, and both sides keep it that way:

  • Orders go through the plant's order intake and customer portal with a customer account and the same gates (artist platform). A purchase order in the catalogue company's books becomes a sales order and a work order in the plant's ERPNext; the plant's invoice becomes a purchase invoice on the other side.
  • Prices come from the plant's price list. Runs that fill idle slots can be sold as standby pressing (a flexible date, scheduled into idle press time, at a lower price), offered on the same terms to every customer, so the related company gets nothing another label could not (proposal; price and terms open). Thai law lets the Revenue Department adjust prices between related companies to arm's length (Revenue Code section 71 bis), and related companies with more than 200 million THB of revenue a year file a disclosure form (OECD transfer pricing profile, Thailand). Whether the two companies are related in that sense depends on who holds the shares, which is open.
  • Press dates. The plant never moves another customer's date for the catalogue company. A label that suspects its plant favours a related label goes elsewhere.
  • Data. The plant's customers' orders, sizes and addresses never reach the catalogue company, and the catalogue company's sales never reach the plant. In the portal it sees what any customer sees: its own orders, its metal parts in the archive and the standby calendar.
  • Metal. Its fathers and mothers sit in the plant's archive under the same storage and retention terms as every customer's, which the customer contract still has to state (production timeline).

The questions the system answers

  1. What to press next: which title, before it runs out where it sells.
  2. How many: a run sized to the demand of the next few months, since the next repress is two weeks away.
  3. Which variant: black or a colour, within what the plant can make (specials compete with every customer's specials on the Duplex; black and solid colours suit standby runs on the Classic's idle hours).
  4. Where the stock goes: its own store room, a distributor, or a shop on consignment.
  5. Which titles to add: licensing leads for a person to research.

Data sources

Source What it gives Location detail Access and terms Lands in
Own web shop, direct shop accounts, event sales (Poy Festival merch table) Every sale with its ship-to or the event's place postcode or city; the event venue the company's own its ERPNext: Sales Invoice, POS Invoice, Delivery Note
Distributor statements Units per account (shop) and territory per month, returns shop or territory the distribution agreement must require monthly sell-through by account, not only sell-in its ERPNext: Channel Sales Report (new, below)
Consignment shops Monthly stock count, so sell-through per shop the shop the consignment agreement its ERPNext: Channel Sales Report, consignment warehouse per shop
Bandcamp Raw sales report with the buyer's ship-to city, state, postcode and country for physical items; also as JSON through the Sales API (help, API) postcode or city the label's own account its ERPNext: Sales Invoice per Bandcamp payout with lines, or Channel Sales Report
Record passport registrations A buyer scans the sleeve code and, opting in, gives country and city: the end listener's place even when the record went through a shop or distributor city consent on the form; no IP address stored; the plant runs the passport for every customer and passes a customer's registrations on to it as its processor (traceability) its analytics store, per-record rows keyed to the record key
Streaming of its own artists Top countries and cities per artist and per song in Spotify for Artists (Spotify); country totals in the distributor's streaming statements country, top cities only for artists it releases its analytics store, weekly series
Interest list and pre-orders "Tell me when it is pressed" sign-ups and pre-orders in its own shop, or through the plant's campaign service on the artist platform on the same terms as any label country, city consent on sign-up its ERPNext: Lead, Sales Order with advance payments
Discogs monthly data dumps Every release, version and pressing in the Discogs database: labels, countries, formats, identifiers (data.discogs.com, CC0) country of release free to use (CC0) a local index on its own server, refreshed monthly
Discogs API: have/want counts, lowest price and copies for sale (API) The collectors' view of a title none useful Restricted Data (marketplace data by name; the have/want counts come from users' collections and wantlists, which the terms also restrict): no commercial use, no storage longer than needed, never shown more than six hours old, no marketing analytics without Discogs' written permission (API Terms of Use, checked October 2026); 60 requests a minute not stored; live look-ups by a person only, unless Discogs agrees in writing
Market totals Country production and sales series, e.g. RIAJ for Japan (revenue model) country public a context layer on the map
Events Tours, festival slots, film or ad syncs, anniversaries, Record Store Day city, date entered by the team its ERPNext (a dated note on the Release)

Sell-in is not sell-through. A distributor buying 300 copies says nothing about fans until the shops sell them; returns can come months later. The model uses sell-through wherever an agreement provides it and treats sell-in as a weaker signal.

Stockouts hide demand. Weeks in which a title was out of stock at a shop record zero sales, not zero demand. Those weeks are marked censored, and the interest list and passport registrations carry the demand the till could not.

Where the data lives (ERPNext touchpoints)

The catalogue company follows the rule the plant set for itself: ERPNext is its only system of record, its tools read and write it, and only machine-speed and signal data stays outside (digital factory). It runs its own ERPNext site, not a second company inside the plant's ERPNext: separate books, a separate database and no shared users, so neither company can see the other's records. The packaging the plant plans to use runs several sites from one installation (frappe-nix with per-site systemd units, hosting on NixOS).

Object In its ERPNext Outside (its analytics store)
Release, side, item per format and variant custom Release and Side documents from the same cnx_erp app; Item per release, format and variant none
Rights new Licence document: licensor, territories, term, sell-off end, royalty basis and rate, advance and recoupment; Release links to it; "owned" or "licensed" on the Release none
Royalties royalty accrual per unit sold, posted as journal entries; a royalty statement print format per licensor none
Places Address gains latitude and longitude of its postcode or city centroid (custom fields, filled by the geocoder); shops are Customers in a "Shop" group with their exact location; regions are ERPNext Territories none
Sales Sales Invoice, POS Invoice, Delivery Note none
Third-party sales new Channel Sales Report: source (distributor, Bandcamp, consignment count), period, lines of item, place (shop, territory or city), units sold, returned, on hand none
Stock Warehouses: its own store room, each distributor, one per consignment shop none
Pressing Purchase Order to the plant, Purchase Invoice from it; repress-ready status (archived father and mother, stamper sets left) read from the plant's customer portal none
Recommendations new Catalogue Recommendation: title and variant, quantity, the forecast quantiles it rests on, the reason, status (proposed, accepted, rejected), link to the Purchase Order it became the full forecast rows per title, place and month
Market opportunities CRM Opportunity and Lead (new shop, distributor, territory, licensing lead) none
External signals none weekly streams per country and city, passport registrations, Discogs dump index, map aggregates

The forecast rows and map aggregates are derived and can be rebuilt from ERPNext and the signal series at any time; nobody types into them. Decisions and their outcomes are ERPNext documents, which is what lets the model and the advisor be scored later.

flowchart LR
    subgraph S[Sources]
        SHOP[Web shop, shop accounts,<br/>event POS]
        DIST[Distributor and<br/>consignment statements]
        BC[Bandcamp sales report]
        INT[Interest list,<br/>pre-orders]
        PP[Record passport<br/>registrations, opt-in]
        STR[Streaming by country<br/>and city, own artists]
        DG[Discogs CC0 dump]
    end
    subgraph C[Catalogue company, on premises]
        ERP[(Its ERPNext<br/>releases, licences, sales,<br/>stock, channel reports)]
        MD[(Analytics store<br/>signal series, forecast rows)]
        FC[Forecast job]
        DASH[Catalogue dashboard<br/>and sales map]
        AG[Market advisor,<br/>self-hosted model]
        TEAM[Team decides]
    end
    subgraph P[Plant company]
        PORTAL[Order intake and<br/>customer portal]
    end
    SHOP --> ERP
    DIST --> ERP
    BC --> ERP
    INT --> ERP
    PP --> MD
    STR --> MD
    DG --> MD
    ERP --> FC
    MD --> FC
    FC --> MD
    FC -->|recommendations| ERP
    ERP --> DASH
    MD --> DASH
    DASH --> AG
    AG -->|drafts: recommendations,<br/>opportunities| ERP
    ERP --> TEAM
    TEAM -->|purchase order| PORTAL
    PORTAL -->|order status, archive,<br/>standby calendar, invoice| ERP

Personal data

Buyers' names and addresses are personal data under Thailand's PDPA (B.E. 2562, fully in force since 1 June 2022; overview), and so is a sales location fine enough to point at one buyer. The catalogue company is the controller of its buyers' data; the plant handles passport registrations for it as a processor, under a processing agreement. The map is built so that it never needs a person:

  • addresses are geocoded to the postcode or city centroid, never to the house;
  • a map cell shows a count only when it holds at least five buyers; smaller cells merge into the surrounding region;
  • only shops and venues, which are businesses, appear as points;
  • passport registrations ask for country and city, with consent, and store no name, e-mail or IP address unless the fan asks to be told about represses;
  • the advisor sees aggregates only; no personal data goes into a prompt.

The catalogue dashboard

One internal tool for the catalogue company's team, with five views.

  1. Catalogue. Every title and variant: owned or licensed, licence territories and expiry, stock by place (store room, distributors, each consignment shop), sell-through over 4, 13 and 52 weeks, weeks of cover at the current rate, repress-ready (from the plant's portal), last pressing, royalties accrued, and a flag when a recommendation is open.
  2. Sales map. Sales density by city or hexagon over time, with a time slider and filters by title, genre, variant and channel. Layers: own sales; shops with its stock (pins sized by stock, coloured by weeks of cover); distributor territories; streaming listeners of its artists; passport registrations; interest-list sign-ups; country totals (RIAJ and others) as context. A white-space layer marks places where listeners, sign-ups or registrations are high and sales or stock are low: the map's version of a market opportunity.
  3. Title page. The sales curve with out-of-stock weeks shaded, the forecast fan for the next months, the title's own map, its archived metal and its licence clock.
  4. Repress planner. Proposed runs against the plant's standby calendar (the idle slots the plant publishes to every customer) and normal lead times, with the Classic's idle hours as the default for black and solid colours.
  5. Advisor inbox. The advisor's notes, each with its numbers linked to the rows they came from, and accept or reject buttons that create or close the ERPNext document.

How it is built. The same open-source stack as the plant's tools (digital factory): Rust (axum, minijinja, HTMX), its own ERPNext integration user, NixOS, managed like the plant's machines but on the catalogue company's own server and disks; internal only, not public. The map is open source and self-hosted, in line with the plant's open-source decision (digital factory):

  • MapLibre GL JS (BSD-3-Clause) in the browser;
  • vector tiles from OpenStreetMap data (ODbL, attribution on the map) as one Protomaps PMTiles file (BSD-3-Clause tooling) served from its own server, so no Google Maps or Mapbox account;
  • H3 hexagons (Apache-2.0) for binning;
  • geocoding offline: postcode and city centroids from GeoNames (CC BY 4.0), with a self-hosted Nominatim only if centroids prove too coarse.

The demand model

The model grows with the data. Each stage has to beat the simpler one before it is allowed to decide anything.

Stage 0: no sales history (a new title or a reissue candidate). Demand is borrowed from comparable titles (genre, era, the artist's streaming, how many pressings already exist per the Discogs dump) and tested cheaply with a pre-order: in the company's own shop, or through the plant's campaign service on the artist platform on the same terms as any label. If the pre-orders reach the minimum run, press; if not, refund and learn.

Stage 1: the first months of sales. A reorder rule, not a model: sell-through per title and place per week, with out-of-stock weeks left out of the rate. Repress when the stock that will be left at the end of the repress lead time (~7 to 11 working days at the plant, plus transport to where it sells) falls below a safety stock. Dashboard view 1 shows this from the first sale.

Stage 2: a year of data and a few dozen titles (thresholds are estimates). A hierarchical count model of weekly sales per title and place (negative binomial, with partial pooling across titles of the same genre and across nearby places), so a title with three months of history borrows strength from its neighbours. Inputs: past sales with censoring for stockouts, the artist's streaming in that place with a lag, price, variant, season (year-end, Record Store Day), events, age since release, passport registrations and sign-ups. Output: a forecast distribution (quantiles), never a single number. Runs as a nightly batch job on its server (Python with statsmodels or PyMC from nixpkgs, as a systemd timer).

How many to press. With a two-week repress the run only has to cover the next few months, so it is sized by the classic stocking rule: press the quantile of next-period demand at which the margin lost on a missed sale balances the cost of a record left unsold.

  • Missed-sale cost: net selling price after the channel's margin, minus what the record costs the catalogue company (the plant's price, 3.40 to 4.25 USD a standard record in the revenue model before any standby discount, plus jacket, sleeve and freight), minus royalty.
  • Unsold-record cost: that cost plus storage and the money tied up, minus any salvage value (an unsold record can be label-punched and granulated into regrind, pressing line, if the plant takes it back; terms open).
  • Floor: the plant's minimum run and setup terms, and within one stamper's life (1,000 to 2,000 pressings, production timeline).

The catalogue company's wholesale and retail prices, the standby price and the packaging cost are not in any document yet; they are inputs to fill before the rule produces a number.

How it is checked. Rolling back-tests on its own history: do the 80 % intervals contain about 80 % of outcomes, and does following the model give fewer out-of-stock weeks and less stock unsold after a year than the Stage 1 rule did? Accepted and rejected recommendations, with what then sold, are ERPNext records, so this is a report, not a project.

The market advisor

An agent that reads the dashboard's data and writes a weekly note plus answers to questions ("where does molam sell outside Thailand?", "which shops stock out fastest?"). It proposes and never acts: it places no order with the plant, sends no e-mail to a shop or licensor and changes no price. An accepted proposal becomes an ERPNext document created by a person.

What it looks for:

  • Repress now: weeks of cover below the repress lead time plus safety, with the run size from the model.
  • Move stock: a shop out of stock while another sits on months of cover.
  • White space: places with listeners, sign-ups or registrations and no shop or distributor; proposed as a CRM Lead for a shop or distributor to approach.
  • Variants: colours that sell faster in a region than black, within what the plant's standby calendar offers.
  • Events: an artist's tour or festival date in a city where stock is thin.
  • Licensing leads: titles in genres that sell for the company that, per the Discogs dump, were never reissued or not for decades, with the original label named. A lead for a person to research; the advisor never says that rights are available.

How it is kept honest:

  • the numbers come from the model and the database, the words from the agent; every figure in a note links to its row and date;
  • it separates the company's own data from outside signals and says how sure it is;
  • it has read-only tools: the dashboard API, the forecast rows, ERPNext reports through a read-only integration user, the local Discogs dump index, market notes, and web search through a self-hosted SearXNG for news (tours, syncs, competing reissues); it has no access to the plant's systems beyond the customer portal;
  • every suggestion and its outcome is logged, and after six months it is scored against the plain reorder rule; if it does not beat it, it becomes a report instead of an agent.

Which model runs it (decided: self-hosted, on premises). The same software as the plant assistant, as the catalogue company's own instance with its own data and permissions, and an open-weights model on hardware it controls. The forecasting is ordinary statistics, so the language model only reads, searches and writes; a mixture-of-experts model such as Typhoon 2.5 may run on a CPU server (to be measured, as for the plant). Running it on the plant's vinyl-ai instead would put the catalogue company's sales data into prompts on the plant company's hardware; that needs a written hosting agreement and is an open decision, not the default.

How it works with the plant

  • Scheduling. Its orders enter the plant's schedule like any customer's; standby runs go into idle slots, the Classic's first, and never move another customer's date.
  • Metal archive. Its fathers and mothers sit in the archive room with every customer's (facility security); the portal shows it what is archived and how many stamper sets are left.
  • Traceability. Its sleeves carry the record passport code like every other record, which is what makes the registration layer of the map possible (traceability).
  • Artist platform. It can use the plant's campaign service on the same terms as any label; its own web shop is its own.
  • Money. The plant's revenue model does not count on its orders. Its working capital (stock, licence advances) and its systems are its own, outside the plant's total investment.

Phasing

Roadmap phase Step
0, validate (now) List the titles to own and to license, with rights and territories; collect Poy Records' existing sales (Bandcamp report, shops, festival) into one sheet and draw the first map by hand; decide whether to ask Discogs for written permission
1 to 2, quotes and commit Found the catalogue company (shareholders, name, whether Poy Records is it or moves into it); the plant's customer terms with standby pressing, data and archive clauses
3, build Its ERPNext site with Licence, Channel Sales Report, Catalogue Recommendation, geocode fields, consignment warehouses; dashboard views 1 and 2; geocoder and tiles on its own server
4, launch First standby runs at the plant on the Stage 1 rule; passport registrations live; advisor version 0 (rule-based notes written up by the self-hosted model)
5, expand Stage 2 model once there is a year of data; licensing leads; the software offered to other labels, open source like the plant stack

Rough cost (estimates)

All of it borne by the catalogue company.

Item Effort or cost
Company setup, its ERPNext site with Thai tax, the catalogue documents and royalty statement 1 to 2 person-months, or a partner quote for the ERPNext configuration
Importers (Bandcamp, distributor and consignment statements, streaming exports) 0.5 to 1 person-month
Dashboard and sales map 1.5 to 3 person-months, less where the plant's open-source code is reused
Forecast job: Stage 1 rule, then the Stage 2 model 0.5, then 1 to 2 person-months
Advisor: tools, prompts, logging, scoring on the plant assistant's software 0.5 to 1 person-month
On-premises server for ERPNext, dashboard, forecast and model (CPU first) a few thousand USD; a GPU only if the CPU trial is too slow (plant assistant for the GPU figure)

Risks

  • Stock is the risk a pressing plant normally avoids. It now sits in the catalogue company; small, frequent represses keep it small, and the model's job is to keep it smaller.
  • Related-party pricing. Prices between the two companies must be the plant's published terms, documented, or the Revenue Department can adjust them.
  • Neutrality. Other labels must be able to trust that the plant does not favour its neighbour; the arm's-length rules above go into the customer terms, not only into this document.
  • Small data. A few dozen titles is little to learn from; the stages above exist so that no complex model decides before it has beaten a simple rule.
  • Data access. Distributors and shops report sell-through only if the contract says so; that clause goes into every agreement from the first.
  • Platform terms. Discogs' marketplace and wantlist data are restricted; the plan uses its CC0 dumps and live look-ups by a person unless Discogs agrees in writing.
  • Distraction. A label is a second business for the same people. Its runs stay fillers for idle press time until the plant's own order book is validated (roadmap item 1).

Open decisions

  1. The catalogue company: who holds its shares, its name, and whether Poy Records is that company or its titles move into it.
  2. Working capital for stock and licence advances: how much and from whom.
  3. Standby pressing: price, terms and the minimum run, offered to every customer of the plant.
  4. Discogs: ask for written permission to use have/want and marketplace data commercially, or work from the CC0 dumps alone.
  5. Where its systems run: its own on-premises server (the default here) or hardware at the plant under a written hosting agreement.
  6. Other labels: whether the software is offered to them, and on what terms (it is open source either way).