← Slot Desk
API
Tokens

Run Slot Desk from your own code

Both metered lanes are available over HTTP and each returns one JSON object. The division of labour: the page reads the rooms, sessions and windows, lays the grid, runs the four clash types and picks the buffer, track starts, clash depth and publication posture - all free, in slotkit.js. The run writes the plan or the overlap pass; the page then holds the reply to its own picks and re-checks every swap (slotreply.js).

Base URL and the response shape

Every endpoint lives under https://api.skillsafe.ai/v1/app-api, and every response has one shape:

{ "ok": true,  "data":  { ... } }
{ "ok": false, "error": { "code": "...", "message": "..." } }

The token is minted for this app (the guest call takes {"slug":"slot-desk"}), so no slug header is needed afterwards. Send it as Authorization: Bearer …. The run body is the input object, sent bare.

StatusCodeMeaning
400validation_errorThe body is not a JSON object, or a required key (task, event, grid, facts) is missing.
401unauthorizedNo token, or a stale one. Mint a guest token or sign in again.
402insufficient_creditsThe balance is under min_credits. Price with /estimate first.
403forbiddenA guest token tried to run: both lanes are metered and need a personal sign-in.
404not_foundUnknown job id.
429rate_limitedBack off and retry.
5xxserver_errorTransient. Retry with the same Idempotency-Key so a retry never double-bills.

The task field comes first

Two lanes - plan (validate the grid before it goes public) and overlap (multi-track only). A missing or unknown task is answered as plan. Both lanes send the same four fields.

The input

