Proposed schema for the ETS27 site and its AI concierge, with the mapping back to WordPress, Whova and Eventbrite. Written 2026-10-13.
Companion files: ets-content-inventory.md (what exists today and the evidence) and ../prototype/data/ets.sample.json (a fixture that follows this model). Field names below are the fixture's field names unless a row says "production only".
1. Principles
Per-edition facts, stable identities. A person is stable; their title, employer, bio and photo are not. Model Person once and Appearance per edition. The fixture flattens one edition (ETS26 stand-ins) and keeps the WordPress archive record under wp.
One source of truth per field. Staff edit speakers, FAQ, venue and hotel in WordPress and the agenda in Whova. Anything the front end or concierge builds from them is a disposable snapshot, never a second editable copy (human-operable parity).
Honest gaps. An unknown value is null with a status, never an invented value. Stand-in data carries placeholder: true and a basis.
Readable ids.spk-greg-brown, ses-d2-1330-breakout-a, spn-itron, tkt-industry-phase1. A model can cite them, and a person can read them in a log.
Plain text at the boundary. WPBakery shortcodes, HTML and entities are stripped when data enters the model.
Time. ISO date, local 24-hour HH:MM, one event timezone (America/Chicago).
One-hop answers. Every entity must answer its visitor questions (section 4) from its own fields or its direct references. If answering needs a two-hop join, add a field.
Only announced data reaches visitors. Production adds a status (invited, confirmed, announced, withdrawn) to speakers, sessions and sponsors; the public front end and the concierge read announced only.
Eventbrite API with an organizer token, else hand-mirrored in the Event record
Yes
Visible only in the checkout panel
FAQ
WordPress FAQ type (to be built)
WordPress REST
No
Does not exist
Post
WordPress posts
WordPress REST
No
5 video posts
Edition (past)
WordPress
WordPress REST
No
Separate microsites per year
Snapshot rule: the job that builds a snapshot validates it (referential integrity, no HTML, times valid), diffs it against the last good one, and refuses to publish a snapshot that drops more than a threshold of speakers or sessions.
4. Entities
Each entity has a field table and the visitor questions it must answer. "WP" is WordPress, "WV" is Whova, "EB" is Eventbrite. Required means required in the fixture.
4.1 Edition (event)
Field
Type
Req
Notes and source
id
string
yes
ets27; past editions ets26; satellites ets-chicago-2024
kind
flagship or satellite
editions
ets@events one-day events are satellites
name, short_name
string
yes
"Energy Thought Summit 2027", "ETS27"
year, edition_number
int
yes
edition_number = year - 2013 (ETS23 was the 10th, ETS26 the 13th, ETS27 the 14th)
theme, tagline, hashtag
string
yes
"Free Your Mind", "Free Your Mind. Shape the Future.", "#LoveYourEnergy" (EB copy)
description
string
yes
Organizer copy from EB
status
enum
yes
announced for ETS27
start_date, end_date, timezone
ISO date, IANA zone
yes
2027-05-03 to 2027-05-06, America/Chicago (EB JSON-LD, WP hero)
day_count_calendar, published_hours
int, string
no
4; "08:00-17:30" (EB)
city, region, country
string
yes
Austin, TX, US
attendance_mode
enum
no
in_person
organizer
object
yes
Zpryme
urls, contact, social
objects
yes
Register link keeps the affiliate parameter. Contact form subjects are listed
confirmed
object of booleans
yes
dates, city, theme, register_link, ticket_prices true; venue, hotel, lineup, agenda, sponsors false. The concierge reads this before answering
venue (editions)
string or null
no
Past venues; ETS23 Hotel ZaZa, ETS25 and ETS26 Boeing
eventbrite_url, pages
url, urls
no
Archive links
Visitor questions:
Question
Answered by
If missing
When is it?
start_date, end_date, published_hours
Never missing
Where is it?
city, region; venue.name
Say the venue is to be announced (confirmed.venue false)
What is ETS and what is the theme?
theme, tagline, description
n/a
How do I register?
urls.register, tickets
n/a
Is the lineup or agenda out yet?
confirmed.lineup, confirmed.agenda
Offer the ETS26 program as a reference, labeled as such
Has it been held before, and where?
editions[]
n/a
Who runs it, how do I contact them?
organizer, contact
n/a
How do I follow updates?
social, newsletter
n/a
4.2 Day
Field
Type
Req
Notes and source
id, n, label
d1, 1, "Day 1"
yes
date, weekday
ISO date, string
yes
WV agenda[].date, .day
start, end
HH:MM
yes
Earliest start, latest end of the day's sessions
session_count
int
yes
Derived
summary
string
no
Editorial one-liner (placeholder in the fixture)
Four days for ETS27 (Mon May 3 to Thu May 6); the fourth is a half day as in ETS23, ETS24 and ETS26.
Question
Answered by
If missing
What is on Tuesday?
Sessions with day = d2
Say the agenda is not announced
What time does each day start and finish?
start, end
n/a
Is there a half day, when does it end?
d4.end
n/a
What is the evening plan?
Sessions of type reception that day
"No evening event announced"
When are meals and breaks?
Sessions of type meal, break
n/a
What date is Day 3?
date, weekday
n/a
What is the shape of a typical day?
summary
n/a
4.3 SessionType and Track
Whova's eight "tracks" are formats. The model splits them: SessionType is the format, Track is an optional theme.
(none) and title is an opening, closing or event close
ceremony
Track fields: id, label, color_hint. ETS26 had no thematic tracks. The fixture invents seven placeholders from recurring session themes (ai-digital, resilience-security, customer-affordability, policy-planning, grid-edge, load-growth, people-community) and flags them placeholder: true, basis: invented. For ETS27, decide whether themes come from Whova tags or a WordPress list.
Question
Answered by
If missing
What formats are there, what is a Town Hall?
session_types[].label, note
n/a
Show me all keynotes
Sessions with type = keynote
n/a
Which sessions are about AI, security, affordability?
topics, track
Fall back to title search
What are the themes?
tracks[]
Say themes are not announced
Which are the short formats?
duration_min by type
n/a
Which sessions run in parallel, how do I choose?
Sessions with the same day and start and type = breakout
n/a
4.4 Session
Field
Type
Req
Notes and source
id
string
yes
ses-d{day}-{HHMM}-{slug}
day, date
d2, ISO date
yes
WV calendar_stime date
start, end, duration_min
HH:MM, int
yes
WV start_time, end_time
title
string
yes
WV name
type
SessionType id
yes
Mapping in 4.3
track, topics[]
Track ids
no
Derived in the fixture; WV tags is empty today
description
string or null
no
WV desc (HTML, stripped). 9 of 68 in ETS26
speaker_ids[], moderator_ids[]
Person ids
yes
WV speaker.Speakers, .Speaker, .Moderator
room
string or null
no
WV place. 22 of 68 in ETS26
sponsor_ids[]
Sponsor ids
no
WV sponsors is empty today; ETS26 sponsors were named in titles
Person key and matching: key on normalized first last, with an alias table (Chima and Chimaobi Chijioke, Rudy D. and Rudy Garza, H.G. and H G Chissell). The ETS26 to ETS25 match used last name plus first initial, then a manual check: 35 of 147 matched (31 exact, 4 by name variant).
Question
Answered by
If missing
Who is X?
title, org, bio
Show title and org; no bio for 41 of 77 fixture speakers
Who is speaking this year?
Speakers with status = announced
Say the lineup is not announced; offer ETS26 as reference
When is X on?
session_ids
n/a
Who is from utility or company Y?
org search
n/a
Who are the keynotes, who is featured?
category, featured
n/a
Has X spoken before, any honors?
wp, honors
n/a
What does X look like, link to a profile?
photo, photo_alt, slug
Show the placeholder portrait
How do I nominate a speaker?
Contact subject "Nominate Thought Leader"
n/a
4.6 Venue, Hotel, Room
Field
Type
Req
Notes and source
id, name, city, region, country
yes
ETS27: "TBD - Austin, TX"
address, phone, website
string or null
no
WP /venue/ copy for past venues
status
not_announced, announced
yes
eventbrite_listing
object
no
EB location name and street pin; unconfirmed
hotels[]
objects
no
name, role (host, overflow), booking_url, deadline, shuttle, status
rooms[]
objects
production
id, name, level, capacity; WV place is free text today
getting_there
object
no
Transit, airport, parking, accessibility (placeholder in the fixture)
prior_venue
object
no
ETS26 venue, hotels, evening venues, and a note about the Boeing/Westin split
Starter set (8): when and where, theme, register and cost, who should attend, hotel, getting around, dress, speak sponsor or volunteer. Likely next: accessibility, parking, wifi, dietary needs, children, international visitors, recordings, refunds in detail, what is included.
Question topic the FAQ must cover
Today
Dress code
Placeholder
Hotel and room block
Placeholder (ETS26 pattern)
Travel and local transport
Partial (Sustainability Promise)
Who should attend
Grounded in ETS23 and home copy
Refunds and transfers
Refunds grounded (EB); transfers unknown
Accessibility, parking, wifi, dietary
No source yet
Speaking, sponsoring, volunteering
Grounded (contact form)
Recordings and photos
No source yet
4.10 Post
Field
Type
Req
Notes and source
id, wp_id, slug, title, date, url
yes
WP posts
kind
video, article
yes
All five live posts are video
youtube_id, image_url
string
no
Parsed from the iframe; WP featured_media
category, excerpt
string or null
no
Category "News"; excerpts empty
Question
Answered by
If missing
What is the latest news?
Posts by date
Latest is 2024-09-24; say news is quiet
Show me videos from past events
kind = video
n/a
Who spoke at past editions?
title only (for example Wozniak at ETS14)
No transcript; needs YouTube captions or a written summary
Where can I watch recordings?
youtube_id, social youtube
n/a
What happened last year?
editions[], archive pages
n/a
Can I share this?
url
n/a
5. Concierge snapshot, component catalog and tools
The project brief puts a compact knowledge snapshot in a cached prompt prefix and has the concierge answer with one structured result, {say, ui}, where ui is a list of components from an allow-listed catalog that carry record ids. The renderer draws each component from the site's own data by id and drops unknown ids. This model is built for that: ids are readable and stable, and every record carries its placeholder and confirmed flags.
5.1 Lean snapshot (goes in the prefix)
Keep the prefix to the fields the model needs to choose and cite; the renderer reads the rest by id.
Measured on the fixture: about 31.6 KB compact JSON, roughly 8,000 tokens by a characters-divided-by-four estimate (ids tokenize heavily, so measure with the real tokenizer). That fits the brief's 6 to 10 thousand token budget. Bios, descriptions, photos, wp archive blocks and source blocks stay out of the prefix. A real ETS27 lineup of 100 to 150 speakers will push the prefix up; at that point switch the speaker block to search (5.3).
5.2 Component catalog
Names follow the brief's first cut. Props are the few the model controls; the right-hand column is what the renderer reads by id.
Component
Model supplies
Renderer reads
speaker_grid
speaker_ids[]
name, title, org, photo, photo_alt, category, featured
Entities the first cut does not yet cover: past editions and videos (edition_timeline, video_card) and FAQ as a first-class item (faq_item, or keep using text_block). The sample marker is renderer-owned: any component that draws a record with placeholder: true shows it, and the model cannot switch it off.
5.3 Tools (only if the snapshot outgrows the prefix)
Everything else (event, venue, tickets, sponsors, days, tracks) is small enough to stay in the prefix. Every tool result keeps the placeholder and confirmed flags.
6. Placeholder and provenance conventions
placeholder (bool): true means "stands in for ETS27 data that does not exist yet; replace when real data arrives." False means a real, published fact, still subject to as_of and verify_before_display.
confirmed_for_ets27 (speakers, sponsors): false for every stand-in. Real people in the fixture are there because they spoke at ETS26; none is confirmed for ETS27.
owner_to_confirm (FAQ): the answer needs a Zpryme decision before launch.
UI rule: wherever placeholder is true, show a visible "sample data" marker. The concierge states stand-ins as examples, never as announcements.
The provenance block in the fixture lists sources with retrieval dates, which fields are real, adapted, invented or derived, counts, manual corrections and known data issues.
7. Normalization rules
Area
Rule
Text
Strip tags, decode entities (Whova bios contain '), trim; unknown becomes null, never an empty string
Names
Whova name is the display name; WP name is an alias; straight apostrophes
Title and org
Whova for the current edition; WP values kept as ets25_title, ets25_org
Dates
calendar_stime gives the date; start_time and end_time are already 24-hour local
ETS26 to ETS27 relabel
Shift dates by +371 days (Monday Apr 27, 2026 to Monday May 3, 2027); replace "ETS26" with "ETS27" in titles; strip venue and sponsor suffixes from receptions and lunch; keep the original in source
Photos
Prefer the current edition's upload; omit generic avatars; add alt text; resize through an image service
Bios
Detail pages show the full bio; cards use the leading sentences up to 60 words
Sponsors
Names from logo file names are provisional; record name_confidence and replace with structured data
Edition number
year - 2013
8. About the fixture
prototype/data/ets.sample.json follows this model with the keys meta, provenance, event, editions, venue, agenda (days, tracks, session_types, sessions), speakers, sponsor_tiers, sponsors, tickets, faq, posts.
Block
Count
Basis
Speakers
77 (30 fully complete, 36 with a bio, 59 with a photo, 27 with a WordPress archive record)
Real ETS26 speakers, stand-ins
Sessions
50 over 4 days
ETS26 program relabeled to ETS27 dates; 44 copied, 6 adapted (reception, lunch and ETS26-branded titles)
Tracks
7
Invented placeholders
Sponsors
39 in 6 tiers
ETS26 partners, stand-ins
Tickets
4 classes
Real, read 2026-10-13, verify before display
FAQ
8 (5 grounded, 3 placeholder)
Mixed
Posts
5
Real
Editions
5 flagships, 2 satellites
Real
Choices that differ from the original ask:
Four days, not three. ETS27 is announced as May 3 to 6, 2027. Days 1 to 3 hold the full program; day 4 is the half day. If a prototype wants exactly three days, take d1 to d3.
Real ticket tiers instead of placeholders. They were readable on the public Eventbrite panel, so the fixture carries them with an as_of date.
Speakers come from Whova, with WordPress photos where a returning speaker exists. The WordPress archive holds ETS25, not ETS26. 26 photos come from WordPress featured_media, 33 from the Whova CDN, 18 speakers have no usable photo (generic avatar omitted).
Gaps are kept on purpose. 41 speakers have no bio and 18 no photo, so prototypes must design for missing data, as the real lineup will have.
Checks run: the file parses as UTF-8 JSON; no HTML or entities in any string; every session, speaker, sponsor and day reference resolves; all bios are at most 60 words; all 103 image URLs returned HTTP 200 on 2026-10-13.
Do not paste the whole file into a model prompt (about 200 KB). Build the lean snapshot in section 5.1 from it (about 31.6 KB, roughly 8,000 tokens) and let the renderer read full records by id.
9. Facts only Zpryme can supply
Venue and hotel for ETS27; whether the ETS27 Whova event exists and whether an official Whova API credential is available; an Eventbrite API token or a person who will keep the ticket table current; ticket inclusions and discount rules; sponsor tier benefits and the ETS27 partner list; which FAQ answers are right (dress, accessibility, parking, recordings); whether the ETS23 and ETS24 press logos may be reused.