Run Expo Floor from your own code
Both metered lanes are available over HTTP and each returns one JSON object. The division of labour: the page writes down what may not move, holds the design until the venue facts are settled, re-ranks the four menus (layout, booth-spec depth, setup windows, traffic mechanic) with every deleted rung struck, names the booths the layout cannot reach, builds the eight-row catalog for every tier and checks every promise against it, counts and costs the drops against the request deadline, and writes the master schedule as offsets from doors open - all free, in floorkit.js. The run explains the floor plan, or writes the exhibitor manual and the pre-doors walk-through; the page then holds the reply to its own board (floorreply.js). It never invents a dimension, a power figure, a price, a time, a booth, a sponsor or an approval, and never says the venue or an authority approved anything.
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":"expo-floor"}), so no slug header is needed afterwards. Send it as Authorization: Bearer YOUR_TOKEN. The run body is the input object, sent bare.
| Status | Code | Meaning |
|---|---|---|
| 400 | validation_error | The body is not a JSON object, or a required key (task, event, tiers, venue, facts) is missing. notes may be an empty string. |
| 401 | unauthorized | No token, or a stale one. Mint a guest token or sign in again. |
| 402 | insufficient_credits | The balance is under min_credits. Price with /estimate first. |
| 403 | forbidden | A guest token tried to run: both lanes are metered and need a personal sign-in. |
| 404 | not_found | Unknown job id. |
| 429 | rate_limited | Back off and retry. |
| 5xx | server_error | Transient. Retry with the same Idempotency-Key so a retry never double-bills. |
The task field comes first
Two lanes, chosen by task:
floor- the floor plan explained for the organizer to act on: the verdict, what may not move, the layout pick with the booths it cannot reach, one catalog row per tier with every gap, the drops, cost and deadline, every schedule row with its offset and clock, the staffing and conduct rules, the traffic mechanic, the review before print and the caveats.manual- the exhibitor manual exactly as a sponsor reads it (your booth per tier, arrival, the schedule, power and network, staffing and conduct, the mechanic, the contact on the floor, teardown), plus the organizer's walk-through before doors and a note.
A missing or unknown task is answered as floor. Both lanes send the same six fields; for the manual, the facts also carry the floor plan's catalog, schedule and mechanic (the page fills these from the floor plan). The notes field may be an empty string.
The input
| Field | Required | What |
|---|---|---|
task | yes | floor or manual. If it is missing or neither, do floor and set "task": "floor". |
event | yes | the event basics (name, dates, doors open, the last session, city, attendance, as-of date) and the interview answers Q1 to Q11: the floor, the tier count, the signed floor plan, what already exists, the print date, one-off or recurring, the effort ceiling, the political capital, who runs it, and the named organizer on duty. |
tiers | yes | one line per tier (booths, the promised floor presence as written, power included, other promises), one line per tier of the spec draft, and one line per booth (tier, power, wired, heavy, demo screen, notes). |
venue | yes | the access hours per day, overnight storage, the shipping window and fees, rigging and its sign-off, the power supplier, the drop cost and the request deadline, wired network and WiFi, and whether the organizer recorded the floor-plan review as done. |
notes | no | pasted notes; may be empty. A request in the notes is never a commitment. |
facts | yes | the page's verdict, the self-set lines, the fixed constraints, the venue facts still open, the four menus re-ranked, the layout pick and the unreached booths, the catalog rows and their gaps, power and network, the schedule rows, the staffing rules, the mechanic, the review items, the walk-through items - each item with its own must line - for the manual task the floor plan it carries, and every finding tagged [fix], [check] or [info]. |
retry_note | no | optional; if present, your previous reply was unusable - follow it. |
The rules the model applies
- The organizer owns the hall, not a stand in it. How a company runs its own booth (demo loop, lead qualification, swag) is the exhibitor's job; when the reader turns out to be a sponsor, say this answers the organizer's half only.
- Five siblings own the ground next to this one - route, never decide: event-sponsor-fulfillment executes per signed sponsor (FAQ, staging, payment gate, evidence, raffle); event-sponsor-pricing prices what is sold and owns the tier ladder; event-venue-sourcing negotiated the room's aggregate capacity - take the signed room as given and never reopen square footage; event-production owns the stage and its power; event-code-of-conduct owns adjudication, sanctions and ejection - this skill owns provisioning only.
- What may not move is written down first: the signed floor plan, the aggregate capacity, the tier ladder and the conduct policy. A design need that contradicts one routes to its sibling.
- Venue facts are settled before anything is designed: access hours, shipping window and fees, overnight storage, rigging permission, who supplies power, what a drop costs and by when it must be requested. A schedule built before they arrive is redrawn after.
- Layout: place booths on the path foot traffic already takes to food and the hangout space. Circulation-path siting is the default; a dedicated hall promotes the racetrack loop; zoned by tier is deleted when the ladder sold no floor differentiation; hub-and-spoke needs a draw that already exists. Never leave the floor unmapped for sponsors to pick their own spot.
- The tier-to-spec catalog has eight rows per tier, all mandatory: footprint (a dimension, never an adjective), furniture, position class, power, network, vertical limit, signage rule and staffing. The vertical limit and the signage rule are the two organizers skip and regret. A promise the spec cannot meet is a make-good routed to pricing, never a changed ladder.
- Power: count the booths that need a drop, not the booths; publish per tier what is included and what must be requested, with the deadline. Event WiFi is a stated inclusion, not a throughput guarantee - a live demo brings a fallback.
- The master schedule is written as offsets from a fixed anchor, not clock times, with request deadlines as rows. Teardown never starts before the last session ends. No secure overnight storage or no out-of-hours access deletes the overnight pre-day build - it is not a rung the organizer may choose against the venue's answer.
- Staffing and conduct are provisioning only: every booth staffed whenever the floor is open, a maximum per booth, badges that identify booth staff, send "somebody that can tell your story and participate with the community", the attire standard, and one named organizer on duty. A conduct matter leaves for the incident pipeline.
- The traffic mechanic serves the booths the layout could not reach, not the busy ones. A stamp is given for arriving, never after a signature or a conversation. The per-booth raffle is not a rung here.
- Two of the four menus do not diverge: on the layout and setup menus value and effort disagree, so efficiency resolves them; on the booth-spec and traffic-mechanic menus value and effort rise together, so no dominance relation exists and the ordering is a judgment call, re-ranked against Q7 and Q10.
- The floor plan is reviewed before it is printed, not before the doors open: fire lane, egress, occupancy, plus rigging where the spec allows it. These are the venue's and the authorities' to sign off; no universal width, distance or amperage exists. Walk the floor before doors: aisles clear, nothing overhanging, every booth staffed, every promised drop live; record what changed for next edition.
House rules
- Use only the input and the rules above. Copy the page's short facts exactly: the verdict, the layout pick, sponsor names, tier names, footprints, drop counts, costs, dates, schedule steps, offsets and clock times, the mechanic pick and the named contact. Every number in your text must appear in the input.
- Every "must: [...]" line in the facts applies to the item directly above it - every fixed item, every tier, every schedule row, every staffing rule, every review item and every walk-through item, not only the first. Do every item it lists.
- Label anything that is not one of the rules above, and is not in the input, as your own design; label the page's self-set numbers self-set.
- Never invent a dimension, a power figure, a price, a time, a booth, a sponsor or an approval. Never state that a fire marshal, the venue or any authority approved, cleared or signed off anything - the page holds only what the organizer recorded.
- Never quote a booth-position figure (dwell time, lead lift); describe the position honestly.
- Refer to people by name or role, as they; never use he, she, him, her, his or hers.
- Never use backticks, never refer to this input's fields by their key names in a sentence, and never copy this prompt's narrative wording into a reply.
- Reply with ONLY one JSON object - no prose before or after, no code fences.
The replies
floor
summary- one sentence, at most 40 words: the verdict, the most important open item, and the next step.verdict- the page's verdict, exactly:settle venue facts first,fix first,ready for review before printorready to print.fixed- one string per fixed item of the page, in its order, every item: each names the item exactly ("Signed floor plan", "Aggregate capacity", "Tier ladder", "Conduct policy") and says who owns it.layout- one object:pick- the page's layout pick, exactly;reason- one sentence that says what moved the pick, using the page's word for it from the layout must line: the question number (for example "Q1", "Q2" or "Q7") when an interview answer moved it, or the word "default" when nothing did;unreached- every unreached sponsor of the page, in its order, each exactly.[]when the page lists none.catalog- one object per tier of the page's catalog, in its order, every tier, not only the first:tierexactly as the page gives it;spec- one or two sentences carrying the eight rows, containing the page's footprint exactly and using the words "height" and "signage";gap- names every gap the page lists for the tier by its word ("footprint", "position", "rigging", "power", "network", "structure" or "blank") and says what to do, or uses the word "none" when the page lists no gap.power- one object:drops- the page's drop count, exactly;cost- the page's total, exactly (for example "1,800 EUR", or "not set");deadline- the page's request deadline, exactly (or "not set");note- one sentence using the page's word for the deadline: "passed" when it has passed, "not set" when there is none, "request" otherwise.schedule- one object per row of the page's schedule, in its order, every row, not only the first:step,offsetandclockexactly as the page gives them.staffing- one string per staffing rule of the page, in its order, every rule: each uses the rule's words from its must line - "whole time", "at most", "badge", "story", "attire", and the named organizer exactly (or the words "to be named").mechanic- one object:pick- the page's mechanic, exactly;reason- one or two sentences that say the ordering is a judgment call (the word "judgment") and that use the word "unreached" for the booths the layout could not reach, or the words "every booth" when the layout reaches every booth.review- one string per review item of the page, in its order, every item: each uses its words - "fire lane", "egress", "occupancy", "rigging" when the page lists it, and the print date exactly (or "not set"). Say what to ask for; never say any of it is approved.caveats- at most 5 short strings: the[fix]findings first in the page's order, then the most important[check]findings. Never empty when the page has a[fix]finding;[]otherwise when there is nothing to say.
{
"task": "floor",
"summary": "one sentence",
"verdict": "fix first",
"fixed": [ "Signed floor plan - one sentence" ],
"layout": { "pick": "the page's pick", "reason": "one sentence", "unreached": [ "the page's sponsor" ] },
"catalog": [ { "tier": "the page's tier", "spec": "one or two sentences", "gap": "none" } ],
"power": { "drops": "12", "cost": "the page's total", "deadline": "the page's deadline", "note": "one sentence" },
"schedule": [ { "step": "the page's step", "offset": "the page's offset", "clock": "the page's clock" } ],
"staffing": [ "a rule" ],
"mechanic": { "pick": "the page's mechanic", "reason": "one or two sentences" },
"review": [ "an item" ],
"caveats": [ "a caveat" ]
}
The page holds it to its own board: the verdict exactly; the four fixed items in order; the layout pick exactly with the question that moved it ("Q1", "Q2", "Q7") or "default" in the reason, and every unreached sponsor exactly; every tier with its footprint, "height" and "signage" in the spec and every gap named by its word (or "none"); the drops, the cost and the deadline exactly with "passed", "not set" or "request" in the note; every schedule row's step, offset and clock; every staffing rule's word; the mechanic exactly with "judgment" and "unreached" (or "every booth"); every review item's word; caveats when the page has a fix; and no number, approval, quote or pronoun the input does not hold. Required words are read tolerantly: "missed" is passed, "a judgement call" is judgment.
manual
title- one line; it must contain the event's name exactly.welcome- one short paragraph to the sponsors.your_booth- one object per tier of the page's catalog, in its order, every tier:tierexactly;what_you_get- one or two sentences containing the page's footprint exactly and using the words "height" and "signage". Only the page's catalog - never a promise the spec does not hold.arrival- one object:load_in- contains the page's first move-in clock exactly;shipping- contains the date the shipping window opens exactly (or the words "not set");storage- uses the page's storage words: "storage", "organizers", "no storage" or "not set".schedule- one object per row of the page's schedule, in its order, every row:stepandclockexactly as the page gives them.power_and_network- one paragraph: contains the page's request deadline exactly (or "not set") and uses the word "request".staffing_and_conduct- one paragraph using the words "whole time", "badge", "story" and "attire".the_mechanic- how sponsors take part, using the page's word for the mechanic: "stamp", "organic" or "leaderboard". For a stamp card, say the stamp is given for arriving (the word "arriving") - never after a signature, a scan or a conversation.contact- the page's named organizer exactly, or the words "to be named".teardown- contains the page's teardown clock exactly and the words "last session": teardown never starts before it.walk_through- one string per walk-through item of the page, in its order, every item, each using its word: "aisle", "overhang", "staffed", "drop" or "record".note- one sentence: when the page says "ready to send the manual: no", begin with "Not ready to send:" and say what to fix first; otherwise use the word "send" and say what happens next.
{
"task": "manual",
"title": "the event's name - exhibitor manual",
"welcome": "one paragraph",
"your_booth": [ { "tier": "the page's tier", "what_you_get": "one or two sentences" } ],
"arrival": { "load_in": "one sentence", "shipping": "one sentence", "storage": "one sentence" },
"schedule": [ { "step": "the page's step", "clock": "the page's clock" } ],
"power_and_network": "one paragraph",
"staffing_and_conduct": "one paragraph",
"the_mechanic": "one paragraph",
"contact": "the page's named organizer",
"teardown": "one sentence",
"walk_through": [ "an item" ],
"note": "one sentence"
}
The page requires the event's name in the title; one booth per catalog tier with its footprint, "height" and "signage"; the first move-in clock, the shipping date and the storage words in the arrival; every schedule row's step and clock; the deadline and "request" in power and network; "whole time", "badge", "story" and "attire" in staffing and conduct; the mechanic's word ("arriving" for a stamp card, never a stamp after a conversation); the named contact or "to be named"; the teardown clock and "last session"; one walk-through item per page item with its word; and a note beginning "Not ready to send:" unless the page is ready.
Worked examples - both lanes
Two of the page's four free samples (fictional events, organizations, sponsors and people). Each input is exactly what the page sends; each reply is the saved reply the sample replays, shipped unedited; the last line is the page's own check. The manual input carries its sample's saved floor plan, as the handoff does.
A 900-person conference, a passed power deadline and a hanging sign the venue forbids - floor
Verdict: fix first; ready to send: no; the floor: a dedicated hall; layout: Racetrack perimeter loop (2 unreached); 3 tiers, 24 booths, 12 drops by 2027-05-01; window: Staggered by zone; mechanic: Passport or stamp card; 3 fix-level findings.
Input:
{
"task": "floor",
"event": "Event: \"Tidewater Tech Conf 2027\" | dates: 2027-06-15 to 2027-06-16 | doors open, day one: 09:00 | doors open, later days: 09:00 | last session ends: 17:30 | city: \"Port Calder\" | attendance: 900 | as of: 2027-05-10\nQ1 the floor: \"a dedicated hall\"\nQ2 tiers: 3 | booths sold: 24 (each tier's promise is in the tiers table)\nQ3 the signed floor plan: entrance: \"North doors from the registration lobby\" | food service: \"Coffee and lunch along the east wall\" | hallway-track space: \"A lounge in the south-east corner\" | where power and network reach: \"Power along the north and east walls, wired network at the north wall\" | booth positions it holds: 26 | tables the food path holds: 14\nQ4 and Q5 and Q6: see the venue facts\nQ7 already exists: last edition's floor plan: no | a screen and someone to run it: no | printed signage: yes | fire sign-off: \"booked\" | a central draw: \"none\"\nQ8 print and sign-off date: 2027-05-28 | Q9 edition: \"recurring - this plan is next edition's starting point\" | Q10 effort ceiling: \"medium\" | Q10 political capital to hold a top-tier sponsor's spot: \"yes\" | Q11 run by: \"an independent community group\"\nNamed organizer on duty: \"Ines Varga, floor lead\"",
"tiers": "Tiers, top first - 3, one per line:\n- tier 1: \"Gold\" | booths: 4 | promised floor presence: \"premium location and 3x3 m\" | power included: yes | other promises: \"logo on the hall map\"\n- tier 2: \"Silver\" | booths: 8 | promised floor presence: \"a 2x1 m table on the main floor\" | power included: yes | other promises: \"none\"\n- tier 3: \"Bronze\" | booths: 12 | promised floor presence: \"half of a shared table\" | power included: no | other promises: \"none\"\nSpec draft - 3, one per tier:\n- spec 1: \"Gold\" | footprint: \"3 x 2 m\" | furniture: \"table, cloth, two chairs\" | position class: \"premium zone by the coffee\" | vertical limit: \"free-standing banner behind the table, 2.5 m high\" | signage rule: \"inside the plot, nothing over the aisle\" | staffing: \"2-3\"\n- spec 2: \"Silver\" | footprint: \"2 x 1 m\" | furniture: \"table, cloth, two chairs\" | position class: \"general floor\" | vertical limit: \"free-standing banner behind the table, 2 m high\" | signage rule: \"inside the plot, nothing over the aisle\" | staffing: \"2\"\n- spec 3: \"Bronze\" | footprint: \"1 x 1 m\" | furniture: \"half of a shared table, one chair\" | position class: \"general floor\" | vertical limit: \"nothing free-standing\" | signage rule: \"table-top only\" | staffing: \"1\"\nBooths - 24, one per line:\n- booth 1: \"Brightwave\" | tier: \"Gold\" | power: yes | wired: yes | heavy: no | demo screen: yes | notes: \"plans a hanging sign above the booth\"\n- booth 2: \"Corvane\" | tier: \"Gold\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 3: \"Delphin Labs\" | tier: \"Gold\" | power: yes | wired: no | heavy: no | demo screen: yes | notes: \"none\"\n- booth 4: \"Equinox Data\" | tier: \"Gold\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 5: \"Fernhill Cloud\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 6: \"Gridline\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 7: \"Halcyon AI\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: yes | notes: \"none\"\n- booth 8: \"Ironleaf\" | tier: \"Silver\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 9: \"Juniper Stack\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 10: \"Orbit Robotics\" | tier: \"Silver\" | power: yes | wired: no | heavy: yes | demo screen: no | notes: \"a robot arm on a pallet\"\n- booth 11: \"Pinewood Security\" | tier: \"Silver\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 12: \"Quarry DB\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 13: \"Kettlebird\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"corner alcove, far from the food\"\n- booth 14: \"Lumen Forge\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"corner alcove, far from the food\"\n- booth 15: \"Mosswork\" | tier: \"Bronze\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 16: \"Nimbus Pay\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 17: \"Redfern\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 18: \"Saltbox\" | tier: \"Bronze\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 19: \"Tallow\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 20: \"Umbra Labs\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 21: \"Vesper\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 22: \"Wrenfield\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 23: \"Yarrow\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 24: \"Zephyr Ops\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"",
"venue": "Q4 access hours - 2 days: [2027-06-15 07:00-19:00; 2027-06-16 07:00-19:30]\nQ4 overnight storage: \"no secure overnight storage\"\nShipping window opens: 2027-06-01 | shipping fees: \"45 EUR per received crate\"\nQ5 rigging permitted: \"no\" | sign-off it requires: \"not stated\"\nQ6 power supplier: \"Hallvolt Events, the venue's electrician\" | drop cost: 150 EUR | request deadline: 2027-05-01\nNetwork: wired at the booths: \"yes\" | event WiFi included: \"yes\"\nFloor-plan review (fire lane, egress, occupancy, rigging): \"not recorded done\"",
"notes": "Call with Brightwave on 2027-05-08: they plan a hanging sign above the booth and asked whether they can set up the evening before.",
"facts": "Verdict: \"fix first\" | ready to send the manual: no | fix-level findings: 3\nSelf-set lines: [one shared window absorbs 15 booths; a zone slot is 30 minutes for 10 booths; a tiered slot opens 60 minutes before the shared one; the floor walk is 15 minutes before doors; the room is clear 90 minutes after the last session; the review closes 7 days before print; a deadline under 14 days is soon; a small event is at most 300 people; a large floor is over 40 booths; a summary cap of 40 words; at most 5 caveats] | published anchor: setup an hour before registration on the first day (one city's practice, not a standard)\nNever invented: a dimension, a power figure, a price, a time, a booth, a sponsor, an approval. The venue and the authorities sign off the fire lane, egress, occupancy and rigging - never say any of it was approved.\nFixed (step 1) - what may not move, in this order - 4:\n- fixed 1: \"Signed floor plan\" | detail: holds 26 booth positions - booths are distributed inside it, never reopened | owner: \"event-venue-sourcing\"\n must: [contains \"Signed floor plan\"]\n- fixed 2: \"Aggregate capacity\" | detail: the room's capacity as negotiated - taken as given for a planned attendance of 900 | owner: \"event-venue-sourcing\"\n must: [contains \"Aggregate capacity\"]\n- fixed 3: \"Tier ladder\" | detail: 3 tiers as sold (Gold, Silver, Bronze) - never re-priced or re-tiered here | owner: \"event-sponsor-pricing\"\n must: [contains \"Tier ladder\"]\n- fixed 4: \"Conduct policy\" | detail: adjudication, sanctions and ejection stay with the policy - this page provisions only | owner: \"event-code-of-conduct\"\n must: [contains \"Conduct policy\"]\nVenue facts still open (step 2) - 0: none\nLayout and traffic pattern menu (step 3), re-ranked - pick: \"Racetrack perimeter loop\"\n- rung 1: \"Racetrack perimeter loop\" | moved: promoted by Q1: a dedicated hall - circulation-path siting is promoted to the racetrack; promoted by Q2: 24 booths exceed the 14 tables the food and hangout path holds\n- rung 2: \"Circulation-path siting\"\n- rung 3: \"Zoned by tier\" | moved: promoted by Q2 and Q10: the ladder genuinely sold position and there is political capital to hold the line\n- rung 4: \"Grid rows\"\n- rung 5: \"Hub-and-spoke around a central draw\"\n- deleted, not demoted: \"An unmapped floor where sponsors pick their own spot on arrival\" | reason: it rewards whoever arrived earliest, not whoever paid most, and leaves the last sponsor in the dead corner with a legitimate complaint\n- notes: Hub-and-spoke is promoted only by a draw that already exists (Q7) - none is named. Value and effort disagree on this menu, so an efficiency ratio genuinely resolves it.\nLayout: pick: \"Racetrack perimeter loop\" | moved by: \"Q1\" | unreached booths: 2\n layout must: [pick \"Racetrack perimeter loop\" exactly; reason uses the word \"Q1\"; unreached copies every unreached sponsor below, in this order, each exactly]\nUnreached booths - in this order - 2:\n- unreached 1: \"Kettlebird\" | tier: \"Bronze\" | why: off the loop: corner alcove, far from the food\n- unreached 2: \"Lumen Forge\" | tier: \"Bronze\" | why: off the loop: corner alcove, far from the food\nBooth tier physical-spec depth menu (step 4), re-ranked - pick: \"Standard table spec per tier\"\n- rung 1: \"Standard table spec per tier\"\n- rung 2: \"Custom structure for the top tier only\"\n- rung 3: \"Fully bespoke per sponsor\"\n- deleted, not demoted: \"Shared table row\" | reason: Q2: the ladder sold floor-presence differentiation - one shared surface collapses the axis it gates on\n- deleted, not demoted: \"'A table will be provided' with no dimension, no height limit and no signage rule\" | reason: whoever is standing there at 08:00 fills each blank later, inconsistently\n- notes: Q7: printed signage already exists - write the signage rule so it fits. Value and effort rise together across every rung - no dominance relation exists, so this ordering is a judgment call, re-ranked against Q7 and Q10.\nCatalog (step 4) - one row per tier, the eight rows each, in this order - 3:\n- tier 1: \"Gold\" | booths: 4 | promised: \"premium location and 3x3 m\" | other promises: \"logo on the hall map\"\n rows: [footprint \"3 x 2 m\"; furniture \"table, cloth, two chairs\"; position class \"premium zone by the coffee\"; power \"One drop included, supplied by Hallvolt Events, the venue's electrician - request by 2027-05-01\"; network \"Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-01\"; vertical limit \"free-standing banner behind the table, 2.5 m high\"; signage rule \"inside the plot, nothing over the aisle\"; staffing \"2-3\"]\n gaps: [footprint: the package promised 3x3 m, the footprint is 3 x 2 m]\n must: [tier \"Gold\" exactly; spec and what_you_get each contain the footprint \"3 x 2 m\" exactly; spec and what_you_get each use the words \"height\" and \"signage\"; gap names \"footprint\"]\n- tier 2: \"Silver\" | booths: 8 | promised: \"a 2x1 m table on the main floor\" | other promises: \"none\"\n rows: [footprint \"2 x 1 m\"; furniture \"table, cloth, two chairs\"; position class \"general floor\"; power \"One drop included, supplied by Hallvolt Events, the venue's electrician - request by 2027-05-01\"; network \"Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-01\"; vertical limit \"free-standing banner behind the table, 2 m high\"; signage rule \"inside the plot, nothing over the aisle\"; staffing \"2\"]\n gaps: none\n must: [tier \"Silver\" exactly; spec and what_you_get each contain the footprint \"2 x 1 m\" exactly; spec and what_you_get each use the words \"height\" and \"signage\"; gap uses the word \"none\"]\n- tier 3: \"Bronze\" | booths: 12 | promised: \"half of a shared table\" | other promises: \"none\"\n rows: [footprint \"1 x 1 m\"; furniture \"half of a shared table, one chair\"; position class \"general floor\"; power \"Not included - request and pay for a drop by 2027-05-01 from Hallvolt Events, the venue's electrician\"; network \"Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-01\"; vertical limit \"nothing free-standing\"; signage rule \"table-top only\"; staffing \"1\"]\n gaps: none\n must: [tier \"Bronze\" exactly; spec and what_you_get each contain the footprint \"1 x 1 m\" exactly; spec and what_you_get each use the words \"height\" and \"signage\"; gap uses the word \"none\"]\nPower and network (step 5): booths: 24 | drops: 12 | drops included by tier: 10 | drops to request and pay: 2 | drop cost: 150 | total: \"1,800 EUR\" | included total: \"1,500 EUR\" | requested total: \"300 EUR\" | deadline: \"2027-05-01\" | deadline state: \"passed\" | days from the as-of date: -9 | wired needed: 1 | wired available: \"yes\"\n power must: [drops \"12\" exactly; cost \"1,800 EUR\" exactly; deadline \"2027-05-01\" exactly; note uses the word \"passed\"]\nPer booth - sponsor, tier, drop, wired - 24: [Brightwave (Gold), drop included, wired yes; Corvane (Gold), drop included, wired no; Delphin Labs (Gold), drop included, wired no; Equinox Data (Gold), drop included, wired no; Fernhill Cloud (Silver), drop included, wired no; Gridline (Silver), drop included, wired no; Halcyon AI (Silver), drop included, wired no; Ironleaf (Silver), drop no, wired no; Juniper Stack (Silver), drop included, wired no; Orbit Robotics (Silver), drop included, wired no; Pinewood Security (Silver), drop no, wired no; Quarry DB (Silver), drop included, wired no; Kettlebird (Bronze), drop no, wired no; Lumen Forge (Bronze), drop no, wired no; Mosswork (Bronze), drop to request, wired no; Nimbus Pay (Bronze), drop no, wired no; Redfern (Bronze), drop no, wired no; Saltbox (Bronze), drop to request, wired no; Tallow (Bronze), drop no, wired no; Umbra Labs (Bronze), drop no, wired no; Vesper (Bronze), drop no, wired no; Wrenfield (Bronze), drop no, wired no; Yarrow (Bronze), drop no, wired no; Zephyr Ops (Bronze), drop no, wired no]\nSetup and teardown window menu (step 6), re-ranked - pick: \"Staggered by zone\"\n- rung 1: \"Staggered by zone\" | moved: promoted by Q2: 24 booths - more than one door absorbs in one window (the page's line: 15, self-set)\n- rung 2: \"Single shared window\"\n- rung 3: \"Tiered windows\" | moved: promoted by Q2: 1 booth brings heavy or oversized items - a build that needs more time than the shared window holds\n- deleted, not demoted: \"Overnight pre-day build\" | reason: Q4: the venue grants no secure overnight storage - not a rung the organizer may choose against the venue's answer\n- deleted, not demoted: \"Teardown starting before the last session ends\" | reason: it turns the closing session into packing-tape noise and silently breaks the floor presence the sponsor bought\n- notes: Q6: every promised drop is live before the floor walk - the supplier's drops go in before move-in opens. Tiered windows dominate the overnight build outright - better value and less effort - so overnight never ranks above tiered. Value and effort disagree on this menu, so an efficiency ratio resolves it.\nSchedule (step 6) - offsets from D, doors open on day one (\"2027-06-15 09:00\"), in this order - 12:\n- row 1: step: \"Shipping window opens\" | offset: \"D - 14 days\" | clock: \"2027-06-01\"\n must: [step \"Shipping window opens\" exactly; offset \"D - 14 days\" exactly; clock \"2027-06-01\" exactly]\n- row 2: step: \"Power and A/V requests close\" | offset: \"D - 45 days\" | clock: \"2027-05-01\"\n must: [step \"Power and A/V requests close\" exactly; offset \"D - 45 days\" exactly; clock \"2027-05-01\" exactly]\n- row 3: step: \"Floor-plan review closes\" | offset: \"D - 25 days\" | clock: \"2027-05-21\" | self-set\n must: [step \"Floor-plan review closes\" exactly; offset \"D - 25 days\" exactly; clock \"2027-05-21\" exactly]\n- row 4: step: \"Floor plan signed off and printed\" | offset: \"D - 18 days\" | clock: \"2027-05-28\"\n must: [step \"Floor plan signed off and printed\" exactly; offset \"D - 18 days\" exactly; clock \"2027-05-28\" exactly]\n- row 5: step: \"Move-in, zone slot 1 of 3\" | offset: \"D - 1 h 45 min\" | clock: \"2027-06-15 07:15\" | self-set\n must: [step \"Move-in, zone slot 1 of 3\" exactly; offset \"D - 1 h 45 min\" exactly; clock \"2027-06-15 07:15\" exactly]\n- row 6: step: \"Move-in, zone slot 2 of 3\" | offset: \"D - 1 h 15 min\" | clock: \"2027-06-15 07:45\" | self-set\n must: [step \"Move-in, zone slot 2 of 3\" exactly; offset \"D - 1 h 15 min\" exactly; clock \"2027-06-15 07:45\" exactly]\n- row 7: step: \"Move-in, zone slot 3 of 3\" | offset: \"D - 45 min\" | clock: \"2027-06-15 08:15\" | self-set\n must: [step \"Move-in, zone slot 3 of 3\" exactly; offset \"D - 45 min\" exactly; clock \"2027-06-15 08:15\" exactly]\n- row 8: step: \"Floor walk before doors\" | offset: \"D - 15 min\" | clock: \"2027-06-15 08:45\" | self-set\n must: [step \"Floor walk before doors\" exactly; offset \"D - 15 min\" exactly; clock \"2027-06-15 08:45\" exactly]\n- row 9: step: \"Doors open, booths staffed\" | offset: \"D\" | clock: \"2027-06-15 09:00\"\n must: [step \"Doors open, booths staffed\" exactly; offset \"D\" exactly; clock \"2027-06-15 09:00\" exactly]\n- row 10: step: \"Doors open, day 2\" | offset: \"D + 1 day\" | clock: \"2027-06-16 09:00\"\n must: [step \"Doors open, day 2\" exactly; offset \"D + 1 day\" exactly; clock \"2027-06-16 09:00\" exactly]\n- row 11: step: \"Teardown opens, not before the last session ends\" | offset: \"D + 1 day 8 h 30 min\" | clock: \"2027-06-16 17:30\"\n must: [step \"Teardown opens, not before the last session ends\" exactly; offset \"D + 1 day 8 h 30 min\" exactly; clock \"2027-06-16 17:30\" exactly]\n- row 12: step: \"Room clear\" | offset: \"D + 1 day 10 h\" | clock: \"2027-06-16 19:00\" | self-set\n must: [step \"Room clear\" exactly; offset \"D + 1 day 10 h\" exactly; clock \"2027-06-16 19:00\" exactly]\nStaffing and conduct (step 7), provisioning only - in this order - 6:\n- rule 1: \"Every booth staffed for the whole time the floor is open, with a named person per shift - the sponsor sizes the rota\"\n must: [uses the words \"whole time\"]\n- rule 2: \"At most the staffing the tier allows, so no booth crowds the aisle it fronts: Gold 2-3, Silver 2, Bronze 1\"\n must: [uses the words \"at most\"]\n- rule 3: \"Booth staff wear badges that identify them as booth staff - what makes the conduct policy's scope operable on the floor\"\n must: [uses the words \"badge\"]\n- rule 4: \"Send somebody that can tell your story and participate with the community (DevOpsDays Des Moines)\"\n must: [uses the words \"story\"]\n- rule 5: \"Attire standard: no sexualized clothing, uniforms, costumes, or environments, volunteers included (confcodeofconduct.com)\"\n must: [uses the words \"attire\"]\n- rule 6: \"One named organizer on duty for the floor: Ines Varga, floor lead - anything that becomes a conduct matter leaves the floor rules for the incident pipeline\"\n must: [uses the words \"Ines Varga, floor lead\"]\nTraffic-driving mechanic menu (step 8), re-ranked - pick: \"Passport or stamp card\"\n- rung 1: \"Passport or stamp card\"\n- rung 2: \"Scavenger hunt with a live leaderboard\"\n- rung 3: \"Organic traffic only\" | moved: demoted by the layout: it could not reach 2 booths - organic exposure stops at siting\n- deleted, not demoted: \"A passport that requires a sponsor's signature or a conversation before the stamp is given\" | reason: it turns a traffic mechanic into a forced pitch - a stamp is given for arriving, not for listening\n- notes: The per-booth raffle is not a rung: event-sponsor-fulfillment ranks it as a lead-capture posture, and its pull stays at the booth already running it. No compliance-cost axis: no rung collects more than one winner's contact detail at claim time; a passport that scans attendees becomes fulfillment's lead-capture question, with a consent flow. Value and effort rise together across every rung - no dominance relation exists, so this ordering is a judgment call, re-ranked against Q7 and Q10.\nMechanic: pick: \"Passport or stamp card\" | aimed at the unreached booths: [\"Kettlebird\"; \"Lumen Forge\"]\n mechanic must: [pick \"Passport or stamp card\" exactly; reason uses the word \"judgment\"; reason uses the word \"unreached\"]\nReview before print (step 9) - status: \"booked, not yet recorded done\" - in this order - 5:\n- review 1: \"Fire lane - route the actual widths to the venue's own stated requirements, no universal figure is stated here\"\n must: [uses the words \"fire lane\"]\n- review 2: \"Egress - exits and the routes to them stay clear of every plot and sign\"\n must: [uses the words \"egress\"]\n- review 3: \"Occupancy - the floor's occupancy as the venue states it\"\n must: [uses the words \"occupancy\"]\n- review 4: \"Rigging - anything suspended or attached to the building needs the venue's rigging approval\"\n must: [uses the words \"rigging\"]\n- review 5: \"Reviewed before the plan is printed, by 2027-05-28 - not before the doors open\"\n must: [uses the words \"2027-05-28\"]\nWalk the floor before doors (step 10) - in this order - 5:\n- walk 1: \"Aisles clear\"\n must: [uses the word \"aisle\"]\n- walk 2: \"Nothing overhanging the aisle\"\n must: [uses the word \"overhang\"]\n- walk 3: \"Every booth staffed - 24 booths\"\n must: [uses the word \"staffed\"]\n- walk 4: \"Every promised drop live - 12 drops\"\n must: [uses the word \"drop\"]\n- walk 5: \"Record what changed - dead spots, tables moved by hand, missed deadlines - next edition's starting plan\"\n must: [uses the word \"record\"]\nFloor must: [summary at most 40 words; verdict \"fix first\" exactly; fixed carries the 4 items above, in this order; caveats carry the fix findings first, at most 5]\nManual must: [title contains \"Tidewater Tech Conf 2027\"; load_in contains \"2027-06-15 07:15\"; shipping contains \"2027-06-01\"; storage uses the words \"no storage\"; power_and_network contains \"2027-05-01\" and the word \"request\"; contact \"Ines Varga, floor lead\" exactly; teardown contains \"2027-06-16 17:30\" and the words \"last session\"; the_mechanic uses the word \"stamp\"; the_mechanic says the stamp is given for arriving (the word \"arriving\")] | manual note must: [begin \"Not ready to send:\" and say what to fix first]\nHand-off: one floor brief - the schedule, the catalog, the provisioning rules and the named contact - goes to event-sponsor-fulfillment to execute per signed sponsor; no per-sponsor tracking matrix here.\nFindings (16):\n[fix] booth_rig_1 (rigging): \"Brightwave\"'s notes say \"plans a hanging sign above the booth\" - the venue does not permit rigging: anything suspended or attached to the building does not go up. Tell the sponsor before it builds; the vertical limit is nothing suspended.\n[fix] gap_1_size (catalog): \"Gold\": the package promised 3x3 m; the footprint is 3 x 2 m - the tier ladder is fixed, so change the spec to meet the promise, or route a make-good to event-sponsor-pricing.\n[fix] power_passed (power): Q6: the power request deadline 2027-05-01 passed 9 days before the as-of date - ask the venue now what can still be requested; none of the 12 drops is live until it answers.\n[check] heavy (booths): 1 booth brings heavy or oversized items (Orbit Robotics) - confirm the dock, the shipping address and any venue labour rule in writing.\n[check] unreached (layout): The Racetrack perimeter loop cannot reach 2 booths (Kettlebird, Lumen Forge) - the traffic mechanic is designed to serve them, not the booths already busy.\n[check] storage_nights (schedule): A 2-day floor with no secure overnight storage - tell sponsors what stays on the floor overnight at their own risk, and ask the venue whether the hall is locked.\n[info] labour (venue): Ask in writing, during negotiation: the electrical safety sign-off for temporary power (who may run a drop) and any venue labour rules for load-in, rigging and dock work - neither can be renegotiated mid-setup, and the page states no universal threshold for either.\n[info] position_figure (layout): Never quote a booth-position figure to a sponsor: no usable data exists. Describe the position honestly - on the food path or off a spur - and let the sponsor judge.\n[info] wifi_fallback (power): Event WiFi is a stated inclusion, not a guarantee of throughput - tell every booth running a live demo over it to bring a fallback.\n[info] no_formula (power): No formula converts the venue's aggregate ratio into a per-booth allocation - the page counts booths that need a drop, not booths.\n[info] provisioning (staffing): Provisioning only: adjudication, sanctions and ejection belong to event-code-of-conduct, and the contractual ejection right to event-sponsor-agreement.\n[info] notes (context): The pasted notes are context: a request in the notes is never a commitment.\n[info] recurring (context): Q9: recurring - this year's plan is next year's starting point; record dead spots, hand-moved tables and missed deadlines.\n[info] measure (context): Measured across editions, all self-set: the dead-booth count (ask the sponsors), spec completeness (zero blanks), floor ready at doors, tables moved by hand, and whether the mechanic reached anyone not already touring booths.\n[info] handoff (scope): Publish one floor brief - the schedule, the catalog, the provisioning rules and the named contact - and hand it to samber/dev-event-organizer-skills@event-sponsor-fulfillment to execute per signed sponsor; never a per-sponsor tracking matrix here.\n[info] scope (scope): Fire lane, egress, occupancy and rigging are the venue's and the authorities' to sign off - the page states no universal width, distance or amperage and never says anything was approved. It never invents a dimension, a power figure, a price, a time, a booth, a sponsor or an approval."
}
Reply:
{
"task": "floor",
"summary": "Fix first: the power request deadline passed, the Gold footprint is smaller than the package promised, and a hanging sign meets a venue that forbids rigging - settle those, then send the manual.",
"verdict": "fix first",
"fixed": [
"Signed floor plan - holds 26 booth positions - booths are distributed inside it, never reopened (event-venue-sourcing).",
"Aggregate capacity - the room's capacity as negotiated - taken as given for a planned attendance of 900 (event-venue-sourcing).",
"Tier ladder - 3 tiers as sold (Gold, Silver, Bronze) - never re-priced or re-tiered here (event-sponsor-pricing).",
"Conduct policy - adjudication, sanctions and ejection stay with the policy - this page provisions only (event-code-of-conduct)."
],
"layout": {
"pick": "Racetrack perimeter loop",
"reason": "Q1: the floor is a dedicated hall, so circulation-path siting is promoted to the racetrack loop, where position barely matters.",
"unreached": [
"Kettlebird",
"Lumen Forge"
]
},
"catalog": [
{
"tier": "Gold",
"spec": "Footprint 3 x 2 m, table, cloth, two chairs. Position class: premium zone by the coffee. Power: One drop included, supplied by Hallvolt Events, the venue's electrician - request by 2027-05-01. Network: Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-01. Height: free-standing banner behind the table, 2.5 m high. Signage: inside the plot, nothing over the aisle. Staffing: 2-3.",
"gap": "footprint gap: the package promised 3x3 m; the footprint is 3 x 2 m - change the spec, or route a make-good to event-sponsor-pricing."
},
{
"tier": "Silver",
"spec": "Footprint 2 x 1 m, table, cloth, two chairs. Position class: general floor. Power: One drop included, supplied by Hallvolt Events, the venue's electrician - request by 2027-05-01. Network: Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-01. Height: free-standing banner behind the table, 2 m high. Signage: inside the plot, nothing over the aisle. Staffing: 2.",
"gap": "None - the spec meets what the package promised."
},
{
"tier": "Bronze",
"spec": "Footprint 1 x 1 m, half of a shared table, one chair. Position class: general floor. Power: Not included - request and pay for a drop by 2027-05-01 from Hallvolt Events, the venue's electrician. Network: Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-01. Height: nothing free-standing. Signage: table-top only. Staffing: 1.",
"gap": "None - the spec meets what the package promised."
}
],
"power": {
"drops": "12",
"cost": "1,800 EUR",
"deadline": "2027-05-01",
"note": "The request deadline passed on 2027-05-01 - ask the venue now what can still be requested before any drop is promised."
},
"schedule": [
{
"step": "Shipping window opens",
"offset": "D - 14 days",
"clock": "2027-06-01"
},
{
"step": "Power and A/V requests close",
"offset": "D - 45 days",
"clock": "2027-05-01"
},
{
"step": "Floor-plan review closes",
"offset": "D - 25 days",
"clock": "2027-05-21"
},
{
"step": "Floor plan signed off and printed",
"offset": "D - 18 days",
"clock": "2027-05-28"
},
{
"step": "Move-in, zone slot 1 of 3",
"offset": "D - 1 h 45 min",
"clock": "2027-06-15 07:15"
},
{
"step": "Move-in, zone slot 2 of 3",
"offset": "D - 1 h 15 min",
"clock": "2027-06-15 07:45"
},
{
"step": "Move-in, zone slot 3 of 3",
"offset": "D - 45 min",
"clock": "2027-06-15 08:15"
},
{
"step": "Floor walk before doors",
"offset": "D - 15 min",
"clock": "2027-06-15 08:45"
},
{
"step": "Doors open, booths staffed",
"offset": "D",
"clock": "2027-06-15 09:00"
},
{
"step": "Doors open, day 2",
"offset": "D + 1 day",
"clock": "2027-06-16 09:00"
},
{
"step": "Teardown opens, not before the last session ends",
"offset": "D + 1 day 8 h 30 min",
"clock": "2027-06-16 17:30"
},
{
"step": "Room clear",
"offset": "D + 1 day 10 h",
"clock": "2027-06-16 19:00"
}
],
"staffing": [
"Every booth staffed for the whole time the floor is open, with a named person per shift - the sponsor sizes the rota.",
"At most the staffing the tier allows, so no booth crowds the aisle it fronts: Gold 2-3, Silver 2, Bronze 1.",
"Booth staff wear badges that identify them as booth staff - what makes the conduct policy's scope operable on the floor.",
"Send somebody that can tell your story and participate with the community (DevOpsDays Des Moines).",
"Attire standard: no sexualized clothing, uniforms, costumes, or environments, volunteers included (confcodeofconduct.com).",
"One named organizer on duty for the floor: Ines Varga, floor lead - anything that becomes a conduct matter leaves the floor rules for the incident pipeline."
],
"mechanic": {
"pick": "Passport or stamp card",
"reason": "The ordering on this menu is a judgment call, because value and effort rise together; the passport makes the unreached booths (Kettlebird, Lumen Forge) a required stop."
},
"review": [
"Fire lane - route the actual widths to the venue's own stated requirements; no universal figure is stated here.",
"Egress - exits and the routes to them stay clear of every plot and sign.",
"Occupancy - the floor's occupancy as the venue states it.",
"Rigging - anything suspended or attached to the building needs the venue's rigging approval.",
"Reviewed before the plan is printed, by 2027-05-28 - not before the doors open."
],
"caveats": [
"\"Brightwave\"'s notes say \"plans a hanging sign above the booth\" - the venue does not permit rigging: anything suspended or attached to the building does not go up.",
"\"Gold\": the package promised 3x3 m; the footprint is 3 x 2 m - the tier ladder is fixed, so change the spec to meet the promise, or route a make-good to event-sponsor-pricing.",
"the power request deadline 2027-05-01 passed 9 days before the as-of date - ask the venue now what can still be requested; none of the 12 drops is live until it answers.",
"1 booth brings heavy or oversized items (Orbit Robotics) - confirm the dock, the shipping address and any venue labour rule in writing.",
"The Racetrack perimeter loop cannot reach 2 booths (Kettlebird, Lumen Forge) - the traffic mechanic is designed to serve them, not the booths already busy."
]
}
The page's check: kept - nothing to flag
The same, resolved - ready for review before print - manual
Verdict: ready for review before print; ready to send: yes; the floor: a dedicated hall; layout: Racetrack perimeter loop (2 unreached); 3 tiers, 24 booths, 12 drops by 2027-05-31; window: Staggered by zone; mechanic: Passport or stamp card; 0 fix-level findings.
Input:
{
"task": "manual",
"event": "Event: \"Tidewater Tech Conf 2027\" | dates: 2027-06-15 to 2027-06-16 | doors open, day one: 09:00 | doors open, later days: 09:00 | last session ends: 17:30 | city: \"Port Calder\" | attendance: 900 | as of: 2027-05-10\nQ1 the floor: \"a dedicated hall\"\nQ2 tiers: 3 | booths sold: 24 (each tier's promise is in the tiers table)\nQ3 the signed floor plan: entrance: \"North doors from the registration lobby\" | food service: \"Coffee and lunch along the east wall\" | hallway-track space: \"A lounge in the south-east corner\" | where power and network reach: \"Power along the north and east walls, wired network at the north wall\" | booth positions it holds: 26 | tables the food path holds: 14\nQ4 and Q5 and Q6: see the venue facts\nQ7 already exists: last edition's floor plan: no | a screen and someone to run it: no | printed signage: yes | fire sign-off: \"booked\" | a central draw: \"none\"\nQ8 print and sign-off date: 2027-05-28 | Q9 edition: \"recurring - this plan is next edition's starting point\" | Q10 effort ceiling: \"medium\" | Q10 political capital to hold a top-tier sponsor's spot: \"yes\" | Q11 run by: \"an independent community group\"\nNamed organizer on duty: \"Ines Varga, floor lead\"",
"tiers": "Tiers, top first - 3, one per line:\n- tier 1: \"Gold\" | booths: 4 | promised floor presence: \"premium location and 3x3 m\" | power included: yes | other promises: \"logo on the hall map\"\n- tier 2: \"Silver\" | booths: 8 | promised floor presence: \"a 2x1 m table on the main floor\" | power included: yes | other promises: \"none\"\n- tier 3: \"Bronze\" | booths: 12 | promised floor presence: \"half of a shared table\" | power included: no | other promises: \"none\"\nSpec draft - 3, one per tier:\n- spec 1: \"Gold\" | footprint: \"3 x 3 m\" | furniture: \"table, cloth, two chairs\" | position class: \"premium zone by the coffee\" | vertical limit: \"free-standing banner behind the table, 2.5 m high\" | signage rule: \"inside the plot, nothing over the aisle\" | staffing: \"2-3\"\n- spec 2: \"Silver\" | footprint: \"2 x 1 m\" | furniture: \"table, cloth, two chairs\" | position class: \"general floor\" | vertical limit: \"free-standing banner behind the table, 2 m high\" | signage rule: \"inside the plot, nothing over the aisle\" | staffing: \"2\"\n- spec 3: \"Bronze\" | footprint: \"1 x 1 m\" | furniture: \"half of a shared table, one chair\" | position class: \"general floor\" | vertical limit: \"nothing free-standing\" | signage rule: \"table-top only\" | staffing: \"1\"\nBooths - 24, one per line:\n- booth 1: \"Brightwave\" | tier: \"Gold\" | power: yes | wired: yes | heavy: no | demo screen: yes | notes: \"a free-standing banner, nothing suspended\"\n- booth 2: \"Corvane\" | tier: \"Gold\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 3: \"Delphin Labs\" | tier: \"Gold\" | power: yes | wired: no | heavy: no | demo screen: yes | notes: \"none\"\n- booth 4: \"Equinox Data\" | tier: \"Gold\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 5: \"Fernhill Cloud\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 6: \"Gridline\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 7: \"Halcyon AI\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: yes | notes: \"none\"\n- booth 8: \"Ironleaf\" | tier: \"Silver\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 9: \"Juniper Stack\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 10: \"Orbit Robotics\" | tier: \"Silver\" | power: yes | wired: no | heavy: yes | demo screen: no | notes: \"a robot arm on a pallet\"\n- booth 11: \"Pinewood Security\" | tier: \"Silver\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 12: \"Quarry DB\" | tier: \"Silver\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 13: \"Kettlebird\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"corner alcove, far from the food\"\n- booth 14: \"Lumen Forge\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"corner alcove, far from the food\"\n- booth 15: \"Mosswork\" | tier: \"Bronze\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 16: \"Nimbus Pay\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 17: \"Redfern\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 18: \"Saltbox\" | tier: \"Bronze\" | power: yes | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 19: \"Tallow\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 20: \"Umbra Labs\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 21: \"Vesper\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 22: \"Wrenfield\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 23: \"Yarrow\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"\n- booth 24: \"Zephyr Ops\" | tier: \"Bronze\" | power: no | wired: no | heavy: no | demo screen: no | notes: \"none\"",
"venue": "Q4 access hours - 2 days: [2027-06-15 07:00-19:00; 2027-06-16 07:00-19:30]\nQ4 overnight storage: \"no secure overnight storage\"\nShipping window opens: 2027-06-01 | shipping fees: \"45 EUR per received crate\"\nQ5 rigging permitted: \"no\" | sign-off it requires: \"not stated\"\nQ6 power supplier: \"Hallvolt Events, the venue's electrician\" | drop cost: 150 EUR | request deadline: 2027-05-31\nNetwork: wired at the booths: \"yes\" | event WiFi included: \"yes\"\nFloor-plan review (fire lane, egress, occupancy, rigging): \"not recorded done\"",
"notes": "The venue extended the power request deadline to 2027-05-31 by email on 2027-05-09. Brightwave confirmed a free-standing banner instead of the hanging sign.",
"facts": "Verdict: \"ready for review before print\" | ready to send the manual: yes | fix-level findings: 0\nSelf-set lines: [one shared window absorbs 15 booths; a zone slot is 30 minutes for 10 booths; a tiered slot opens 60 minutes before the shared one; the floor walk is 15 minutes before doors; the room is clear 90 minutes after the last session; the review closes 7 days before print; a deadline under 14 days is soon; a small event is at most 300 people; a large floor is over 40 booths; a summary cap of 40 words; at most 5 caveats] | published anchor: setup an hour before registration on the first day (one city's practice, not a standard)\nNever invented: a dimension, a power figure, a price, a time, a booth, a sponsor, an approval. The venue and the authorities sign off the fire lane, egress, occupancy and rigging - never say any of it was approved.\nFixed (step 1) - what may not move, in this order - 4:\n- fixed 1: \"Signed floor plan\" | detail: holds 26 booth positions - booths are distributed inside it, never reopened | owner: \"event-venue-sourcing\"\n must: [contains \"Signed floor plan\"]\n- fixed 2: \"Aggregate capacity\" | detail: the room's capacity as negotiated - taken as given for a planned attendance of 900 | owner: \"event-venue-sourcing\"\n must: [contains \"Aggregate capacity\"]\n- fixed 3: \"Tier ladder\" | detail: 3 tiers as sold (Gold, Silver, Bronze) - never re-priced or re-tiered here | owner: \"event-sponsor-pricing\"\n must: [contains \"Tier ladder\"]\n- fixed 4: \"Conduct policy\" | detail: adjudication, sanctions and ejection stay with the policy - this page provisions only | owner: \"event-code-of-conduct\"\n must: [contains \"Conduct policy\"]\nVenue facts still open (step 2) - 0: none\nLayout and traffic pattern menu (step 3), re-ranked - pick: \"Racetrack perimeter loop\"\n- rung 1: \"Racetrack perimeter loop\" | moved: promoted by Q1: a dedicated hall - circulation-path siting is promoted to the racetrack; promoted by Q2: 24 booths exceed the 14 tables the food and hangout path holds\n- rung 2: \"Circulation-path siting\"\n- rung 3: \"Zoned by tier\" | moved: promoted by Q2 and Q10: the ladder genuinely sold position and there is political capital to hold the line\n- rung 4: \"Grid rows\"\n- rung 5: \"Hub-and-spoke around a central draw\"\n- deleted, not demoted: \"An unmapped floor where sponsors pick their own spot on arrival\" | reason: it rewards whoever arrived earliest, not whoever paid most, and leaves the last sponsor in the dead corner with a legitimate complaint\n- notes: Hub-and-spoke is promoted only by a draw that already exists (Q7) - none is named. Value and effort disagree on this menu, so an efficiency ratio genuinely resolves it.\nLayout: pick: \"Racetrack perimeter loop\" | moved by: \"Q1\" | unreached booths: 2\n layout must: [pick \"Racetrack perimeter loop\" exactly; reason uses the word \"Q1\"; unreached copies every unreached sponsor below, in this order, each exactly]\nUnreached booths - in this order - 2:\n- unreached 1: \"Kettlebird\" | tier: \"Bronze\" | why: off the loop: corner alcove, far from the food\n- unreached 2: \"Lumen Forge\" | tier: \"Bronze\" | why: off the loop: corner alcove, far from the food\nBooth tier physical-spec depth menu (step 4), re-ranked - pick: \"Standard table spec per tier\"\n- rung 1: \"Standard table spec per tier\"\n- rung 2: \"Custom structure for the top tier only\"\n- rung 3: \"Fully bespoke per sponsor\"\n- deleted, not demoted: \"Shared table row\" | reason: Q2: the ladder sold floor-presence differentiation - one shared surface collapses the axis it gates on\n- deleted, not demoted: \"'A table will be provided' with no dimension, no height limit and no signage rule\" | reason: whoever is standing there at 08:00 fills each blank later, inconsistently\n- notes: Q7: printed signage already exists - write the signage rule so it fits. Value and effort rise together across every rung - no dominance relation exists, so this ordering is a judgment call, re-ranked against Q7 and Q10.\nCatalog (step 4) - one row per tier, the eight rows each, in this order - 3:\n- tier 1: \"Gold\" | booths: 4 | promised: \"premium location and 3x3 m\" | other promises: \"logo on the hall map\"\n rows: [footprint \"3 x 3 m\"; furniture \"table, cloth, two chairs\"; position class \"premium zone by the coffee\"; power \"One drop included, supplied by Hallvolt Events, the venue's electrician - request by 2027-05-31\"; network \"Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-31\"; vertical limit \"free-standing banner behind the table, 2.5 m high\"; signage rule \"inside the plot, nothing over the aisle\"; staffing \"2-3\"]\n gaps: none\n must: [tier \"Gold\" exactly; spec and what_you_get each contain the footprint \"3 x 3 m\" exactly; spec and what_you_get each use the words \"height\" and \"signage\"; gap uses the word \"none\"]\n- tier 2: \"Silver\" | booths: 8 | promised: \"a 2x1 m table on the main floor\" | other promises: \"none\"\n rows: [footprint \"2 x 1 m\"; furniture \"table, cloth, two chairs\"; position class \"general floor\"; power \"One drop included, supplied by Hallvolt Events, the venue's electrician - request by 2027-05-31\"; network \"Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-31\"; vertical limit \"free-standing banner behind the table, 2 m high\"; signage rule \"inside the plot, nothing over the aisle\"; staffing \"2\"]\n gaps: none\n must: [tier \"Silver\" exactly; spec and what_you_get each contain the footprint \"2 x 1 m\" exactly; spec and what_you_get each use the words \"height\" and \"signage\"; gap uses the word \"none\"]\n- tier 3: \"Bronze\" | booths: 12 | promised: \"half of a shared table\" | other promises: \"none\"\n rows: [footprint \"1 x 1 m\"; furniture \"half of a shared table, one chair\"; position class \"general floor\"; power \"Not included - request and pay for a drop by 2027-05-31 from Hallvolt Events, the venue's electrician\"; network \"Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-31\"; vertical limit \"nothing free-standing\"; signage rule \"table-top only\"; staffing \"1\"]\n gaps: none\n must: [tier \"Bronze\" exactly; spec and what_you_get each contain the footprint \"1 x 1 m\" exactly; spec and what_you_get each use the words \"height\" and \"signage\"; gap uses the word \"none\"]\nPower and network (step 5): booths: 24 | drops: 12 | drops included by tier: 10 | drops to request and pay: 2 | drop cost: 150 | total: \"1,800 EUR\" | included total: \"1,500 EUR\" | requested total: \"300 EUR\" | deadline: \"2027-05-31\" | deadline state: \"open\" | days from the as-of date: 21 | wired needed: 1 | wired available: \"yes\"\n power must: [drops \"12\" exactly; cost \"1,800 EUR\" exactly; deadline \"2027-05-31\" exactly; note uses the word \"request\"]\nPer booth - sponsor, tier, drop, wired - 24: [Brightwave (Gold), drop included, wired yes; Corvane (Gold), drop included, wired no; Delphin Labs (Gold), drop included, wired no; Equinox Data (Gold), drop included, wired no; Fernhill Cloud (Silver), drop included, wired no; Gridline (Silver), drop included, wired no; Halcyon AI (Silver), drop included, wired no; Ironleaf (Silver), drop no, wired no; Juniper Stack (Silver), drop included, wired no; Orbit Robotics (Silver), drop included, wired no; Pinewood Security (Silver), drop no, wired no; Quarry DB (Silver), drop included, wired no; Kettlebird (Bronze), drop no, wired no; Lumen Forge (Bronze), drop no, wired no; Mosswork (Bronze), drop to request, wired no; Nimbus Pay (Bronze), drop no, wired no; Redfern (Bronze), drop no, wired no; Saltbox (Bronze), drop to request, wired no; Tallow (Bronze), drop no, wired no; Umbra Labs (Bronze), drop no, wired no; Vesper (Bronze), drop no, wired no; Wrenfield (Bronze), drop no, wired no; Yarrow (Bronze), drop no, wired no; Zephyr Ops (Bronze), drop no, wired no]\nSetup and teardown window menu (step 6), re-ranked - pick: \"Staggered by zone\"\n- rung 1: \"Staggered by zone\" | moved: promoted by Q2: 24 booths - more than one door absorbs in one window (the page's line: 15, self-set)\n- rung 2: \"Single shared window\"\n- rung 3: \"Tiered windows\" | moved: promoted by Q2: 1 booth brings heavy or oversized items - a build that needs more time than the shared window holds\n- deleted, not demoted: \"Overnight pre-day build\" | reason: Q4: the venue grants no secure overnight storage - not a rung the organizer may choose against the venue's answer\n- deleted, not demoted: \"Teardown starting before the last session ends\" | reason: it turns the closing session into packing-tape noise and silently breaks the floor presence the sponsor bought\n- notes: Q6: every promised drop is live before the floor walk - the supplier's drops go in before move-in opens. Tiered windows dominate the overnight build outright - better value and less effort - so overnight never ranks above tiered. Value and effort disagree on this menu, so an efficiency ratio resolves it.\nSchedule (step 6) - offsets from D, doors open on day one (\"2027-06-15 09:00\"), in this order - 12:\n- row 1: step: \"Shipping window opens\" | offset: \"D - 14 days\" | clock: \"2027-06-01\"\n must: [step \"Shipping window opens\" exactly; offset \"D - 14 days\" exactly; clock \"2027-06-01\" exactly]\n- row 2: step: \"Power and A/V requests close\" | offset: \"D - 15 days\" | clock: \"2027-05-31\"\n must: [step \"Power and A/V requests close\" exactly; offset \"D - 15 days\" exactly; clock \"2027-05-31\" exactly]\n- row 3: step: \"Floor-plan review closes\" | offset: \"D - 25 days\" | clock: \"2027-05-21\" | self-set\n must: [step \"Floor-plan review closes\" exactly; offset \"D - 25 days\" exactly; clock \"2027-05-21\" exactly]\n- row 4: step: \"Floor plan signed off and printed\" | offset: \"D - 18 days\" | clock: \"2027-05-28\"\n must: [step \"Floor plan signed off and printed\" exactly; offset \"D - 18 days\" exactly; clock \"2027-05-28\" exactly]\n- row 5: step: \"Move-in, zone slot 1 of 3\" | offset: \"D - 1 h 45 min\" | clock: \"2027-06-15 07:15\" | self-set\n must: [step \"Move-in, zone slot 1 of 3\" exactly; offset \"D - 1 h 45 min\" exactly; clock \"2027-06-15 07:15\" exactly]\n- row 6: step: \"Move-in, zone slot 2 of 3\" | offset: \"D - 1 h 15 min\" | clock: \"2027-06-15 07:45\" | self-set\n must: [step \"Move-in, zone slot 2 of 3\" exactly; offset \"D - 1 h 15 min\" exactly; clock \"2027-06-15 07:45\" exactly]\n- row 7: step: \"Move-in, zone slot 3 of 3\" | offset: \"D - 45 min\" | clock: \"2027-06-15 08:15\" | self-set\n must: [step \"Move-in, zone slot 3 of 3\" exactly; offset \"D - 45 min\" exactly; clock \"2027-06-15 08:15\" exactly]\n- row 8: step: \"Floor walk before doors\" | offset: \"D - 15 min\" | clock: \"2027-06-15 08:45\" | self-set\n must: [step \"Floor walk before doors\" exactly; offset \"D - 15 min\" exactly; clock \"2027-06-15 08:45\" exactly]\n- row 9: step: \"Doors open, booths staffed\" | offset: \"D\" | clock: \"2027-06-15 09:00\"\n must: [step \"Doors open, booths staffed\" exactly; offset \"D\" exactly; clock \"2027-06-15 09:00\" exactly]\n- row 10: step: \"Doors open, day 2\" | offset: \"D + 1 day\" | clock: \"2027-06-16 09:00\"\n must: [step \"Doors open, day 2\" exactly; offset \"D + 1 day\" exactly; clock \"2027-06-16 09:00\" exactly]\n- row 11: step: \"Teardown opens, not before the last session ends\" | offset: \"D + 1 day 8 h 30 min\" | clock: \"2027-06-16 17:30\"\n must: [step \"Teardown opens, not before the last session ends\" exactly; offset \"D + 1 day 8 h 30 min\" exactly; clock \"2027-06-16 17:30\" exactly]\n- row 12: step: \"Room clear\" | offset: \"D + 1 day 10 h\" | clock: \"2027-06-16 19:00\" | self-set\n must: [step \"Room clear\" exactly; offset \"D + 1 day 10 h\" exactly; clock \"2027-06-16 19:00\" exactly]\nStaffing and conduct (step 7), provisioning only - in this order - 6:\n- rule 1: \"Every booth staffed for the whole time the floor is open, with a named person per shift - the sponsor sizes the rota\"\n must: [uses the words \"whole time\"]\n- rule 2: \"At most the staffing the tier allows, so no booth crowds the aisle it fronts: Gold 2-3, Silver 2, Bronze 1\"\n must: [uses the words \"at most\"]\n- rule 3: \"Booth staff wear badges that identify them as booth staff - what makes the conduct policy's scope operable on the floor\"\n must: [uses the words \"badge\"]\n- rule 4: \"Send somebody that can tell your story and participate with the community (DevOpsDays Des Moines)\"\n must: [uses the words \"story\"]\n- rule 5: \"Attire standard: no sexualized clothing, uniforms, costumes, or environments, volunteers included (confcodeofconduct.com)\"\n must: [uses the words \"attire\"]\n- rule 6: \"One named organizer on duty for the floor: Ines Varga, floor lead - anything that becomes a conduct matter leaves the floor rules for the incident pipeline\"\n must: [uses the words \"Ines Varga, floor lead\"]\nTraffic-driving mechanic menu (step 8), re-ranked - pick: \"Passport or stamp card\"\n- rung 1: \"Passport or stamp card\"\n- rung 2: \"Scavenger hunt with a live leaderboard\"\n- rung 3: \"Organic traffic only\" | moved: demoted by the layout: it could not reach 2 booths - organic exposure stops at siting\n- deleted, not demoted: \"A passport that requires a sponsor's signature or a conversation before the stamp is given\" | reason: it turns a traffic mechanic into a forced pitch - a stamp is given for arriving, not for listening\n- notes: The per-booth raffle is not a rung: event-sponsor-fulfillment ranks it as a lead-capture posture, and its pull stays at the booth already running it. No compliance-cost axis: no rung collects more than one winner's contact detail at claim time; a passport that scans attendees becomes fulfillment's lead-capture question, with a consent flow. Value and effort rise together across every rung - no dominance relation exists, so this ordering is a judgment call, re-ranked against Q7 and Q10.\nMechanic: pick: \"Passport or stamp card\" | aimed at the unreached booths: [\"Kettlebird\"; \"Lumen Forge\"]\n mechanic must: [pick \"Passport or stamp card\" exactly; reason uses the word \"judgment\"; reason uses the word \"unreached\"]\nReview before print (step 9) - status: \"booked, not yet recorded done\" - in this order - 4:\n- review 1: \"Fire lane - route the actual widths to the venue's own stated requirements, no universal figure is stated here\"\n must: [uses the words \"fire lane\"]\n- review 2: \"Egress - exits and the routes to them stay clear of every plot and sign\"\n must: [uses the words \"egress\"]\n- review 3: \"Occupancy - the floor's occupancy as the venue states it\"\n must: [uses the words \"occupancy\"]\n- review 4: \"Reviewed before the plan is printed, by 2027-05-28 - not before the doors open\"\n must: [uses the words \"2027-05-28\"]\nWalk the floor before doors (step 10) - in this order - 5:\n- walk 1: \"Aisles clear\"\n must: [uses the word \"aisle\"]\n- walk 2: \"Nothing overhanging the aisle\"\n must: [uses the word \"overhang\"]\n- walk 3: \"Every booth staffed - 24 booths\"\n must: [uses the word \"staffed\"]\n- walk 4: \"Every promised drop live - 12 drops\"\n must: [uses the word \"drop\"]\n- walk 5: \"Record what changed - dead spots, tables moved by hand, missed deadlines - next edition's starting plan\"\n must: [uses the word \"record\"]\nFloor must: [summary at most 40 words; verdict \"ready for review before print\" exactly; fixed carries the 4 items above, in this order; caveats carry the fix findings first, at most 5]\nManual must: [title contains \"Tidewater Tech Conf 2027\"; load_in contains \"2027-06-15 07:15\"; shipping contains \"2027-06-01\"; storage uses the words \"no storage\"; power_and_network contains \"2027-05-31\" and the word \"request\"; contact \"Ines Varga, floor lead\" exactly; teardown contains \"2027-06-16 17:30\" and the words \"last session\"; the_mechanic uses the word \"stamp\"; the_mechanic says the stamp is given for arriving (the word \"arriving\")] | manual note must: [use the word \"send\" and say what happens next]\nHand-off: one floor brief - the schedule, the catalog, the provisioning rules and the named contact - goes to event-sponsor-fulfillment to execute per signed sponsor; no per-sponsor tracking matrix here.\nCarried from the floor plan: summary: \"Ready for review before print: every tier's spec meets its package and the drops can still be requested - book the fire lane, egress and occupancy review before the plan is printed.\" | parts matching the page: 3 of 3\nFindings (13):\n[check] heavy (booths): 1 booth brings heavy or oversized items (Orbit Robotics) - confirm the dock, the shipping address and any venue labour rule in writing.\n[check] unreached (layout): The Racetrack perimeter loop cannot reach 2 booths (Kettlebird, Lumen Forge) - the traffic mechanic is designed to serve them, not the booths already busy.\n[check] storage_nights (schedule): A 2-day floor with no secure overnight storage - tell sponsors what stays on the floor overnight at their own risk, and ask the venue whether the hall is locked.\n[info] labour (venue): Ask in writing, during negotiation: the electrical safety sign-off for temporary power (who may run a drop) and any venue labour rules for load-in, rigging and dock work - neither can be renegotiated mid-setup, and the page states no universal threshold for either.\n[info] position_figure (layout): Never quote a booth-position figure to a sponsor: no usable data exists. Describe the position honestly - on the food path or off a spur - and let the sponsor judge.\n[info] wifi_fallback (power): Event WiFi is a stated inclusion, not a guarantee of throughput - tell every booth running a live demo over it to bring a fallback.\n[info] no_formula (power): No formula converts the venue's aggregate ratio into a per-booth allocation - the page counts booths that need a drop, not booths.\n[info] provisioning (staffing): Provisioning only: adjudication, sanctions and ejection belong to event-code-of-conduct, and the contractual ejection right to event-sponsor-agreement.\n[info] notes (context): The pasted notes are context: a request in the notes is never a commitment.\n[info] recurring (context): Q9: recurring - this year's plan is next year's starting point; record dead spots, hand-moved tables and missed deadlines.\n[info] measure (context): Measured across editions, all self-set: the dead-booth count (ask the sponsors), spec completeness (zero blanks), floor ready at doors, tables moved by hand, and whether the mechanic reached anyone not already touring booths.\n[info] handoff (scope): Publish one floor brief - the schedule, the catalog, the provisioning rules and the named contact - and hand it to samber/dev-event-organizer-skills@event-sponsor-fulfillment to execute per signed sponsor; never a per-sponsor tracking matrix here.\n[info] scope (scope): Fire lane, egress, occupancy and rigging are the venue's and the authorities' to sign off - the page states no universal width, distance or amperage and never says anything was approved. It never invents a dimension, a power figure, a price, a time, a booth, a sponsor or an approval."
}
Reply:
{
"task": "manual",
"title": "Tidewater Tech Conf 2027 - exhibitor manual",
"welcome": "Welcome to the Tidewater Tech Conf 2027 expo floor. Everything below is what your tier includes and when you can get in and out of the hall.",
"your_booth": [
{
"tier": "Gold",
"what_you_get": "A 3 x 3 m plot with table, cloth, two chairs. Position: premium zone by the coffee. Height: free-standing banner behind the table, 2.5 m high. Signage: inside the plot, nothing over the aisle."
},
{
"tier": "Silver",
"what_you_get": "A 2 x 1 m plot with table, cloth, two chairs. Position: general floor. Height: free-standing banner behind the table, 2 m high. Signage: inside the plot, nothing over the aisle."
},
{
"tier": "Bronze",
"what_you_get": "A 1 x 1 m plot with half of a shared table, one chair. Position: general floor. Height: nothing free-standing. Signage: table-top only."
}
],
"arrival": {
"load_in": "Move-in opens at 2027-06-15 07:15 for the first zone slot - every slot is in the schedule below.",
"shipping": "The venue accepts shipments from 2027-06-01; fees: 45 EUR per received crate.",
"storage": "There is no storage on site: nothing stays in secure storage overnight, so take valuables with you each evening."
},
"schedule": [
{
"step": "Shipping window opens",
"clock": "2027-06-01"
},
{
"step": "Power and A/V requests close",
"clock": "2027-05-31"
},
{
"step": "Floor-plan review closes",
"clock": "2027-05-21"
},
{
"step": "Floor plan signed off and printed",
"clock": "2027-05-28"
},
{
"step": "Move-in, zone slot 1 of 3",
"clock": "2027-06-15 07:15"
},
{
"step": "Move-in, zone slot 2 of 3",
"clock": "2027-06-15 07:45"
},
{
"step": "Move-in, zone slot 3 of 3",
"clock": "2027-06-15 08:15"
},
{
"step": "Floor walk before doors",
"clock": "2027-06-15 08:45"
},
{
"step": "Doors open, booths staffed",
"clock": "2027-06-15 09:00"
},
{
"step": "Doors open, day 2",
"clock": "2027-06-16 09:00"
},
{
"step": "Teardown opens, not before the last session ends",
"clock": "2027-06-16 17:30"
},
{
"step": "Room clear",
"clock": "2027-06-16 19:00"
}
],
"power_and_network": "Request your drop from Hallvolt Events, the venue's electrician by 2027-05-31 - the tier table below says whether your tier includes one. Event WiFi included at no extra cost, not a throughput guarantee, wired on request by 2027-05-31; bring a fallback for any live demo.",
"staffing_and_conduct": "Staff your booth for the whole time the floor is open, with a named person per shift. Every booth staffer wears a booth-staff badge. Send somebody who can tell your story and participate with the community. The attire standard: no sexualized clothing, uniforms, costumes or environments.",
"the_mechanic": "Every booth is a stop on the passport: attendees get a stamp for arriving at your table, never after a scan, a signature or a conversation. Keep the stamp at the front of the table.",
"contact": "Ines Varga, floor lead",
"teardown": "Teardown opens at 2027-06-16 17:30, when the last session ends - never before; the room is clear by 2027-06-16 19:00.",
"walk_through": [
"Aisles clear.",
"Nothing overhanging the aisle.",
"Every booth staffed - 24 booths.",
"Every promised drop live - 12 drops.",
"Record what changed - dead spots, tables moved by hand, missed deadlines - next edition's starting plan."
],
"note": "Send the manual to every signed sponsor now, and get the floor plan reviewed before it is printed on 2027-05-28."
}
The page's check: kept - nothing to flag
The free walk-through for the resolved sample
# Tidewater Tech Conf 2027 - walk the floor before doors
_Verdict: ready for review before print. Doors open 2027-06-15 09:00. Floor walk at 2027-06-15 08:45 (15 minutes before doors, self-set)._
## Walk the floor
- [ ] Aisles clear
- [ ] Nothing overhanging the aisle
- [ ] Every booth staffed - 24 booths
- [ ] Every promised drop live - 12 drops
- [ ] Record what changed - dead spots, tables moved by hand, missed deadlines - next edition's starting plan
## Review before print (booked, not yet recorded done)
- [ ] Fire lane - route the actual widths to the venue's own stated requirements; no universal figure is stated here
- [ ] Egress - exits and the routes to them stay clear of every plot and sign
- [ ] Occupancy - the floor's occupancy as the venue states it
- [ ] Reviewed before the plan is printed, by 2027-05-28 - not before the doors open
The venue and the authorities sign these off; this list records what to ask, never an approval.
## The named organizer on duty
Ines Varga, floor lead
Made with Expo Floor - https://expo-floor.skillsafe.ai/
Build the input yourself
Load the engine in node (global.window = global; require("./floorkit.js"); require("./floorreply.js")), then:
const K = FloorKit, R = FloorReply;
const f = K.form({ name: "My Conf 2027", start: "2027-06-15", doors1: "09:00", lastSession: "17:30", floorType: "hall",
tiers: "Gold | 4 | premium location and 3x3 m | yes |\nSilver | 8 | a 2x1 m table | yes |",
specs: "Gold | 3 x 3 m | table, two chairs | premium zone | free-standing banner, 2.5 m high | inside the plot | 2-3" });
// f.fixed, f.venueOpen, f.layout / f.unreached, f.specMenu, f.catalog, f.power, f.window, f.schedule, f.staffing, f.mechanic, f.review, f.walk, f.verdict, f.findings
K.catalogCsv(f); K.scheduleCsv(f); K.scheduleIcs(f); K.walkMd(f); K.board(f) // the free exports
const b = K.buildInput(f, "floor"); // or "manual"
const wire = K.toWire(b.input); // POST this to /estimate and /run
// then: const reply = R.normalize(R.parseReply(job.output.output), "floor");
// R.check(reply, b) // {status: kept or flagged, notes}
// R.carryText(reply) // the lines the manual lane carries - set them as the carry field
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="YOUR_TOKEN" # from https://expo-floor.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"}
}
import json, urllib.request
BASE = "https://api.skillsafe.ai/v1/app-api"
TOKEN = "YOUR_TOKEN" # from https://expo-floor.skillsafe.ai/tokens.html
def api(method, path, body=None, headers=None):
req = urllib.request.Request(BASE + path, method=method,
data=None if body is None else json.dumps(body).encode(),
headers={"Content-Type": "application/json", **({"Authorization": "Bearer " + TOKEN} if TOKEN else {}), **(headers or {})})
with urllib.request.urlopen(req) as r:
env = json.load(r)
if env.get("error"):
raise RuntimeError(env["error"])
return env["data"]
// expo-floor.mjs -- Node 18+ (global fetch)
const BASE = "https://api.skillsafe.ai/v1/app-api";
let TOKEN = "YOUR_TOKEN"; // from https://expo-floor.skillsafe.ai/tokens.html
async function api(method, path, body, headers = {}) {
const r = await fetch(BASE + path, { method, headers: { "Content-Type": "application/json",
...(TOKEN ? { Authorization: "Bearer " + TOKEN } : {}), ...headers },
body: body === undefined ? undefined : JSON.stringify(body) });
const env = await r.json();
if (env.error) throw new Error(env.error.code + ": " + env.error.message);
return env.data;
}
package main
import ("bytes"; "encoding/json"; "fmt"; "net/http")
const base = "https://api.skillsafe.ai/v1/app-api"
var token = "YOUR_TOKEN" // from https://expo-floor.skillsafe.ai/tokens.html
func api(method, path string, body any, headers map[string]string) (map[string]any, error) {
var buf bytes.Buffer
if body != nil { json.NewEncoder(&buf).Encode(body) }
req, _ := http.NewRequest(method, base+path, &buf)
req.Header.Set("Content-Type", "application/json")
if token != "" { req.Header.Set("Authorization", "Bearer "+token) }
for k, v := range headers { req.Header.Set(k, v) }
res, err := http.DefaultClient.Do(req)
if err != nil { return nil, err }
defer res.Body.Close()
var env struct { Data map[string]any; Error map[string]any }
json.NewDecoder(res.Body).Decode(&env)
if env.Error != nil { return nil, fmt.Errorf("%v", env.Error) }
return env.Data, nil
}
// ExpoFloor.java -- Java 17+, with com.fasterxml.jackson.core:jackson-databind
import com.fasterxml.jackson.databind.*;
import java.net.URI; import java.net.http.*; import java.util.*;
public class ExpoFloor {
static final String BASE = "https://api.skillsafe.ai/v1/app-api";
static String token = "YOUR_TOKEN"; // from https://expo-floor.skillsafe.ai/tokens.html
static final ObjectMapper M = new ObjectMapper();
static final HttpClient C = HttpClient.newHttpClient();
static JsonNode api(String method, String path, Object body, Map<String, String> headers) throws Exception {
var b = HttpRequest.newBuilder(URI.create(BASE + path)).header("Content-Type", "application/json");
if (!token.isEmpty()) b.header("Authorization", "Bearer " + token);
if (headers != null) headers.forEach(b::header);
b.method(method, body == null ? HttpRequest.BodyPublishers.noBody() : HttpRequest.BodyPublishers.ofString(M.writeValueAsString(body)));
JsonNode env = M.readTree(C.send(b.build(), HttpResponse.BodyHandlers.ofString()).body());
if (env.hasNonNull("error")) throw new RuntimeException(env.get("error").toString());
return env.get("data");
}
}
require "json"
require "net/http"
BASE = "https://api.skillsafe.ai/v1/app-api"
TOKEN = "YOUR_TOKEN" # from https://expo-floor.skillsafe.ai/tokens.html
def api(method, path, body = nil, headers = {})
uri = URI(BASE + path)
req = Net::HTTPGenericRequest.new(method, !body.nil?, true, uri.request_uri,
{ "Content-Type" => "application/json" }.merge(TOKEN.empty? ? {} : { "Authorization" => "Bearer #{TOKEN}" }).merge(headers))
req.body = JSON.generate(body) unless body.nil?
env = JSON.parse(Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }.body)
raise env["error"].to_s if env["error"]
env["data"]
end
<?php
const BASE = "https://api.skillsafe.ai/v1/app-api";
$TOKEN = "YOUR_TOKEN"; // from https://expo-floor.skillsafe.ai/tokens.html
function api(string $method, string $path, $body = null, array $headers = []) {
global $TOKEN;
$h = ["Content-Type: application/json"];
if ($TOKEN) $h[] = "Authorization: Bearer $TOKEN";
foreach ($headers as $k => $v) $h[] = "$k: $v";
$ch = curl_init(BASE . $path);
curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => $h, CURLOPT_RETURNTRANSFER => true]);
if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
$env = json_decode(curl_exec($ch), true);
if (!empty($env["error"])) throw new Exception(json_encode($env["error"]));
return $env["data"];
}
// Program.cs -- .NET 6+ console app
using System.Net.Http.Json; using System.Text.Json; using System.Text.Json.Nodes;
static class Api {
public const string Base = "https://api.skillsafe.ai/v1/app-api";
public static string Token = "YOUR_TOKEN"; // from https://expo-floor.skillsafe.ai/tokens.html
static readonly HttpClient C = new();
public static async Task<JsonNode?> Call(string method, string path, object? body = null, Dictionary<string, string>? headers = null) {
var req = new HttpRequestMessage(new HttpMethod(method), Base + path);
if (Token != "") req.Headers.Add("Authorization", "Bearer " + Token);
if (headers != null) foreach (var h in headers) req.Headers.Add(h.Key, h.Value);
if (body != null) req.Content = JsonContent.Create(body);
var env = JsonNode.Parse(await (await C.SendAsync(req)).Content.ReadAsStringAsync())!;
if (env["error"] is JsonNode e && e.GetValueKind() != JsonValueKind.Null) throw new Exception(e.ToJsonString());
return env["data"];
}
}
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":"expo-floor"}' | jq -r '.data.token')
# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN = ""
TOKEN = api("POST", "/guest", {"slug": "expo-floor"})["token"]
// a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN = "";
TOKEN = (await api("POST", "/guest", { slug: "expo-floor" })).token;
// inside main: a guest token (enough for /me and /estimate); a run needs your personal token
token = ""
g, err := api("POST", "/guest", map[string]string{"slug": "expo-floor"}, nil)
if err != nil { panic(err) }
token = g["token"].(string)
// inside main: a guest token (enough for /me and /estimate); a run needs your personal token
token = "";
token = api("POST", "/guest", Map.of("slug", "expo-floor"), null).get("token").asText();
# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN.replace("")
TOKEN.replace(api("POST", "/guest", { slug: "expo-floor" })["token"])
// a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
$TOKEN = "";
$TOKEN = api("POST", "/guest", ["slug" => "expo-floor"])["token"];
// a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
Api.Token = "";
Api.Token = (await Api.Call("POST", "/guest", new { slug = "expo-floor" }))!["token"]!.GetValue<string>();
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}'
me = api("GET", "/me")
print(me["subject_type"], me.get("credits"))
const me = await api("GET", "/me");
console.log(me.subject_type, me.credits);
me, _ := api("GET", "/me", nil, nil)
fmt.Println(me["subject_type"], me["credits"])
JsonNode me = api("GET", "/me", null, null);
System.out.println(me.get("subject_type") + " " + me.get("credits"));
me = api("GET", "/me")
puts [me["subject_type"], me["credits"]].inspect
$me = api("GET", "/me");
echo $me["subject_type"], " ", $me["credits"] ?? "", "\n";
var me = await Api.Call("GET", "/me");
Console.WriteLine($"{me!["subject_type"]} {me["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": "floor", "event": "Event: ... | dates: ... | doors open, day one: ...", "tiers": "Tiers, top first - 3 ...", "venue": "Q4 access hours - ...", "notes": "", "facts": "Verdict: ..."}
# - see the input table
api POST /estimate "$(cat input.json)" | jq '.data | {hold_credits, min_credits, model, model_alias, markup_bps, warnings}'
inp = json.load(open("input.json")) # {"task": "floor", "event": "Event: ... | dates: ... | doors open, day one: ...", "tiers": "Tiers, top first - 3 ...", "venue": "Q4 access hours - ...", "notes": "", "facts": "Verdict: ..."}
# - see the input table
est = api("POST", "/estimate", inp)
print(est["hold_credits"], est["min_credits"], est["model"], est.get("warnings"))
import { readFileSync } from "node:fs";
const input = JSON.parse(readFileSync("input.json", "utf8")); // {task: "floor" or "manual", event, tiers, venue, notes, facts} (see the input table)
const est = await api("POST", "/estimate", input);
console.log(est.hold_credits, est.min_credits, est.model, est.warnings);
raw, _ := os.ReadFile("input.json") // add "os" to the imports
var input map[string]any
json.Unmarshal(raw, &input)
est, _ := api("POST", "/estimate", input, nil)
fmt.Println(est["hold_credits"], est["min_credits"], est["model"])
Map<String, Object> input = M.readValue(new java.io.File("input.json"), Map.class);
JsonNode est = api("POST", "/estimate", input, null);
System.out.println(est.get("hold_credits") + " " + est.get("min_credits") + " " + est.get("model"));
input = JSON.parse(File.read("input.json"))
est = api("POST", "/estimate", input)
puts [est["hold_credits"], est["min_credits"], est["model"]].inspect
$input = json_decode(file_get_contents("input.json"), true);
$est = api("POST", "/estimate", $input);
echo $est["hold_credits"], " ", $est["min_credits"], " ", $est["model"], "\n";
var input = JsonNode.Parse(File.ReadAllText("input.json"))!;
var est = await Api.Call("POST", "/estimate", input);
Console.WriteLine($"{est!["hold_credits"]} {est["min_credits"]} {est["model"]}");
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 expo-floor:<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 floor plan carries summary, verdict, fixed, layout, catalog, power, schedule, staffing, mechanic, review and caveats; a manual carries title, welcome, your_booth, arrival, schedule, power_and_network, staffing_and_conduct, the_mechanic, contact, teardown, walk_through and note. The code below prints the headline of either.
KEY="expo-floor:floor:$(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 '.verdict // .note, .summary // .title' reply.json
jq -r '.catalog[]? | "\(.tier): \(.gap)"' reply.json # a floor plan; a manual has .your_booth
import hashlib, time
key = "expo-floor:" + inp["task"] + ":" + hashlib.sha256(json.dumps(inp).encode()).hexdigest()[:16] + ":a1"
job = api("POST", "/run", inp, {"Idempotency-Key": key})
while True:
j = api("GET", "/jobs/" + job["job_id"])
if j["status"] in ("succeeded", "failed", "cancelled"):
break
time.sleep(2)
reply = json.loads(j["output"]["output"]) # the reply as one JSON object
print(j["charged_credits"], j.get("truncated"), reply.get("verdict") or reply.get("note"))
for row in reply.get("catalog") or reply.get("your_booth") or []:
print("-", row["tier"], row.get("gap") or row.get("what_you_get"))
import { createHash } from "node:crypto";
const key = `expo-floor:${input.task}:${createHash("sha256").update(JSON.stringify(input)).digest("hex").slice(0, 16)}:a1`;
const job = await api("POST", "/run", input, { "Idempotency-Key": key });
let j;
do { await new Promise((r) => setTimeout(r, 2000)); j = await api("GET", "/jobs/" + job.job_id); }
while (!["succeeded", "failed", "cancelled"].includes(j.status));
const reply = JSON.parse(j.output.output);
console.log(j.charged_credits, j.truncated, reply.verdict ?? reply.note);
for (const row of reply.catalog || reply.your_booth || []) console.log("-", row.tier, row.gap || row.what_you_get);
sum := sha256.Sum256(raw) // add "crypto/sha256", "encoding/hex", "time" to the imports
key := "expo-floor:" + input["task"].(string) + ":" + hex.EncodeToString(sum[:8]) + ":a1"
job, _ := api("POST", "/run", input, map[string]string{"Idempotency-Key": key})
var j map[string]any
for {
time.Sleep(2 * time.Second)
j, _ = api("GET", "/jobs/"+job["job_id"].(string), nil, nil)
if s := j["status"]; s == "succeeded" || s == "failed" || s == "cancelled" { break }
}
var reply map[string]any
json.Unmarshal([]byte(j["output"].(map[string]any)["output"].(string)), &reply)
fmt.Println(j["charged_credits"], j["truncated"], reply["verdict"], reply["note"])
rows, _ := reply["catalog"].([]any) // a floor plan's catalog; a manual has your_booth
for _, row := range rows {
fmt.Println("-", row.(map[string]any)["tier"], row.(map[string]any)["gap"])
}
var digest = java.security.MessageDigest.getInstance("SHA-256").digest(M.writeValueAsBytes(input));
String key = "expo-floor:" + input.get("task") + ":" + HexFormat.of().formatHex(digest, 0, 8) + ":a1";
JsonNode job = api("POST", "/run", input, Map.of("Idempotency-Key", key)), j;
do { Thread.sleep(2000); j = api("GET", "/jobs/" + job.get("job_id").asText(), null, null); }
while (!Set.of("succeeded", "failed", "cancelled").contains(j.get("status").asText()));
JsonNode reply = M.readTree(j.get("output").get("output").asText());
System.out.println(j.get("charged_credits") + " " + reply.path("verdict").asText(reply.path("note").asText()));
for (JsonNode row : reply.path("catalog")) System.out.println("- " + row.path("tier").asText() + " " + row.path("gap").asText());
require "digest"
key = "expo-floor:#{input["task"]}:#{Digest::SHA256.hexdigest(JSON.generate(input))[0, 16]}:a1"
job = api("POST", "/run", input, { "Idempotency-Key" => key })
j = nil
loop do
sleep 2
j = api("GET", "/jobs/#{job["job_id"]}")
break if %w[succeeded failed cancelled].include?(j["status"])
end
reply = JSON.parse(j["output"]["output"])
puts [j["charged_credits"], j["truncated"], reply["verdict"] || reply["note"]].inspect
(reply["catalog"] || []).each { |row| puts "- #{row["tier"]} #{row["gap"]}" }
$key = "expo-floor:" . $input["task"] . ":" . substr(hash("sha256", json_encode($input)), 0, 16) . ":a1";
$job = api("POST", "/run", $input, ["Idempotency-Key" => $key]);
do { sleep(2); $j = api("GET", "/jobs/" . $job["job_id"]); }
while (!in_array($j["status"], ["succeeded", "failed", "cancelled"]));
$reply = json_decode($j["output"]["output"], true);
echo $j["charged_credits"], " ", ($reply["verdict"] ?? $reply["note"] ?? ""), "\n";
foreach ($reply["catalog"] ?? [] as $row) echo "- ", $row["tier"], " ", $row["gap"], "\n";
var digest = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(input.ToJsonString()));
var key = $"expo-floor:{input["task"]}:{Convert.ToHexString(digest, 0, 8).ToLowerInvariant()}:a1";
var job = await Api.Call("POST", "/run", input, new() { ["Idempotency-Key"] = key });
JsonNode j;
do { await Task.Delay(2000); j = (await Api.Call("GET", "/jobs/" + job!["job_id"]))!; }
while (!new[] { "succeeded", "failed", "cancelled" }.Contains(j["status"]!.GetValue<string>()));
var reply = JsonNode.Parse(j["output"]!["output"]!.GetValue<string>());
Console.WriteLine($"{j["charged_credits"]} {reply!["verdict"] ?? reply["note"]}");
foreach (var row in reply["catalog"] as JsonArray ?? new JsonArray()) Console.WriteLine("- " + row!["tier"] + " " + row["gap"]);
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: expo-floor:floor:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json
rev = json.load(open("input.json")) # the same run input as input.json: {"task": "floor", "event": "Event: ... | dates: ... | doors open, day one: ...", "tiers": "Tiers, top first - 3 ...", "venue": "Q4 access hours - ...", "notes": "", "facts": "Verdict: ..."}
# - see the input table
req = urllib.request.Request(BASE + "/run-stream", method="POST", data=json.dumps(rev).encode(),
headers={"Content-Type": "application/json", "Authorization": "Bearer " + TOKEN,
"Idempotency-Key": "expo-floor:floor:" + hashlib.sha256(json.dumps(rev).encode()).hexdigest()[:16] + ":a1"})
with urllib.request.urlopen(req) as r:
for line in r:
line = line.decode().strip()
if line.startswith("data:"):
print(line[5:].strip()[:200])
const rev = JSON.parse(readFileSync("input.json", "utf8"));
const r = await fetch(BASE + "/run-stream", { method: "POST", body: JSON.stringify(rev), headers: {
"Content-Type": "application/json", Authorization: "Bearer " + TOKEN,
"Idempotency-Key": `expo-floor:floor:${createHash("sha256").update(JSON.stringify(rev)).digest("hex").slice(0, 16)}:a1` } });
const dec = new TextDecoder();
for await (const chunk of r.body) for (const line of dec.decode(chunk).split("\n"))
if (line.startsWith("data:")) console.log(line.slice(5).trim().slice(0, 200));
rraw, _ := os.ReadFile("input.json") // add "bufio", "strings" to the imports
rs := sha256.Sum256(rraw)
req, _ := http.NewRequest("POST", base+"/run-stream", bytes.NewReader(rraw))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Idempotency-Key", "expo-floor:floor:"+hex.EncodeToString(rs[:8])+":a1")
res, _ := http.DefaultClient.Do(req)
sc := bufio.NewScanner(res.Body)
for sc.Scan() { if l := sc.Text(); strings.HasPrefix(l, "data:") { fmt.Println(l[5:]) } }
String rev = java.nio.file.Files.readString(java.nio.file.Path.of("input.json"));
var rd = java.security.MessageDigest.getInstance("SHA-256").digest(rev.getBytes());
var sreq = HttpRequest.newBuilder(URI.create(BASE + "/run-stream")).header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token).header("Idempotency-Key", "expo-floor:floor:" + HexFormat.of().formatHex(rd, 0, 8) + ":a1")
.POST(HttpRequest.BodyPublishers.ofString(rev)).build();
C.send(sreq, HttpResponse.BodyHandlers.ofLines()).body().filter(l -> l.startsWith("data:")).forEach(System.out::println);
rev = File.read("input.json")
uri = URI(BASE + "/run-stream")
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json", "Authorization" => "Bearer #{TOKEN}",
"Idempotency-Key" => "expo-floor:floor:#{Digest::SHA256.hexdigest(rev)[0, 16]}:a1")
req.body = rev
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |h|
h.request(req) { |res| res.read_body { |chunk| chunk.each_line { |l| puts l if l.start_with?("data:") } } }
end
$rev = file_get_contents("input.json");
$ch = curl_init(BASE . "/run-stream");
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $rev, CURLOPT_HTTPHEADER => [
"Content-Type: application/json", "Authorization: Bearer $TOKEN",
"Idempotency-Key: expo-floor:floor:" . substr(hash("sha256", $rev), 0, 16) . ":a1"],
CURLOPT_WRITEFUNCTION => function ($ch, $chunk) { foreach (explode("\n", $chunk) as $l) if (str_starts_with($l, "data:")) echo $l, "\n"; return strlen($chunk); }]);
curl_exec($ch);
var rev = File.ReadAllText("input.json");
var rd = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(rev));
var sreq = new HttpRequestMessage(HttpMethod.Post, Api.Base + "/run-stream") { Content = new StringContent(rev, System.Text.Encoding.UTF8, "application/json") };
sreq.Headers.Add("Authorization", "Bearer " + Api.Token);
sreq.Headers.Add("Idempotency-Key", $"expo-floor:floor:{Convert.ToHexString(rd, 0, 8).ToLowerInvariant()}:a1");
using var http = new HttpClient();
using var res = await http.SendAsync(sreq, HttpCompletionOption.ResponseHeadersRead);
using var rdr = new StreamReader(await res.Content.ReadAsStreamAsync());
for (string? l; (l = await rdr.ReadLineAsync()) != null;) if (l.StartsWith("data:")) Console.WriteLine(l);