FieldRequiredWhat
taskyesplan or overlap. If it is missing or neither, do plan and set "task": "plan".
eventyesthe event, its days and dates, the day window, the venue-fixed breaks, the rooms with seats, walking minutes, floors and windows, the corridor, what changes in a room between sessions, the audience and the dates.
gridyesthe grid the page laid, row by row and room by room (each session with its format, track, level, length, speakers and expected audience against the room's seats), what is not on the grid, each co-speaker intersection and every speaker window given.
factsyesthe page's picks (slot standard, buffer, alignment, clash depth, fixed points, publication posture and date, disruption order, measurement) and every finding tagged [fix], [check] or [info].
retry_notenooptional; if present, your previous reply was unusable - follow it.

The rules the model applies

House rules

The replies

plan

  1. summary - one sentence, at most 35 words: the grid's shape and the first thing to settle.
  2. slots - standard (the page's talk and slot lengths, as a short phrase), brief (one sentence telling speakers both numbers).
  3. fixed_points - one entry per session the page placed as a fixed point (keynotes and pinned sessions), in time order: id, when (day and start time as the grid shows them, such as D1 09:00), why (one sentence: a keynote bookend, or pinned there by the organizer, and what that position does for the day - never an invented reason).
  4. breaks - 1 to 4 short strings: the breaks and which of them are plenary re-sync points.
  5. rooms - one entry per room: room (its name), holds (one sentence: what it holds and the audience estimate behind the match, naming any overflow).
  6. clashes - depth (availability, mechanical or overlap, the page's pick), findings (0 to 6 short strings: each clash the page found and how to fix it; [] when there are none), rerun (one sentence: when the check runs again).
  7. buffer - rung (internal, fixed, proportional or turnover, the page's pick), minutes (the minutes the page's slot leaves between talks, a number), walking (one sentence: the walking distance it was checked against).
  8. alignment - pick (synchronized, staggered or single, the page's pick), why (one sentence).
  9. pacing - 2 to 4 short strings about this grid, each ending with (sourced) or (judgment).
  10. disruption - exactly 4 strings, the page's order, made specific to this grid where you can (the headline commitment is your judgment - say which session and why; when the grid has no keynote or plenary, say so in the first step and protect the nearest fixed point).
  11. publication - posture (early, staged, versioned or late, the page's pick), date (the page's publish-by date, or "not dated"), why (one sentence).
  12. metrics - 2 or 3 short strings, the page's measurement picks, each with the revision it would trigger next edition (your design).
  13. caveats - at most 4 short strings: every [fix] finding first, then the most important [check] findings while there is room. [] when there are none of either.
{
  "task": "plan",
  "summary": "one sentence",
  "slots": { "standard": "45-minute talks in 50-minute slots", "brief": "one sentence" },
  "fixed_points": [ { "id": "K1", "when": "D1 09:00", "why": "one sentence" } ],
  "breaks": [ "a break" ],
  "rooms": [ { "room": "a room", "holds": "one sentence" } ],
  "clashes": { "depth": "mechanical", "findings": [ "a clash and its fix" ], "rerun": "one sentence" },
  "buffer": { "rung": "internal", "minutes": 5, "walking": "one sentence" },
  "alignment": { "pick": "synchronized", "why": "one sentence" },
  "pacing": [ "a read (judgment)" ],
  "disruption": [ "first", "second", "third", "fourth" ],
  "publication": { "posture": "early", "date": "YYYY-MM-DD", "why": "one sentence" },
  "metrics": [ "what to record and what it changes" ],
  "caveats": [ "a caveat" ]
}

The page holds it to its own picks: the clash depth, buffer rung and minutes, track-start alignment, publication posture and date must be the page's; every fixed point must be listed at its grid time; the disruption order protects the plenary first; no number or session may appear that the input does not hold.

overlap

  1. pairs - 1 to 6 entries, the strongest first: a and b (IDs of two sessions the grid runs at the same time, in different rooms), when (day and start time as the grid shows them), why (one sentence: who would want both, from the titles, tracks and levels - your judgment), move (a swap that would split them, or null): session (a or b's ID), swap_with (the ID of a session of the same length in a different time row, not a keynote and not pinned), why (one sentence). A swap must not break a speaker window, a room window or a double-booking, must not put a session in a room smaller than its expected audience, and must not land the moved session opposite the other one again - the page checks every swap. Include every same-track pair the page flagged. Judge each move on its own against the grid as laid, using the speaker windows, co-speaker intersections and room windows the input gives.
  2. clear - one sentence: what in the grid does not need moving.
  3. note - one sentence, at most 30 words, for the program chair: this pass is judgment, and what to ask attendees next edition to check it.
{
  "task": "overlap",
  "pairs": [ { "a": "S04", "b": "S09", "when": "D1 11:00", "why": "one sentence", "move": { "session": "S09", "swap_with": "S15", "why": "one sentence" } } ],
  "clear": "one sentence",
  "note": "one sentence"
}

The page checks that every pair really runs at the same time on its grid, re-runs every proposed swap through the four clash types and the rooms' seats, rejects a swap that lands the session opposite its partner again, and requires every same-track pair it flagged.

Worked examples - every lane, every sample

These are the page's three free samples (fictional events, people and companies). Each input is exactly what the page sends; each reply is the saved reply the sample replays, shipped as the validating model wrote it; the last line is the page's own check. The one-room meetup has no overlap lane - nothing runs at once.

Harbor DevDays (2 days, 3 rooms) - plan

30 of 30 sessions placed in 3 rooms over 2 days; 1 clashes; clash depth overlap, publication versioned.

Input:

{
 "task": "plan",
 "event": "Event: Harbor DevDays; 2 days from 2027-05-13; day window 09:00-17:30\nBreaks (venue-fixed): 10:40-11:00 Coffee; 12:40-13:40 Lunch; 15:20-15:40 Coffee\nRooms: Main Hall 420 seats, 0 min walk, floor G; Room B 160 seats, 4 min walk, floor 1; Room C 90 seats, 5 min walk, floor 1, available D1 09:50-17:30, D2\nVenue: corridor open; between sessions a room needs nothing\nAudience: mixed technical and non-technical no; fast-moving field yes; edition compounds yearly yes; attendees travel yes; tickets already on sale yes; organizer says two tracks share an audience no\nDates: today 2027-02-01; planned publication 2027-03-20",
 "grid": "D1 (2027-05-13):\nD1 09:00-09:50 PLENARY | Main Hall: K1 \"What ten years of on-call taught us\" (keynote; intro; 45 min; speakers Mara Quist; expected 380 of 420 seats)\nD1 09:50-10:40 | Main Hall: P01 \"Scaling Postgres at read-heavy loads\" (talk; track Data; intermediate; 45 min; speakers Ana Ruiz & Ben Okoro; expected 170 of 420 seats) | Room B: P12 \"Incident reviews people read\" (talk; track Platform; intro; 45 min; speakers Dee Harlow; expected 150 of 160 seats) | Room C: P22 \"Animations that respect motion settings\" (talk; track Frontend; intermediate; 45 min; speakers Rio Day; expected 60 of 90 seats)\nD1 10:40-11:00 BREAK Coffee\nD1 11:00-11:50 | Main Hall: empty | Room B: P21 \"Time zones will hurt you\" (talk; track Data; intermediate; 45 min; speakers Kai Mott; expected 150 of 160 seats) | Room C: W1 \"Hands-on: profiling Python services\" (workshop; track Platform; intermediate; 95 min; speakers Jon Abara & Fen Holt; expected 40 of 90 seats)\nD1 11:50-12:40 | Main Hall: empty | Room B: P19 \"Web performance budgets\" (talk; track Frontend; intro; 45 min; speakers Teo Vance; expected 140 of 160 seats) | Room C: W1 continues\nD1 12:40-13:40 BREAK Lunch\nD1 13:40-14:30 | Main Hall: P06 \"Rust in a Python shop\" (talk; track Platform; intermediate; 45 min; speakers Jon Abara; expected 200 of 420 seats) | Room B: P05 \"Accessible forms from the start\" (talk; track Frontend; intro; 45 min; speakers Kit Moreau; expected 110 of 160 seats) | Room C: empty\nD1 14:30-15:20 | Main Hall: P27 \"Shipping a design system\" (talk; track Frontend; intro; 45 min; speakers Noor Sami & Kit Moreau; expected 110 of 420 seats) | Room B: P04 \"Event sourcing in anger\" (talk; track Data; advanced; 45 min; speakers Lena Voss; expected 140 of 160 seats) | Room C: empty\nD1 15:20-15:40 BREAK Coffee\nD1 15:40-16:30 | Main Hall: P18 \"Data contracts that stick\" (talk; track Data; intermediate; 45 min; speakers Ivy Quarle; expected 100 of 420 seats) | Room B: P11 \"Hydration bugs and how to find them\" (talk; track Frontend; advanced; 45 min; speakers Lu Chen; expected 120 of 160 seats) | Room C: empty\nD1 16:30-17:20 | Main Hall: P25 \"Micro-frontends: a retrospective\" (talk; track Frontend; intermediate; 40 min; speakers Sam Ito; expected 100 of 420 seats) | Room B: P07 \"Query plans for humans\" (talk; track Data; intermediate; 45 min; speakers Ana Ruiz; expected 130 of 160 seats) | Room C: empty\nD2 (2027-05-14):\nD2 09:00-09:50 | Main Hall: empty | Room B: P09 \"Kubernetes cost without tears\" (talk; track Platform; intermediate; 45 min; speakers Priya Nand; expected 160 of 160 seats) | Room C: P16 \"Testing the untestable UI\" (talk; track Frontend; intermediate; 45 min; speakers Eli Park; expected 90 of 90 seats)\nD2 09:50-10:40 | Main Hall: empty | Room B: P24 \"Batch to streaming in one quarter\" (talk; track Data; advanced; 45 min; speakers Ola Brandt; expected 110 of 160 seats) | Room C: P03 \"The build cache that lied\" (talk; track Platform; intermediate; 45 min; speakers Rafa Sol; expected 90 of 90 seats)\nD2 10:40-11:00 BREAK Coffee\nD2 11:00-11:50 | Main Hall: empty | Room B: P10 \"Streaming joins explained\" (talk; track Data; advanced; 45 min; speakers Ola Brandt; expected 95 of 160 seats) | Room C: P08 \"CSS layers in practice\" (talk; track Frontend; intermediate; 45 min; speakers Sam Ito; expected 85 of 90 seats)\nD2 11:50-12:40 | Main Hall: empty | Room B: P15 \"Zero-downtime migrations\" (talk; track Data; advanced; 45 min; speakers Ben Okoro; expected 160 of 160 seats) | Room C: P14 \"Design tokens across three apps\" (talk; track Frontend; intro; 45 min; speakers Noor Sami; expected 70 of 90 seats)\nD2 12:40-13:40 BREAK Lunch\nD2 13:40-14:30 | Main Hall: P13 \"Vector search on a budget\" (talk; track Data; intermediate; 45 min; speakers Max Feld; expected 190 of 420 seats) | Room B: P17 \"SLOs your team believes\" (talk; track Platform; intermediate; 45 min; speakers Gus Lind; expected 130 of 160 seats) | Room C: empty\nD2 14:30-15:20 | Main Hall: P20 \"Platform teams as product teams\" (talk; track Platform; intro; 45 min; speakers Ines Calder & Gus Lind; expected 170 of 420 seats) | Room B: P23 \"Observability on a shoestring\" (talk; track Platform; intermediate; 45 min; speakers Fen Holt; expected 120 of 160 seats) | Room C: P26 \"Search relevance tuning\" (talk; track Data; advanced; 45 min; speakers Max Feld; expected 90 of 90 seats)\nD2 15:20-15:40 BREAK Coffee\nD2 15:40-16:30 | Main Hall: empty | Room B: P02 \"Feature flags without the flag debt\" (talk; track Platform; intro; 45 min; speakers Ines Calder; expected 120 of 160 seats) | Room C: empty\nD2 16:30-17:20 PLENARY | Main Hall: K2 \"A live demo you can break\" (keynote; intro; 45 min; speakers Tobi Arden; expected 340 of 420 seats)\nCo-speaker intersections: P01 D1 10:00-17:30, D2 09:00-17:30; P20 all hours; W1 D1 09:00-17:30, D2 09:00-12:40; P27 all hours\nSpeaker windows: Mara Quist D1; Tobi Arden D2; Ana Ruiz D1 08:00-17:30, D2; Ben Okoro D1 10:00-17:30, D2; Lena Voss D1 11:00-17:30; Jon Abara D1, D2 09:00-12:40; Priya Nand D2 09:00-13:00; Ola Brandt D2; Lu Chen D1; Fen Holt D1, D2; every other speaker is treated as free all event",
 "facts": "Slot standard: 45-minute talks in 50-minute slots (5 minutes inside each slot), computed from the buffer\nBuffer: internal - Slot-internal buffer (slots published longer than the talks they hold); 5 minutes wanted. The default: slots published 5 minutes longer than the 45-minute talks they hold - brief speakers on both numbers. Longest walk between rooms: 5 minutes across 2 floors.\nTrack-start alignment: synchronized - The corridor clears with 3 rooms changing at once; keep everyone arriving together at the plenary moments.\nClash depth: overlap - The mechanical checks plus the audience-overlap pass. Sessions from the same track run head to head - that promotes the audience-overlap pass on top of the three mechanical checks. Clashes found: 1 (room window 0, speaker window 1, same-room overlap 0, double-booked 0)\nFixed points placed first: K1 D1 09:00 plenary in Main Hall; K2 D2 16:30 plenary in Main Hall; P01 D1 09:50 pinned in Main Hall\nPlaced 30 of 30 sessions in 42 room-slots; plenary room Main Hall\nPublication posture: versioned - A multi-day, multi-track grid people build personal agendas against - publish early and carry a visible marker of what moved. Attendees travel: publish by 2027-03-14, 60 days out (self-set from flights booked about two months ahead). Lock-late is deleted for this event.\nDisruption order: 1. Protect the plenary or keynote slot first. 2. Protect the headline commitment the audience came for next. 3. Minimize how many other sessions the fix disturbs. 4. Lock the revised grid for the rest of the block instead of re-shuffling.\nMeasurement picks: Room-fit outcomes - sessions that overflowed and sessions that ran near-empty (self-set); Reported clashes - a survey question naming the two sessions attendees were torn between; Post-publication change count and last-change date (self-set)\nLate-held topical slots: 2 (one a day, self-set)\nCalibration (not targets): FOSDEM 2026 - 1,079 events, 37 rooms, 71 tracks; ~50-minute talks, lightning capped at 15; a 10-minute visible gap; PyCon US 2026 - 45-minute talks across five main rooms, staggered starts (11:00, 11:45, 12:30, 1:45...); keynotes 9:00-9:45, lunch about 12:30-1:15\nFindings (10):\n[fix] speaker_window (clash - speaker window): P01 sits D1 09:50-10:35 in Main Hall, but Ben Okoro is not available then (Ben Okoro: D1 10:00-17:30, D2) - the check on Ana Ruiz alone passes; the co-speaker intersection is D1 10:00-17:30, D2 09:00-17:30.\n[check] bespoke (slots): 1 session (P25 40 min) does not fit the 45-minute standard - make every session fit one slot length.\n[check] avail_missing (speakers): 13 speakers without a window (Ines Calder, Rafa Sol, Kit Moreau, Sam Ito, Dee Harlow, Max Feld...) - treated as free all event; ask before publishing.\n[info] intersection (speakers): Co-speaker intersections: P01 D1 10:00-17:30, D2 09:00-17:30; P20 all hours; W1 D1 09:00-17:30, D2 09:00-12:40; P27 all hours.\n[check] same_track (audience): P20 and P23 are both Platform and run head to head on D2 at 14:30.\n[info] bookend (pacing): D1 has no closing keynote - bookending each day in a format unlike the talks is the organizer's own experience, not a published source.\n[info] bookend (pacing): D2 has no opening keynote - bookending each day in a format unlike the talks is the organizer's own experience, not a published source.\n[fix] late_publish (publication): Planned publication 2027-03-20 is after 2027-03-14 - attendees travel, and a late grid cannot inform a flight already booked.\n[info] topical (publication): Fast-moving field: hold 2 slots (one a day, self-set) marked 'topic announced later' - slot, room and time fixed, the talk filled close to the event.\n[info] idle (grid): Minutes no slot fits: 17:20-17:30 at the end of the day."
}

Reply:

{
 "task": "plan",
 "summary": "Harbor DevDays lays 30 sessions across two days and three rooms between two keynote bookends; the first thing to settle is Ben Okoro's unavailability during P01's pinned slot in Main Hall.",
 "slots": {
  "standard": "45-minute talks in 50-minute slots",
  "brief": "Tell speakers their talk runs 45 minutes inside a 50-minute slot, or they will run long into the 5-minute buffer the slot carries."
 },
 "fixed_points": [
  {
   "id": "K1",
   "when": "D1 09:00",
   "why": "This is the keynote that opens D1, the first bookend of the day before the grid's talks begin."
  },
  {
   "id": "P01",
   "when": "D1 09:50",
   "why": "This is pinned by the organizer directly after the opening keynote in Main Hall, carrying the day's largest non-keynote expected audience, 170 of 420, into the first standard slot."
  },
  {
   "id": "K2",
   "when": "D2 16:30",
   "why": "This is the keynote that closes D2, the final bookend placed in the day's very last slot."
  }
 ],
 "breaks": [
  "10:40-11:00 Coffee, a plenary re-sync point that resets per-track drift across Main Hall, Room B and Room C.",
  "12:40-13:40 Lunch, a plenary re-sync point before the afternoon rooms resume together.",
  "15:20-15:40 Coffee, a plenary re-sync point ahead of the final slots of the day."
 ],
 "rooms": [
  {
   "room": "Main Hall",
   "holds": "Main Hall (420 seats) holds both keynotes, K1 at 380 of 420 and K2 at 340 of 420, along with each day's highest-draw talks such as P01 at 170 and P13 at 190 of 420, all comfortably under capacity with no overflow."
  },
  {
   "room": "Room B",
   "holds": "Room B (160 seats) holds mid-sized talks across all three tracks, several running at full capacity such as P09 and P15 at 160 of 160, with no overflow beyond its seats."
  },
  {
   "room": "Room C",
   "holds": "Room C (90 seats) holds the smaller talks and the two-part workshop W1, with several sessions filling it exactly such as P16, P03 and P26 at 90 of 90, and no overflow."
  }
 ],
 "clashes": {
  "depth": "overlap",
  "findings": [
   "P01's pinned 09:50 start on D1 falls before Ben Okoro's own window opens at 10:00, even though Ana Ruiz alone is free then; the fix is to start P01 within the co-speaker intersection of D1 10:00-17:30, D2 09:00-17:30."
  ],
  "rerun": "Re-run all four clash checks after every change to the grid, including after any fix to P01's pinned start time."
 },
 "buffer": {
  "rung": "internal",
  "minutes": 5,
  "walking": "The 5-minute internal buffer was checked against the longest walk between rooms, 5 minutes across 2 floors, to Room C."
 },
 "alignment": {
  "pick": "synchronized",
  "why": "All 3 rooms change at once and the corridor clears, so starts synchronize to keep arrivals together ahead of the plenary moments."
 },
 "pacing": [
  "The slot right after Lunch, 13:40 on both days, falls into the post-lunch dip in attention (sourced).",
  "D2's last slot of the event, 16:30, is normally the worst-attended position studied at other conferences, though no magnitude is given here (sourced).",
  "D1 has no closing keynote, so its day ends on a regular talk slot rather than a bookending keynote format (judgment).",
  "D2 has no opening keynote, so only its close with K2 bookends the day, unlike D1 which bookends only its open with K1 (judgment)."
 ],
 "disruption": [
  "Protect the plenary slots first: keep K1 at D1 09:00 and K2 at D2 16:30 exactly where they sit, since both are the fixed keynote bookends.",
  "Protect the headline commitment next: P01 at D1 09:50 in Main Hall, the pinned session right after the opening keynote with the day's largest non-keynote expected audience at 170 of 420 - our call on what counts as the headline commitment here.",
  "Minimize how many other sessions the fix disturbs: when resolving the P01 clash with Ben Okoro's availability, move only P01 rather than reshuffling Room B or Room C in the same window.",
  "Lock the revised grid for the rest of the block once the fix is set, rather than continuing to re-shuffle D1's morning sessions."
 ],
 "publication": {
  "posture": "versioned",
  "date": "2027-03-14",
  "why": "A multi-day, multi-track grid that attendees build personal agendas against should publish early with a visible marker of what moved, going out by 2027-03-14, 60 days before the event, since attendees travel and typically book flights around then."
 },
 "metrics": [
  "Room-fit outcomes - which sessions overflowed and which ran near-empty; repeated overflow next edition would trigger moving that session to a bigger room, repeated near-empty would trigger a smaller one (our design).",
  "Reported clashes - a survey question naming the two sessions attendees were torn between; a same-track pair named repeatedly would trigger moving one of them to a different time row next edition (our design).",
  "Post-publication change count and last-change date - a high count or a late last change would trigger moving the publish-by date earlier next edition (our design)."
 ],
 "caveats": [
  "P01 is pinned at D1 09:50 in Main Hall but Ben Okoro is only free from D1 10:00 onward (co-speaker intersection D1 10:00-17:30, D2 09:00-17:30); move its start to or after 10:00 to clear the speaker-window clash.",
  "Planned publication is set for 2027-03-20, after the 2027-03-14 publish-by date the 60-day travel window calls for; move the publication date earlier.",
  "13 speakers, including Ines Calder, Rafa Sol and Max Feld, have no stated window and are treated as free all event; confirm before publishing.",
  "P20 and P23 are both Platform-track talks running head to head on D2 at 14:30; this same-track pair needs the audience-overlap pass before publication."
 ]
}

The page's check: kept - nothing to flag

Harbor DevDays (2 days, 3 rooms) - overlap

30 of 30 sessions placed in 3 rooms over 2 days; 1 clashes; clash depth overlap, publication versioned.

Input:

{
 "task": "overlap",
 "event": "Event: Harbor DevDays; 2 days from 2027-05-13; day window 09:00-17:30\nBreaks (venue-fixed): 10:40-11:00 Coffee; 12:40-13:40 Lunch; 15:20-15:40 Coffee\nRooms: Main Hall 420 seats, 0 min walk, floor G; Room B 160 seats, 4 min walk, floor 1; Room C 90 seats, 5 min walk, floor 1, available D1 09:50-17:30, D2\nVenue: corridor open; between sessions a room needs nothing\nAudience: mixed technical and non-technical no; fast-moving field yes; edition compounds yearly yes; attendees travel yes; tickets already on sale yes; organizer says two tracks share an audience no\nDates: today 2027-02-01; planned publication 2027-03-20",
 "grid": "D1 (2027-05-13):\nD1 09:00-09:50 PLENARY | Main Hall: K1 \"What ten years of on-call taught us\" (keynote; intro; 45 min; speakers Mara Quist; expected 380 of 420 seats)\nD1 09:50-10:40 | Main Hall: P01 \"Scaling Postgres at read-heavy loads\" (talk; track Data; intermediate; 45 min; speakers Ana Ruiz & Ben Okoro; expected 170 of 420 seats) | Room B: P12 \"Incident reviews people read\" (talk; track Platform; intro; 45 min; speakers Dee Harlow; expected 150 of 160 seats) | Room C: P22 \"Animations that respect motion settings\" (talk; track Frontend; intermediate; 45 min; speakers Rio Day; expected 60 of 90 seats)\nD1 10:40-11:00 BREAK Coffee\nD1 11:00-11:50 | Main Hall: empty | Room B: P21 \"Time zones will hurt you\" (talk; track Data; intermediate; 45 min; speakers Kai Mott; expected 150 of 160 seats) | Room C: W1 \"Hands-on: profiling Python services\" (workshop; track Platform; intermediate; 95 min; speakers Jon Abara & Fen Holt; expected 40 of 90 seats)\nD1 11:50-12:40 | Main Hall: empty | Room B: P19 \"Web performance budgets\" (talk; track Frontend; intro; 45 min; speakers Teo Vance; expected 140 of 160 seats) | Room C: W1 continues\nD1 12:40-13:40 BREAK Lunch\nD1 13:40-14:30 | Main Hall: P06 \"Rust in a Python shop\" (talk; track Platform; intermediate; 45 min; speakers Jon Abara; expected 200 of 420 seats) | Room B: P05 \"Accessible forms from the start\" (talk; track Frontend; intro; 45 min; speakers Kit Moreau; expected 110 of 160 seats) | Room C: empty\nD1 14:30-15:20 | Main Hall: P27 \"Shipping a design system\" (talk; track Frontend; intro; 45 min; speakers Noor Sami & Kit Moreau; expected 110 of 420 seats) | Room B: P04 \"Event sourcing in anger\" (talk; track Data; advanced; 45 min; speakers Lena Voss; expected 140 of 160 seats) | Room C: empty\nD1 15:20-15:40 BREAK Coffee\nD1 15:40-16:30 | Main Hall: P18 \"Data contracts that stick\" (talk; track Data; intermediate; 45 min; speakers Ivy Quarle; expected 100 of 420 seats) | Room B: P11 \"Hydration bugs and how to find them\" (talk; track Frontend; advanced; 45 min; speakers Lu Chen; expected 120 of 160 seats) | Room C: empty\nD1 16:30-17:20 | Main Hall: P25 \"Micro-frontends: a retrospective\" (talk; track Frontend; intermediate; 40 min; speakers Sam Ito; expected 100 of 420 seats) | Room B: P07 \"Query plans for humans\" (talk; track Data; intermediate; 45 min; speakers Ana Ruiz; expected 130 of 160 seats) | Room C: empty\nD2 (2027-05-14):\nD2 09:00-09:50 | Main Hall: empty | Room B: P09 \"Kubernetes cost without tears\" (talk; track Platform; intermediate; 45 min; speakers Priya Nand; expected 160 of 160 seats) | Room C: P16 \"Testing the untestable UI\" (talk; track Frontend; intermediate; 45 min; speakers Eli Park; expected 90 of 90 seats)\nD2 09:50-10:40 | Main Hall: empty | Room B: P24 \"Batch to streaming in one quarter\" (talk; track Data; advanced; 45 min; speakers Ola Brandt; expected 110 of 160 seats) | Room C: P03 \"The build cache that lied\" (talk; track Platform; intermediate; 45 min; speakers Rafa Sol; expected 90 of 90 seats)\nD2 10:40-11:00 BREAK Coffee\nD2 11:00-11:50 | Main Hall: empty | Room B: P10 \"Streaming joins explained\" (talk; track Data; advanced; 45 min; speakers Ola Brandt; expected 95 of 160 seats) | Room C: P08 \"CSS layers in practice\" (talk; track Frontend; intermediate; 45 min; speakers Sam Ito; expected 85 of 90 seats)\nD2 11:50-12:40 | Main Hall: empty | Room B: P15 \"Zero-downtime migrations\" (talk; track Data; advanced; 45 min; speakers Ben Okoro; expected 160 of 160 seats) | Room C: P14 \"Design tokens across three apps\" (talk; track Frontend; intro; 45 min; speakers Noor Sami; expected 70 of 90 seats)\nD2 12:40-13:40 BREAK Lunch\nD2 13:40-14:30 | Main Hall: P13 \"Vector search on a budget\" (talk; track Data; intermediate; 45 min; speakers Max Feld; expected 190 of 420 seats) | Room B: P17 \"SLOs your team believes\" (talk; track Platform; intermediate; 45 min; speakers Gus Lind; expected 130 of 160 seats) | Room C: empty\nD2 14:30-15:20 | Main Hall: P20 \"Platform teams as product teams\" (talk; track Platform; intro; 45 min; speakers Ines Calder & Gus Lind; expected 170 of 420 seats) | Room B: P23 \"Observability on a shoestring\" (talk; track Platform; intermediate; 45 min; speakers Fen Holt; expected 120 of 160 seats) | Room C: P26 \"Search relevance tuning\" (talk; track Data; advanced; 45 min; speakers Max Feld; expected 90 of 90 seats)\nD2 15:20-15:40 BREAK Coffee\nD2 15:40-16:30 | Main Hall: empty | Room B: P02 \"Feature flags without the flag debt\" (talk; track Platform; intro; 45 min; speakers Ines Calder; expected 120 of 160 seats) | Room C: empty\nD2 16:30-17:20 PLENARY | Main Hall: K2 \"A live demo you can break\" (keynote; intro; 45 min; speakers Tobi Arden; expected 340 of 420 seats)\nCo-speaker intersections: P01 D1 10:00-17:30, D2 09:00-17:30; P20 all hours; W1 D1 09:00-17:30, D2 09:00-12:40; P27 all hours\nSpeaker windows: Mara Quist D1; Tobi Arden D2; Ana Ruiz D1 08:00-17:30, D2; Ben Okoro D1 10:00-17:30, D2; Lena Voss D1 11:00-17:30; Jon Abara D1, D2 09:00-12:40; Priya Nand D2 09:00-13:00; Ola Brandt D2; Lu Chen D1; Fen Holt D1, D2; every other speaker is treated as free all event",
 "facts": "Slot standard: 45-minute talks in 50-minute slots (5 minutes inside each slot), computed from the buffer\nBuffer: internal - Slot-internal buffer (slots published longer than the talks they hold); 5 minutes wanted. The default: slots published 5 minutes longer than the 45-minute talks they hold - brief speakers on both numbers. Longest walk between rooms: 5 minutes across 2 floors.\nTrack-start alignment: synchronized - The corridor clears with 3 rooms changing at once; keep everyone arriving together at the plenary moments.\nClash depth: overlap - The mechanical checks plus the audience-overlap pass. Sessions from the same track run head to head - that promotes the audience-overlap pass on top of the three mechanical checks. Clashes found: 1 (room window 0, speaker window 1, same-room overlap 0, double-booked 0)\nFixed points placed first: K1 D1 09:00 plenary in Main Hall; K2 D2 16:30 plenary in Main Hall; P01 D1 09:50 pinned in Main Hall\nPlaced 30 of 30 sessions in 42 room-slots; plenary room Main Hall\nPublication posture: versioned - A multi-day, multi-track grid people build personal agendas against - publish early and carry a visible marker of what moved. Attendees travel: publish by 2027-03-14, 60 days out (self-set from flights booked about two months ahead). Lock-late is deleted for this event.\nDisruption order: 1. Protect the plenary or keynote slot first. 2. Protect the headline commitment the audience came for next. 3. Minimize how many other sessions the fix disturbs. 4. Lock the revised grid for the rest of the block instead of re-shuffling.\nMeasurement picks: Room-fit outcomes - sessions that overflowed and sessions that ran near-empty (self-set); Reported clashes - a survey question naming the two sessions attendees were torn between; Post-publication change count and last-change date (self-set)\nLate-held topical slots: 2 (one a day, self-set)\nCalibration (not targets): FOSDEM 2026 - 1,079 events, 37 rooms, 71 tracks; ~50-minute talks, lightning capped at 15; a 10-minute visible gap; PyCon US 2026 - 45-minute talks across five main rooms, staggered starts (11:00, 11:45, 12:30, 1:45...); keynotes 9:00-9:45, lunch about 12:30-1:15\nFindings (10):\n[fix] speaker_window (clash - speaker window): P01 sits D1 09:50-10:35 in Main Hall, but Ben Okoro is not available then (Ben Okoro: D1 10:00-17:30, D2) - the check on Ana Ruiz alone passes; the co-speaker intersection is D1 10:00-17:30, D2 09:00-17:30.\n[check] bespoke (slots): 1 session (P25 40 min) does not fit the 45-minute standard - make every session fit one slot length.\n[check] avail_missing (speakers): 13 speakers without a window (Ines Calder, Rafa Sol, Kit Moreau, Sam Ito, Dee Harlow, Max Feld...) - treated as free all event; ask before publishing.\n[info] intersection (speakers): Co-speaker intersections: P01 D1 10:00-17:30, D2 09:00-17:30; P20 all hours; W1 D1 09:00-17:30, D2 09:00-12:40; P27 all hours.\n[check] same_track (audience): P20 and P23 are both Platform and run head to head on D2 at 14:30.\n[info] bookend (pacing): D1 has no closing keynote - bookending each day in a format unlike the talks is the organizer's own experience, not a published source.\n[info] bookend (pacing): D2 has no opening keynote - bookending each day in a format unlike the talks is the organizer's own experience, not a published source.\n[fix] late_publish (publication): Planned publication 2027-03-20 is after 2027-03-14 - attendees travel, and a late grid cannot inform a flight already booked.\n[info] topical (publication): Fast-moving field: hold 2 slots (one a day, self-set) marked 'topic announced later' - slot, room and time fixed, the talk filled close to the event.\n[info] idle (grid): Minutes no slot fits: 17:20-17:30 at the end of the day."
}

Reply:

{
 "task": "overlap",
 "pairs": [
  {
   "a": "P20",
   "b": "P23",
   "when": "D2 14:30",
   "why": "Both are Platform-track sessions that would draw the same platform-engineering crowd, Platform teams as product teams at intro level and Observability on a shoestring at intermediate level, but the grid runs them at the same D2 14:30 start.",
   "move": {
    "session": "P20",
    "swap_with": "P27",
    "why": "P20 and P27 are both 45-minute Main Hall talks with unrestricted speaker windows, so trading D1 14:30 for D2 14:30 pulls Platform away from opposite P23 without changing any room assignment."
   }
  }
 ],
 "clear": "Every other time row seats sessions from different tracks, so only the D2 14:30 Platform pair needs attention and the rest of the grid can stand as laid out.",
 "note": "This pairing is judgment, not a computed check; ask attendees next edition which two sessions they were torn between to confirm or correct it."
}

The page's check: kept - nothing to flag

Open Data Summit (4 rooms, narrow corridor) - plan

16 of 16 sessions placed in 4 rooms over 1 days; 1 clashes; clash depth overlap, publication versioned.

Input:

{
 "task": "plan",
 "event": "Event: Open Data Summit; 1 day from 2027-09-18; day window 09:00-17:00\nBreaks (venue-fixed): 10:30-10:45 Coffee; 12:15-13:00 Lunch; 15:00-15:15 Coffee\nRooms: Auditorium 320 seats, 0 min walk, floor 2; Hall East 150 seats, 3 min walk, floor 2; Studio 60 seats, 3 min walk, floor 2, available D1 10:00-17:00; Lab 40 seats, 4 min walk, floor 2\nVenue: corridor narrow; between sessions a room needs furniture moved\nAudience: mixed technical and non-technical yes; fast-moving field no; edition compounds yearly yes; attendees travel no; tickets already on sale yes; organizer says two tracks share an audience yes\nDates: today 2027-06-01; planned publication not set",
 "grid": "D1 (2027-09-18):\nD1 09:00-09:45 PLENARY | Auditorium: K1 \"Opening: the state of open data\" (keynote; intro; 30 min; speakers Rhea Moss; expected 300 of 320 seats)\nD1 09:45-10:30 | Auditorium: C2 \"Notebooks to pipelines\" (talk; track Tools; intermediate; 30 min; speakers Ida Crane; expected 90 of 320 seats) | Hall East: B1 \"Privacy-preserving statistics\" (talk; track Privacy; advanced; 30 min; speakers Ada Fenn; expected 120 of 150 seats) | Studio: empty | Lab: empty\nD1 10:30-10:45 BREAK Coffee\nD1 10:45-11:30 | Auditorium: A4 \"Data portals that do not rot\" (talk; track Open data; intermediate; 30 min; speakers Cy Brook; expected 80 of 320 seats) | Hall East: B2 \"Differential privacy in production\" (talk; track Privacy; advanced; 30 min; speakers Ada Fenn; expected 100 of 150 seats) | Studio: empty | Lab: C1 \"Workshop: cleaning messy CSVs\" (workshop; track Tools; intro; 60 min; speakers Lee Tan; expected 35 of 40 seats)\nD1 11:30-12:15 | Auditorium: A3 \"Open data at city scale\" (panel; track Open data; intro; 30 min; speakers Ugo Lam & Pia Rask; expected 160 of 320 seats) | Hall East: B4 \"Synthetic data: when it helps\" (talk; track Privacy; intermediate; 30 min; speakers Mo Reyes; expected 110 of 150 seats) | Studio: empty | Lab: C1 continues\nD1 12:15-13:00 BREAK Lunch\nD1 13:00-13:45 | Auditorium: empty | Hall East: A2 \"Licensing for data releases\" (talk; track Open data; intermediate; 30 min; speakers Vera Holm; expected 90 of 150 seats) | Studio: M3 \"Documentation sprints\" (talk; track Community; intro; 30 min; speakers Ray Quill; expected 50 of 60 seats) | Lab: C3 \"Workshop: dashboards in an afternoon\" (workshop; track Tools; intro; 60 min; speakers Lee Tan & Ida Crane; expected 35 of 40 seats)\nD1 13:45-14:30 | Auditorium: empty | Hall East: M1 \"Civic tech funding panel\" (panel; track Community; intro; 30 min; speakers Pia Rask & Jo Wilde & Cy Brook; expected 130 of 150 seats) | Studio: M2 \"Running a volunteer data team\" (talk; track Community; intro; 30 min; speakers Nell Ober; expected 60 of 60 seats) | Lab: C3 continues\nD1 15:00-15:15 BREAK Coffee\nD1 15:15-16:00 | Auditorium: B3 \"Consent records done right\" (talk; track Privacy; intro; 30 min; speakers Jo Wilde; expected 70 of 320 seats) | Hall East: A1 \"Publishing open datasets people reuse\" (talk; track Open data; intro; 30 min; speakers Ugo Lam; expected 140 of 150 seats) | Studio: empty | Lab: empty\nD1 16:00-16:45 PLENARY | Auditorium: K2 \"Closing: what we keep\" (keynote; intro; 30 min; speakers Rhea Moss & Nell Ober; expected 280 of 320 seats)\nCo-speaker intersections: A3 D1 11:00-17:00; C3 D1 09:00-17:00; M1 D1 11:00-17:00; K2 all hours\nSpeaker windows: Pia Rask D1 11:00-17:00; Ada Fenn D1 09:00-12:30; Lee Tan D1 09:00-17:00; Ray Quill D1 14:00-17:00; every other speaker is treated as free all event",
 "facts": "Slot standard: 30-minute talks in 45-minute slots (15 minutes inside each slot), computed from the buffer\nBuffer: turnover - Room-turnover-aware gap (sized to what changes in the room); 15 minutes wanted. The room has to change between sessions (furniture moved), which promotes the room-turnover-aware gap: 15 minutes (self-set), and same-format sessions are kept together in a room. Longest walk between rooms: 4 minutes.\nTrack-start alignment: staggered - Simultaneous room changes would jam the narrow corridor, so offset every other room by 15 minutes (self-set) and move its breaks with it; the grid below is drawn aligned and the clash check holds within each room.\nClash depth: overlap - The mechanical checks plus the audience-overlap pass. You said two tracks share an audience - that promotes the audience-overlap pass on top of the three mechanical checks. Clashes found: 1 (room window 0, speaker window 1, same-room overlap 0, double-booked 0)\nFixed points placed first: K1 D1 09:00 plenary in Auditorium; M3 D1 13:00 pinned in Studio; K2 D1 16:00 plenary in Auditorium\nPlaced 16 of 16 sessions in 24 room-slots; plenary room Auditorium\nPublication posture: versioned - A change will land after tickets are sold, at a compounding annual event - publish early and carry a visible marker of what moved. No one travels: publish by 2027-09-04, 14 days out (self-set). Lock-late is deleted for this event.\nDisruption order: 1. Protect the plenary or keynote slot first. 2. Protect the headline commitment the audience came for next. 3. Minimize how many other sessions the fix disturbs. 4. Lock the revised grid for the rest of the block instead of re-shuffling.\nMeasurement picks: Room-fit outcomes - sessions that overflowed and sessions that ran near-empty (self-set); Reported clashes - a survey question naming the two sessions attendees were torn between; Post-publication change count and last-change date (self-set)\nCalibration (not targets): FOSDEM 2026 - 1,079 events, 37 rooms, 71 tracks; ~50-minute talks, lightning capped at 15; a 10-minute visible gap; PyCon US 2026 - 45-minute talks across five main rooms, staggered starts (11:00, 11:45, 12:30, 1:45...); keynotes 9:00-9:45, lunch about 12:30-1:15\nFindings (6):\n[fix] speaker_window (clash - speaker window): M3 sits D1 13:00-13:30 in Studio, but Ray Quill is not available then (Ray Quill: D1 14:00-17:00).\n[check] avail_missing (speakers): 8 speakers without a window (Rhea Moss, Ugo Lam, Vera Holm, Cy Brook, Jo Wilde, Mo Reyes...) - treated as free all event; ask before publishing.\n[info] intersection (speakers): Co-speaker intersections: A3 D1 11:00-17:00; C3 D1 09:00-17:00; M1 D1 11:00-17:00; K2 all hours.\n[check] same_track (audience): M1 and M2 are both Community and run head to head on D1 at 13:45.\n[info] weekend (pacing): The event starts on a weekend day - DevOpsDays recommends weekdays only, since a weekend competes with time people protect.\n[info] idle (grid): Minutes no slot fits: 14:30-15:00 before coffee; 16:45-17:00 at the end of the day."
}

Reply:

{
 "task": "plan",
 "summary": "One day across the Auditorium, Hall East, Studio and Lab, 16 sessions placed between keynotes K1 and K2; the first thing to settle is M3's speaker-window clash, since Ray Quill is free only from 14:00.",
 "slots": {
  "standard": "30-minute talks in 45-minute slots",
  "brief": "Your talk is 30 minutes inside a 45-minute slot, so do not fill the whole slot."
 },
 "fixed_points": [
  {
   "id": "K1",
   "when": "D1 09:00",
   "why": "K1 is the opening keynote, a bookend in a different format from the talks that gathers everyone together before the rooms split into tracks."
  },
  {
   "id": "M3",
   "when": "D1 13:00",
   "why": "M3 is pinned here by the organizer, opening the Studio room's use of the day right after the lunch break."
  },
  {
   "id": "K2",
   "when": "D1 16:00",
   "why": "K2 is the closing keynote, a bookend in a different format from the talks that gathers everyone together again before the day ends."
  }
 ],
 "breaks": [
  "10:30-10:45 Coffee - brings all tracks back together before the next slot.",
  "12:15-13:00 Lunch - brings all tracks back together before the afternoon sessions.",
  "15:00-15:15 Coffee - brings all tracks back together before the closing keynote."
 ],
 "rooms": [
  {
   "room": "Auditorium",
   "holds": "Auditorium seats 320 and holds K1, K2, C2, A4, A3 and B3, matched up to the largest expected audience of 300 for K1, well under capacity throughout."
  },
  {
   "room": "Hall East",
   "holds": "Hall East seats 150 and holds B1, B2, B4, A2, M1 and A1, matched up to the largest expected audience of 140 of 150 for A1, without overflow."
  },
  {
   "room": "Studio",
   "holds": "Studio seats 60, available D1 10:00-17:00, and holds M3 and M2, filling exactly to 60 of 60 for M2."
  },
  {
   "room": "Lab",
   "holds": "Lab seats 40 and holds C1 and C3, both expected at 35 of 40 seats, with room to spare."
  }
 ],
 "clashes": {
  "depth": "overlap",
  "findings": [
   "Speaker-window clash: M3 runs D1 13:00-13:45 in Studio, but Ray Quill is not available until 14:00; move M3 to any Studio slot at or after 14:00.",
   "Audience-overlap: M1 and M2 are both Community sessions running head to head D1 13:45; separate them by moving one to a different time row."
  ],
  "rerun": "Re-run all four clash checks, including the audience-overlap pass, after any change to the grid."
 },
 "buffer": {
  "rung": "turnover",
  "minutes": 15,
  "walking": "Checked against the longest walk between rooms, 4 minutes, which fits comfortably inside the 15-minute gap."
 },
 "alignment": {
  "pick": "staggered",
  "why": "Simultaneous room changes would jam the narrow corridor, so every other room is offset by 15 minutes and its breaks move with it."
 },
 "pacing": [
  "The 13:00 slot right after the lunch break sits in the circadian post-lunch dip (sourced).",
  "The 15:15 slot before the closing keynote is this conference's weakest-attended position, matching the pattern seen elsewhere (sourced).",
  "Starting and ending the day with keynotes, a different format from the talks around them, reflects the organizers' own experience rather than a published source (judgment)."
 ],
 "disruption": [
  "Protect the plenary keynote slots first: keep K1 fixed at D1 09:00 and K2 fixed at D1 16:00 whatever else moves.",
  "Protect the headline commitment next: A3, the panel drawing the largest non-keynote crowd at 160 expected, is the session the audience most organized their day around (judgment call).",
  "Minimize disturbance: when fixing the Ray Quill availability clash on M3, move only M3 rather than reshuffling its Studio neighbors.",
  "Lock the revised grid for the rest of the day once changed, instead of continuing to re-shuffle other sessions."
 ],
 "publication": {
  "posture": "versioned",
  "date": "2027-09-04",
  "why": "Tickets are already on sale and the edition compounds yearly, so release early but carry a visible marker of anything that moves afterward."
 },
 "metrics": [
  "Room-fit outcomes, sessions that overflowed or ran near-empty: a recurring mismatch next edition would mean resizing that session's room.",
  "Reported clashes, a survey question naming the two sessions attendees were torn between: a repeated pair would move one of them to a different time row next edition.",
  "Post-publication change count and last-change date: a high count or a late last change would tighten the publish-by date next edition."
 ],
 "caveats": [
  "M3 is scheduled D1 13:00-13:45 in Studio, but Ray Quill is not available until 14:00 - move M3 or swap it before publishing.",
  "8 speakers have no stated availability window and are currently treated as free all event - confirm with them before publishing.",
  "M1 and M2 are both Community sessions running head to head D1 13:45 - check whether that is acceptable for this shared audience."
 ]
}

The page's check: kept - nothing to flag

Open Data Summit (4 rooms, narrow corridor) - overlap

16 of 16 sessions placed in 4 rooms over 1 days; 1 clashes; clash depth overlap, publication versioned.

Input:

{
 "task": "overlap",
 "event": "Event: Open Data Summit; 1 day from 2027-09-18; day window 09:00-17:00\nBreaks (venue-fixed): 10:30-10:45 Coffee; 12:15-13:00 Lunch; 15:00-15:15 Coffee\nRooms: Auditorium 320 seats, 0 min walk, floor 2; Hall East 150 seats, 3 min walk, floor 2; Studio 60 seats, 3 min walk, floor 2, available D1 10:00-17:00; Lab 40 seats, 4 min walk, floor 2\nVenue: corridor narrow; between sessions a room needs furniture moved\nAudience: mixed technical and non-technical yes; fast-moving field no; edition compounds yearly yes; attendees travel no; tickets already on sale yes; organizer says two tracks share an audience yes\nDates: today 2027-06-01; planned publication not set",
 "grid": "D1 (2027-09-18):\nD1 09:00-09:45 PLENARY | Auditorium: K1 \"Opening: the state of open data\" (keynote; intro; 30 min; speakers Rhea Moss; expected 300 of 320 seats)\nD1 09:45-10:30 | Auditorium: C2 \"Notebooks to pipelines\" (talk; track Tools; intermediate; 30 min; speakers Ida Crane; expected 90 of 320 seats) | Hall East: B1 \"Privacy-preserving statistics\" (talk; track Privacy; advanced; 30 min; speakers Ada Fenn; expected 120 of 150 seats) | Studio: empty | Lab: empty\nD1 10:30-10:45 BREAK Coffee\nD1 10:45-11:30 | Auditorium: A4 \"Data portals that do not rot\" (talk; track Open data; intermediate; 30 min; speakers Cy Brook; expected 80 of 320 seats) | Hall East: B2 \"Differential privacy in production\" (talk; track Privacy; advanced; 30 min; speakers Ada Fenn; expected 100 of 150 seats) | Studio: empty | Lab: C1 \"Workshop: cleaning messy CSVs\" (workshop; track Tools; intro; 60 min; speakers Lee Tan; expected 35 of 40 seats)\nD1 11:30-12:15 | Auditorium: A3 \"Open data at city scale\" (panel; track Open data; intro; 30 min; speakers Ugo Lam & Pia Rask; expected 160 of 320 seats) | Hall East: B4 \"Synthetic data: when it helps\" (talk; track Privacy; intermediate; 30 min; speakers Mo Reyes; expected 110 of 150 seats) | Studio: empty | Lab: C1 continues\nD1 12:15-13:00 BREAK Lunch\nD1 13:00-13:45 | Auditorium: empty | Hall East: A2 \"Licensing for data releases\" (talk; track Open data; intermediate; 30 min; speakers Vera Holm; expected 90 of 150 seats) | Studio: M3 \"Documentation sprints\" (talk; track Community; intro; 30 min; speakers Ray Quill; expected 50 of 60 seats) | Lab: C3 \"Workshop: dashboards in an afternoon\" (workshop; track Tools; intro; 60 min; speakers Lee Tan & Ida Crane; expected 35 of 40 seats)\nD1 13:45-14:30 | Auditorium: empty | Hall East: M1 \"Civic tech funding panel\" (panel; track Community; intro; 30 min; speakers Pia Rask & Jo Wilde & Cy Brook; expected 130 of 150 seats) | Studio: M2 \"Running a volunteer data team\" (talk; track Community; intro; 30 min; speakers Nell Ober; expected 60 of 60 seats) | Lab: C3 continues\nD1 15:00-15:15 BREAK Coffee\nD1 15:15-16:00 | Auditorium: B3 \"Consent records done right\" (talk; track Privacy; intro; 30 min; speakers Jo Wilde; expected 70 of 320 seats) | Hall East: A1 \"Publishing open datasets people reuse\" (talk; track Open data; intro; 30 min; speakers Ugo Lam; expected 140 of 150 seats) | Studio: empty | Lab: empty\nD1 16:00-16:45 PLENARY | Auditorium: K2 \"Closing: what we keep\" (keynote; intro; 30 min; speakers Rhea Moss & Nell Ober; expected 280 of 320 seats)\nCo-speaker intersections: A3 D1 11:00-17:00; C3 D1 09:00-17:00; M1 D1 11:00-17:00; K2 all hours\nSpeaker windows: Pia Rask D1 11:00-17:00; Ada Fenn D1 09:00-12:30; Lee Tan D1 09:00-17:00; Ray Quill D1 14:00-17:00; every other speaker is treated as free all event",
 "facts": "Slot standard: 30-minute talks in 45-minute slots (15 minutes inside each slot), computed from the buffer\nBuffer: turnover - Room-turnover-aware gap (sized to what changes in the room); 15 minutes wanted. The room has to change between sessions (furniture moved), which promotes the room-turnover-aware gap: 15 minutes (self-set), and same-format sessions are kept together in a room. Longest walk between rooms: 4 minutes.\nTrack-start alignment: staggered - Simultaneous room changes would jam the narrow corridor, so offset every other room by 15 minutes (self-set) and move its breaks with it; the grid below is drawn aligned and the clash check holds within each room.\nClash depth: overlap - The mechanical checks plus the audience-overlap pass. You said two tracks share an audience - that promotes the audience-overlap pass on top of the three mechanical checks. Clashes found: 1 (room window 0, speaker window 1, same-room overlap 0, double-booked 0)\nFixed points placed first: K1 D1 09:00 plenary in Auditorium; M3 D1 13:00 pinned in Studio; K2 D1 16:00 plenary in Auditorium\nPlaced 16 of 16 sessions in 24 room-slots; plenary room Auditorium\nPublication posture: versioned - A change will land after tickets are sold, at a compounding annual event - publish early and carry a visible marker of what moved. No one travels: publish by 2027-09-04, 14 days out (self-set). Lock-late is deleted for this event.\nDisruption order: 1. Protect the plenary or keynote slot first. 2. Protect the headline commitment the audience came for next. 3. Minimize how many other sessions the fix disturbs. 4. Lock the revised grid for the rest of the block instead of re-shuffling.\nMeasurement picks: Room-fit outcomes - sessions that overflowed and sessions that ran near-empty (self-set); Reported clashes - a survey question naming the two sessions attendees were torn between; Post-publication change count and last-change date (self-set)\nCalibration (not targets): FOSDEM 2026 - 1,079 events, 37 rooms, 71 tracks; ~50-minute talks, lightning capped at 15; a 10-minute visible gap; PyCon US 2026 - 45-minute talks across five main rooms, staggered starts (11:00, 11:45, 12:30, 1:45...); keynotes 9:00-9:45, lunch about 12:30-1:15\nFindings (6):\n[fix] speaker_window (clash - speaker window): M3 sits D1 13:00-13:30 in Studio, but Ray Quill is not available then (Ray Quill: D1 14:00-17:00).\n[check] avail_missing (speakers): 8 speakers without a window (Rhea Moss, Ugo Lam, Vera Holm, Cy Brook, Jo Wilde, Mo Reyes...) - treated as free all event; ask before publishing.\n[info] intersection (speakers): Co-speaker intersections: A3 D1 11:00-17:00; C3 D1 09:00-17:00; M1 D1 11:00-17:00; K2 all hours.\n[check] same_track (audience): M1 and M2 are both Community and run head to head on D1 at 13:45.\n[info] weekend (pacing): The event starts on a weekend day - DevOpsDays recommends weekdays only, since a weekend competes with time people protect.\n[info] idle (grid): Minutes no slot fits: 14:30-15:00 before coffee; 16:45-17:00 at the end of the day."
}

Reply:

{
 "task": "overlap",
 "pairs": [
  {
   "a": "M1",
   "b": "M2",
   "when": "D1 13:45",
   "why": "M1 and M2 are both introductory Community sessions - Civic tech funding panel and Running a volunteer data team - so civic-tech organizers and volunteer coordinators would want to be in both rooms at once.",
   "move": {
    "session": "M1",
    "swap_with": "A2",
    "why": "Swapping M1 into A2's 13:00 slot puts it in Hall East (150 seats, enough for its 130), stays inside Pia Rask's D1 11:00-17:00 window with Jo Wilde and Cy Brook free then, and sends A2 to 13:45 in Hall East (150 seats, enough for its 90), so M1 no longer runs against M2."
   }
  },
  {
   "a": "B3",
   "b": "A1",
   "when": "D1 15:15",
   "why": "B3 and A1 are both introductory sessions - Consent records done right in Privacy and Publishing open datasets people reuse in Open data - so attendees weighing how to release data responsibly would want both.",
   "move": {
    "session": "B3",
    "swap_with": "M1",
    "why": "Swapping B3 into M1's 13:45 slot puts it in Hall East (150 seats, enough for its 70) where Jo Wilde is free all event, and sends M1 to the Auditorium at 15:15 (320 seats, enough for its 130) inside Pia Rask's D1 11:00-17:00 window, so B3 no longer runs against A1."
   }
  }
 ],
 "clear": "Keynotes K1 and K2, the Tools workshops C1 and C3 running beside differently themed tracks, and the 13:00 grouping of A2 and M3 draw clearly separate audiences and do not need moving.",
 "note": "This overlap read is judgment, not measurement; next edition ask attendees which concurrent sessions they most wanted to attend together, to confirm or correct these picks."
}

The page's check: kept - nothing to flag

Backend Evening (one room, mixed) - plan

5 of 5 sessions placed in 1 rooms over 1 days; 0 clashes; clash depth availability, publication early.

Input:

{
 "task": "plan",
 "event": "Event: Backend Evening #14; 1 day from 2027-04-07; day window 18:30-21:00\nBreaks (venue-fixed): 19:30-19:45 Pizza\nRooms: Main room 80 seats\nVenue: corridor open; between sessions a room needs nothing\nAudience: mixed technical and non-technical yes; fast-moving field no; edition compounds yearly no; attendees travel no; tickets already on sale no; organizer says two tracks share an audience no\nDates: today 2027-03-20; planned publication not set",
 "grid": "D1 (2027-04-07):\nD1 18:30-19:00 | Main room: T2 \"What a database index actually is\" (talk; intro; 25 min; speakers Bea Lund; expected 70 of 80 seats)\nD1 19:00-19:30 | Main room: T3 \"Caching layers we regret\" (talk; intermediate; 25 min; speakers Sid Okafor; expected 70 of 80 seats)\nD1 19:30-19:45 BREAK Pizza\nD1 19:45-20:15 | Main room: L1 \"Lightning: my first open-source PR\" (lightning; intro; 5 min; speakers Ami Kaur; expected 70 of 80 seats) then L2 \"Lightning: a terminal trick a day\" (lightning; intro; 5 min; speakers Ty Sorel; expected 70 of 80 seats)\nD1 20:15-20:45 | Main room: T1 \"Inside the garbage collector\" (talk; advanced; 25 min; speakers Oren Vale; expected 70 of 80 seats)\nSpeaker windows: none given; every other speaker is treated as free all event",
 "facts": "Slot standard: 25-minute talks in 30-minute slots (5 minutes inside each slot), as entered\nBuffer: internal - Slot-internal buffer (slots published longer than the talks they hold); 5 minutes wanted. The default: slots published 5 minutes longer than the 25-minute talks they hold - brief speakers on both numbers. No walking times given.\nTrack-start alignment: single - One room - every session starts when the one before it ends.\nClash depth: availability - Speaker availability only (single track - nothing runs at once). One room: nothing runs at once, so the overlap and double-booking checks and the audience-overlap pass are deleted; the live check is whether each speaker is in the building. Clashes found: 0 (room window 0, speaker window 0, same-room overlap 0, double-booked 0)\nFixed points placed first: none\nPlaced 5 of 5 sessions in 4 room-slots; plenary room Main room\nPublication posture: early - Release early and iterate: the published grid is a living document. Lock-late survives only for a same-city meetup nobody travels to. No one travels: publish by 2027-03-24, 14 days out (self-set).\nDisruption order: 1. Protect the plenary or keynote slot first. 2. Protect the headline commitment the audience came for next. 3. Minimize how many other sessions the fix disturbs. 4. Lock the revised grid for the rest of the block instead of re-shuffling.\nMeasurement picks: Room-fit outcomes - sessions that overflowed and sessions that ran near-empty (self-set); No-show rate per slot, recorded by slot position; On-time start rate per room (self-set threshold)\nCalibration (not targets): FOSDEM 2026 - 1,079 events, 37 rooms, 71 tracks; ~50-minute talks, lightning capped at 15; a 10-minute visible gap; PyCon US 2026 - 45-minute talks across five main rooms, staggered starts (11:00, 11:45, 12:30, 1:45...); keynotes 9:00-9:45, lunch about 12:30-1:15\nFindings (5):\n[check] no_avail (speakers): No speaker availability pasted - every speaker is treated as free all event. Collect the windows before laying anything; a conflict found after publication costs a public correction.\n[info] single_deletes (clashes): Single track: same-room overlap, speaker double-booking and the audience-overlap pass are deleted - only availability can fail. One overrun moves the whole day.\n[info] bookend (pacing): D1 has no opening or closing keynote - bookending each day in a format unlike the talks is the organizer's own experience, not a published source.\n[info] graveyard (pacing): The last slot of the last day holds T1 - the worst-attended position at the conferences studied (direction, not magnitude); the broad-to-advanced order puts the deepest talk there on purpose - accept that trade for an evening where the specialists stay, and watch the no-show rate per slot.\n[info] idle (grid): Minutes no slot fits: 20:45-21:00 at the end of the day."
}

Reply:

{
 "task": "plan",
 "summary": "One room, one evening, 4 slots holding 5 sessions around a fixed pizza break; the first thing to settle is collecting real speaker availability windows before the grid locks.",
 "slots": {
  "standard": "25-minute talks in 30-minute slots",
  "brief": "Your talk should run 25 minutes; the slot on the grid is 30 minutes, so the extra time is for changeover, not more talking."
 },
 "fixed_points": [],
 "breaks": [
  "19:30-19:45 Pizza, the evening's one venue-fixed break; with only one track running, there is nothing in parallel for it to realign."
 ],
 "rooms": [
  {
   "room": "Main room",
   "holds": "Main room holds all 5 sessions against an audience estimated at 70 of its 80 seats each time, with no overflow."
  }
 ],
 "clashes": {
  "depth": "availability",
  "findings": [],
  "rerun": "Check again whenever anything in this grid changes, since availability is the only thing that can break here."
 },
 "buffer": {
  "rung": "internal",
  "minutes": 5,
  "walking": "No walking distance was given to check the buffer against, since every session runs in the same Main room."
 },
 "alignment": {
  "pick": "single",
  "why": "With only one room, each session simply starts when the one before it ends, so there is no corridor to stagger or synchronize."
 },
 "pacing": [
  "This evening's last slot holds T1, its advanced talk - direction that lines up with weaker attendance in that position at other conferences studied (sourced).",
  "The order runs intro (T2), intermediate (T3), intro lightning talks (L1, L2), then advanced (T1) - a deliberate broad-to-advanced climb that accepts a quieter finish (judgment).",
  "Nothing in a different format bookends this evening at open or close, since no keynote was placed (judgment)."
 ],
 "disruption": [
  "Protect the 19:30-19:45 Pizza break first - it is the evening's one venue-fixed point, so any fix works around it, not through it.",
  "Protect T1, 'Inside the garbage collector,' as the headline commitment next - it is the advanced talk placed last on purpose, for the specialists who stay to the end.",
  "Then favor the fix that disturbs the fewest of the other sessions in Main room.",
  "Finally, lock the revised running order for the rest of this one-day evening instead of changing it again."
 ],
 "publication": {
  "posture": "early",
  "date": "2027-03-24",
  "why": "Since nobody is traveling to this same-city meetup, the grid can go out well ahead of the event and still be adjusted afterward, publishing 14 days before the night itself."
 },
 "metrics": [
  "Room-fit outcomes: track which sessions overflow Main room's 80 seats or run far under the expected 70, and resize the room pick next edition.",
  "No-show rate per slot, recorded by slot position: a high rate in the last slot would move the advanced talk out of the closing spot next edition.",
  "On-time start rate per room: persistent lateness in Main room would add visible minutes to the 5-minute buffer already built into each slot."
 ],
 "caveats": [
  "No speaker availability was pasted - every speaker is treated as free all event; collect real windows before the grid locks, since a conflict found after publication costs a public correction."
 ]
}

The page's check: kept - nothing to flag

The grid CSV for the first sample

day,date,start,end,room,id,title,speakers,format,track,level,expected,capacity
D1,2027-05-13,09:00,09:45,Main Hall,K1,What ten years of on-call taught us,Mara Quist,keynote,,intro,380,420
D1,2027-05-13,09:50,10:35,Main Hall,P01,Scaling Postgres at read-heavy loads,Ana Ruiz & Ben Okoro,talk,Data,intermediate,170,420
D1,2027-05-13,09:50,10:35,Room B,P12,Incident reviews people read,Dee Harlow,talk,Platform,intro,150,160
D1,2027-05-13,09:50,10:35,Room C,P22,Animations that respect motion settings,Rio Day,talk,Frontend,intermediate,60,90
D1,2027-05-13,11:00,11:45,Room B,P21,Time zones will hurt you,Kai Mott,talk,Data,intermediate,150,160
D1,2027-05-13,11:00,12:35,Room C,W1,Hands-on: profiling Python services,Jon Abara & Fen Holt,workshop,Platform,intermediate,40,90
D1,2027-05-13,11:50,12:35,Room B,P19,Web performance budgets,Teo Vance,talk,Frontend,intro,140,160
D1,2027-05-13,13:40,14:25,Main Hall,P06,Rust in a Python shop,Jon Abara,talk,Platform,intermediate,200,420
D1,2027-05-13,13:40,14:25,Room B,P05,Accessible forms from the start,Kit Moreau,talk,Frontend,intro,110,160
D1,2027-05-13,14:30,15:15,Main Hall,P27,Shipping a design system,Noor Sami & Kit Moreau,talk,Frontend,intro,110,420
D1,2027-05-13,14:30,15:15,Room B,P04,Event sourcing in anger,Lena Voss,talk,Data,advanced,140,160
D1,2027-05-13,15:40,16:25,Main Hall,P18,Data contracts that stick,Ivy Quarle,talk,Data,intermediate,100,420
D1,2027-05-13,15:40,16:25,Room B,P11,Hydration bugs and how to find them,Lu Chen,talk,Frontend,advanced,120,160
D1,2027-05-13,16:30,17:10,Main Hall,P25,Micro-frontends: a retrospective,Sam Ito,talk,Frontend,intermediate,100,420
D1,2027-05-13,16:30,17:15,Room B,P07,Query plans for humans,Ana Ruiz,talk,Data,intermediate,130,160
D2,2027-05-14,09:00,09:45,Room B,P09,Kubernetes cost without tears,Priya Nand,talk,Platform,intermediate,160,160
D2,2027-05-14,09:00,09:45,Room C,P16,Testing the untestable UI,Eli Park,talk,Frontend,intermediate,90,90
D2,2027-05-14,09:50,10:35,Room B,P24,Batch to streaming in one quarter,Ola Brandt,talk,Data,advanced,110,160
D2,2027-05-14,09:50,10:35,Room C,P03,The build cache that lied,Rafa Sol,talk,Platform,intermediate,90,90
D2,2027-05-14,11:00,11:45,Room B,P10,Streaming joins explained,Ola Brandt,talk,Data,advanced,95,160
D2,2027-05-14,11:00,11:45,Room C,P08,CSS layers in practice,Sam Ito,talk,Frontend,intermediate,85,90
D2,2027-05-14,11:50,12:35,Room B,P15,Zero-downtime migrations,Ben Okoro,talk,Data,advanced,160,160
D2,2027-05-14,11:50,12:35,Room C,P14,Design tokens across three apps,Noor Sami,talk,Frontend,intro,70,90
D2,2027-05-14,13:40,14:25,Main Hall,P13,Vector search on a budget,Max Feld,talk,Data,intermediate,190,420
D2,2027-05-14,13:40,14:25,Room B,P17,SLOs your team believes,Gus Lind,talk,Platform,intermediate,130,160
D2,2027-05-14,14:30,15:15,Main Hall,P20,Platform teams as product teams,Ines Calder & Gus Lind,talk,Platform,intro,170,420
D2,2027-05-14,14:30,15:15,Room B,P23,Observability on a shoestring,Fen Holt,talk,Platform,intermediate,120,160
D2,2027-05-14,14:30,15:15,Room C,P26,Search relevance tuning,Max Feld,talk,Data,advanced,90,90
D2,2027-05-14,15:40,16:25,Room B,P02,Feature flags without the flag debt,Ines Calder,talk,Platform,intro,120,160
D2,2027-05-14,16:30,17:15,Main Hall,K2,A live demo you can break,Tobi Arden,keynote,,intro,340,420

Build the input yourself

Load the engine in node (global.window = global; require("./slotkit.js"); require("./slotreply.js")), then:

const K = SlotKit, R = SlotReply;
const f = K.form({ name: "My Conf", days: "2", first: "2027-05-13", start: "09:00", end: "17:30", talk: "45", breaks: "10:40 20 Coffee\n12:40 60 Lunch",
  rooms: fs.readFileSync("rooms.csv", "utf8"), sessions: fs.readFileSync("sessions.csv", "utf8"), avail: "Ben Okoro: D1 10:00-17:30; D2" });
// f.grid: [{day, rows: [{kind: slot|break|plenary, a, b, cells: {room: [ids]}}]}]   f.placed, f.unplaced
// f.clash: {room_window, speaker_window, room_overlap, double_booked}   f.buffer, f.gap, f.align, f.depth, f.posture, f.publishBy, f.findings
K.gridCSV(f)                                   // day, date, start, end, room, id, title, speakers, ...
K.trySwap(f, "P23", "P11")                     // {ok, why} - the same check the page runs on every proposed swap
const b = K.buildInput(f, "plan");             // or "overlap" (multi-track grids only)
const wire = K.toWire(b.input);                // POST this to /estimate and /run
// then: const reply = R.normalize(R.parseReply(job.output.output), "plan");
// R.check(reply, b)                           // {status: kept or flagged, notes}

Get a token for the steps below from /tokens.html.

Step 1 — a tiny client helper

One function that sends JSON and unwraps the response. Paste a personal token from /tokens.html, or leave it empty and mint a guest token in step 2.

BASE="https://api.skillsafe.ai/v1/app-api"
TOKEN="paste-your-token-here"   # from https://slot-desk.skillsafe.ai/tokens.html
api() { # api METHOD PATH [JSON-BODY]
  curl -s -X "$1" "$BASE$2" -H "Content-Type: application/json" \
    ${TOKEN:+-H "Authorization: Bearer $TOKEN"} ${3:+--data "$3"}
}

Step 2 — a token

A guest token is enough for /me and /estimate. A run is metered, so it needs a personal token: sign in on /tokens.html and copy it from there.

# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN=$(curl -s -X POST "$BASE/guest" -H "Content-Type: application/json" -d '{"slug":"slot-desk"}' | jq -r '.data.token')

Step 3 — GET /me

Who the token is (subject_type: user or guest) and the credit balance.

api GET /me | jq '.data | {subject_type, credits}' 

Step 4 — POST /estimate

Free. The body is the run input itself, the bare object (never wrapped in {"input": ...}). hold_credits is a reservation, not the price; min_credits is what the balance must cover; model_alias reads gpt-terra.

# input.json: the run input object - {"task": "plan", "event": "Event: ...; 2 days from 2027-05-13; day window 09:00-17:30 ...", "grid": "D1 09:00-09:50 PLENARY | Main Hall: K1 ...", "facts": "Slot standard: 45-minute talks in 50-minute slots ..."}
# - see the input table
api POST /estimate "$(cat input.json)" | jq '.data | {hold_credits, min_credits, model, model_alias, markup_bps, warnings}' 

Step 5 — POST /run, then poll the job

Send an Idempotency-Key built from the lane and the input: a retry with the same key never bills twice. The page uses slot-desk:<task>:<inputHash>:a<attempt> - the lane is part of the key - and its one automatic reformat retry is a new attempt number, named in the page as one extra run. A plan carries summary, fixed_points and caveats among its sections; an overlap pass carries pairs, clear and note. The code below prints either.

KEY="slot-desk:plan:$(shasum -a 256 input.json | cut -c1-16):a1"
JOB=$(curl -s -X POST "$BASE/run" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $KEY" --data @input.json | jq -r '.data.job_id')
while :; do
  J=$(api GET "/jobs/$JOB"); S=$(echo "$J" | jq -r '.data.status')
  case "$S" in succeeded|failed|cancelled) break;; esac; sleep 2
done
echo "$J" | jq -r '.data.output.output' > reply.json   # one JSON object, the reply contract
echo "$J" | jq '.data | {charged_credits, truncated}'
jq -r '.summary // .format, .note // .summary, ((.fixed_points // .pairs)[] | "\(.id // .a): \(.when // .why)")' reply.json
jq -r '.caveats // .note // empty' reply.json   # caveats (plan) or the note for the program chair (overlap)

Step 6 — POST /run-stream

The same run as Server-Sent Events, with the same input.json. Browsers receive progress ticks rather than text deltas; the final done event carries the reply.

# Server-Sent Events: tick/delta events while the job runs, then a final event with the job
curl -N -s -X POST "$BASE/run-stream" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: slot-desk:plan:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json