Run Guest Protocol from your own code
Both metered lanes are available over HTTP and each returns one JSON object. The division of labour: the page routes speakers, sponsor personnel and press out first and stops when nobody is left, tests whoever remains for an obligation (external protocol, security, discretion, dependency exposure - never a title), re-ranks the four menus (identification breadth, program, visibility, escort depth) with every deleted rung struck, builds the roster with its holder, viewers and deletion date, sets each guest's visibility from only what they said, and lists the liaison intake, the two day-of decisions and the hand-offs - all free, in guestkit.js. The run explains the posture, or writes the greeter brief and the liaison intake; the page then holds the reply to its own board (guestreply.js). It never infers anyone's importance, identity, gender, nationality or visibility from a name or a title.
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":"guest-protocol"}), 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, guests, 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:
posture- the guest posture explained for the organizer to act on: the verdict, everyone routed out and to which sibling, who qualifies and on which obligation, who does not and why, the roster, the program, visibility and escort postures, the two day-of decisions, the hand-offs and the caveats.brief- the one-page greeter brief (who arrives, how to greet, what not to say, photographs, who to call), the liaison intake for any guest with their own protective detail, protocol officer or advance team, who decides on the day, and a note. The lane exists only when somebody is in scope.
A missing or unknown task is answered as posture. Both lanes send the same five fields; for the brief, the facts also carry the posture's picks, roster holder, visibility rows and decisions (the page fills these from the posture). The notes field may be an empty string.
The input
| Field | Required | What |
|---|---|---|
task | yes | posture or brief. If it is missing or neither, do posture and set "task": "posture". |
event | yes | the event basics (name, dates, city, attendance, the as-of date and days to doors) and the interview answers: Q1 the mode, Q2 the pole, its owner and its register, Q4 whether a detailed guest's office actually made contact, Q6 the badge print run, seating plan and run of show, Q7 one-off or recurring, Q8 the effort ceiling, the people who can be pulled off and the owner, Q9 the list's size, compiler, viewers, deletion date and assets, and the day-of names. |
guests | yes | one line per named guest as entered: name, role as given, why a guest, on the program, sponsor contract, press, what they arrive with, stated visibility, whether the event depends on the relationship, and any need written as a provision. |
notes | no | pasted notes; may be empty. A request in the notes is never a commitment. |
facts | yes | the page's verdict, its self-set lines, the routed, qualified and not-qualified rows (each list says how many it holds and how many were cut), the four menus re-ranked, the roster, the program, the visibility rows, the escort, the greeter brief items, the what-not-to-say lines, the photograph lines, the liaison intake rows and items, the two day-of decisions, the hand-offs - each item with its own must line - for the brief task the posture 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
- Four siblings own most of what people call a VIP. Route them out first: anyone on the program goes to samber/dev-event-organizer-skills@event-speaker-experience, however senior; anyone covered by a signed sponsorship to samber/dev-event-organizer-skills@event-sponsor-fulfillment; anyone filing copy to samber/dev-event-organizer-skills@event-press-relations; a general attendee stays with samber/dev-event-organizer-skills@event-attendee-experience. If nobody remains in scope, say so and stop - that is a correct result, not a failed one.
- The qualifying fact is an obligation, never a title. Four types qualify and nothing else does: external protocol, security, discretion, and dependency exposure - the last only when the relationship recurs. A senior person who arrives alone, unescorted, with no stated requirement is an attendee with an impressive job.
- Visibility is never inferred: only what the guest or their office said - introduced, unremarked, or not said. A guest who has not been asked is a guess, not a preference; where there is still time, ask rather than decide.
- A closed badge print run and seating plan delete both marker rungs; a flat, explicitly anti-hierarchy register deletes the broad notability list, and the formal program when no external obligation exists; a guest who asked to move through the day unremarked at a flat register deletes the full-visit escort.
- Security and protective-detail decisions belong to the guest's own detail, not the organizer: the liaison intake receives their plan, answers each item yes, no or a substitute in writing, names one counterpart, and states that the code of conduct applies to them.
- The roster is personal data: a named holder, named viewers by need never by seniority, a deletion date set now, and never a judgment about a person.
- Name in advance who decides on the spot when a photograph is requested and who says no on the guest's behalf. Consent to a photograph is never implied by attendance.
House rules
- Use only the input and the rules above. Copy the page's short facts exactly: the verdict, names, sibling names, obligation types, the roster's breadth, fields, holder, viewers and deletion date, every pick, every posture, what each guest said, and every name against a decision. Every number in your text must appear in the input.
- Every "must: [...]" line in the facts applies to the item directly above it - every routed guest, every qualified guest, every guest not qualified, every visibility row, every liaison row, every decision and every hand-off, not only the first. Do every item it lists.
- Copy the page's rows exactly as sent, in order - no more, no fewer. When the facts say rows were cut, do not invent the cut rows.
- 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 lines self-set.
- Never invent a guest, an obligation, a title, a security measure, a stated preference, a date or a person. Never name an obligation type the page did not find for that guest, and never state a percentage.
- Never describe anyone as important, famous or senior beyond the title given - no "important", "famous", "prominent", "notable", "senior" or "VIP" about a person, except in a sentence that refuses the word (for example "never say VIP").
- Never infer visibility: what each guest said is the page's word, exactly - "introduced", "unremarked" or "not said".
- Refer to people by name, 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
posture
summary- one sentence, at most 40 words: the verdict, the most important open item, and the next step.verdict- the page's verdict, exactly:nobody in scope - stop,fix first,ask the guests firstorready to brief the greeters.routed- one object per routed row the page sent, in its order, every row, not only the first:name- exactly as the page gives it;to- the page's sibling exactly (for example "event-speaker-experience", "event-sponsor-fulfillment" or "event-press-relations").[]when the page sent none.qualified- one object per qualified row the page sent, in its order, every row:name- exactly;obligation- one sentence that uses the words of every obligation type on the row's must line ("security", "external protocol", "discretion", "dependency exposure") and names no other type.[]when the page sent none.not_qualified- one object per not-qualified row the page sent, in its order, every row:name- exactly;reason- one sentence using the row's word: "obligation" when no obligation is stated (however senior the title), "recurs" when dependency exposure fails because the relationship does not recur.[]when the page sent none.roster- one object:breadth- the page's breadth exactly (the word "none" when the verdict isnobody in scope - stop);fields- the page's fields exactly, in order ([]when the page lists none);holder- the page's holder exactly, or the words "not named";viewers- the page's viewers exactly, in order ([]when none are named);delete_by- the page's deletion date exactly, or the words "not set".program- one object:pick- the page's program posture, exactly;reason- one sentence that says what moved the pick, using the page's word from the program must line: the question number (for example "Q3", "Q4", "Q7" or "Q9") when an interview answer moved it, or the word "default" when nothing did.visibility- one object per visibility row the page sent, in its order, every row:name,postureandsaidexactly as the page gives them.[]when the page sent none.escort- one object:pick- the page's escort depth, exactly (the word "none" when the verdict isnobody in scope - stop);reason- one sentence using the page's word from the escort must line (the question number, or the word "default").decisions- one object per day-of decision the page sent, in its order:decision- names it, using the row's word ("photograph" for who decides on a photograph request, "no" for who says no on the guest's behalf);who- the page's name exactly, or the words "not named".[]when the page sent none.handoffs- one string per hand-off the page sent, in its order, every one: says what is handed off and contains each sibling the row names (for example "event-schedule-design" and "event-run-of-show").[]when the page sent none.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": "posture",
"summary": "one sentence",
"verdict": "fix first",
"routed": [ { "name": "the page's name", "to": "event-speaker-experience" } ],
"qualified": [ { "name": "the page's name", "obligation": "one sentence" } ],
"not_qualified": [ { "name": "the page's name", "reason": "one sentence" } ],
"roster": { "breadth": "the page's breadth", "fields": [ "Name" ], "holder": "the page's holder", "viewers": [ "the page's viewer" ], "delete_by": "the page's date" },
"program": { "pick": "the page's pick", "reason": "one sentence" },
"visibility": [ { "name": "the page's name", "posture": "the page's posture", "said": "not said" } ],
"escort": { "pick": "the page's pick", "reason": "one sentence" },
"decisions": [ { "decision": "photograph request", "who": "the page's name" } ],
"handoffs": [ "one sentence" ],
"caveats": [ "a caveat" ]
}
The page holds it to its own board: the verdict exactly; every routed guest by name, sent to the sibling the page names; every qualified guest by name with the words of each obligation type the page found and no other; every guest not qualified with the reason's word ("obligation" or "recurs"); the roster's breadth, fields, holder, viewers and deletion date exactly; the program and escort picks exactly, each with the question that moved it or "default"; every visibility row's name, posture and what the guest said; the two day-of decisions with the name against each; every hand-off naming its sibling; caveats when the page has a fix; and no number, percentage, quote, ranking word or pronoun the input does not hold. Required words are read tolerantly: "a protective detail" is security, "recurs edition after edition" is Q7.
brief
greeter_brief- one object:title- one line; it must contain the event's name exactly.who_arrives- one object per visibility row the page sent, in its order, every row, not only the first:name- exactly;arrival- when and where, only as the input states it, or the words "not given" with whom to confirm it;said- what the guest said about visibility, exactly ("introduced", "unremarked" or "not said").how_to_greet- one short paragraph following the escort depth, using the page's word: "greet" for a named greeter for arrival only, "card" for a printed contact card, "escort" for a dedicated escort for the visit, "liaison" for an escort with a protocol or security liaison. Give each guest's visibility instruction in one line, in plain words.what_not_to_say- the page's what-not-to-say lines, one string each, using the words "introduce", "VIP", "explain" and "departure".photos- one or two sentences: the page's photograph decider by name exactly (or the words "not named"), the word "photo", and the two lines for declining a photograph.escalation- one sentence: who to call when anything goes wrong, naming the page's owner exactly (or the words "not named").liaison_intake- one object per liaison row the page sent, in its order, every row:name- exactly;items- the intake as short strings, using the words "counterpart", "verbatim", "substitute", "route", "code of conduct" and "team".[]when no guest arrives with their own protective detail, protocol officer or advance team - the intake runs only then.day_of- one object per day-of decision the page sent, in its order:decision- names it, using the row's word ("photograph" or "no");who- the page's name exactly, or the words "not named".note- one sentence: when the page's verdict is notready to brief the greeters, begin with "Not ready to brief:" and say what to fix first; otherwise use the word "brief" and say what happens next.
{
"task": "brief",
"greeter_brief": {
"title": "the event's name - greeter brief",
"who_arrives": [ { "name": "the page's name", "arrival": "as the input states it", "said": "introduced" } ],
"how_to_greet": "one paragraph",
"what_not_to_say": [ "one line" ],
"photos": "one or two sentences",
"escalation": "one sentence"
},
"liaison_intake": [ { "name": "the page's name", "items": [ "one line" ] } ],
"day_of": [ { "decision": "photograph request", "who": "the page's name" } ],
"note": "one sentence"
}
The page requires the event's name in the greeter brief's title; one arrival per visibility row, with the name and what the guest said exactly; the escort's word in how to greet ("greet", "card", "escort" or "liaison"); the four what-not-to-say lines (introduce, VIP, explain, departure); the photograph decider and "photo" in photos; the owner in the escalation; one liaison intake per guest with their own detail, covering counterpart, verbatim, substitute, route, code of conduct and team; the two day-of decisions; and a note beginning "Not ready to brief:" unless the page is ready.
Worked examples - both lanes
Two of the page's four free samples (fictional events, organizations 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 brief input carries its sample's saved posture, as the handoff does.
A 1,200-person vendor conference - a minister with a detail, a funder, a keynote CTO, sponsors and press; no deletion date - posture
Verdict: fix first; ready to brief: no; 7 named guests, 4 routed out, 2 qualified; roster: Obligation + relationship list; program: Formal named program with dedicated staff; escort: Escort + protocol/security liaison; liaison intakes: 1; 2 fix-level findings.
Input:
{
"task": "posture",
"event": "Event: \"Port Avery Cloud Summit 2027\" | dates: 2027-06-14 to 2027-06-15 | city: \"Port Avery\" | attendance: 1200 | as of: 2027-05-24 | days to doors: 21\nQ1 mode: \"set a posture before an edition\"\nQ2 pole: \"vendor/corporate-run\" | who owns it: \"Northwind Cloud, the host company\" | register: \"comfortable recognizing who is in the room\"\nQ4 a detailed guest's office: \"their office has actually contacted us\"\nQ6 badge print run: \"still open\" | print run closes: 2027-05-27 | seating plan: \"still open\" | run of show: \"still open\"\nQ7 the relationship: \"a relationship that recurs edition after edition\"\nQ8 effort ceiling: \"medium\" | people who can be pulled off on the day: 2 | owner: \"Marta Kowal\"\nQ9 named guests: 7 | compiler: \"Marta Kowal\" | viewers: [\"Sam Ortiz\"; \"Dee Rahman\"] | deletion date: \"not set\" | assets: [a venue with a second entrance; a team member with government or protocol experience]\nDay-of names: photograph decider: \"not named\" | says no on the guest's behalf: \"Marta Kowal\" | counterpart for a detail: \"Marta Kowal\"",
"guests": "Named guests - 7, one per line, as entered (Q3 and Q5 per guest):\n- guest 1: \"Anouk Verhoeven\" | role as given: \"Deputy Minister for Digital Infrastructure\" | why a guest: \"the ministry's office wrote that the deputy minister will attend the opening keynote\" | on the program: no | sponsor contract: no | press: no | arrives with: [a protective detail; a protocol officer] | stated visibility: \"introduced\" | the event depends on the relationship: no | needs: \"step-free route to the keynote hall\"\n- guest 2: \"Rafael Montoya\" | role as given: \"Programme Director, Tessaly Foundation\" | why a guest: \"the foundation funds the open-source track every edition\" | on the program: no | sponsor contract: no | press: no | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: yes | needs: \"none stated\"\n- guest 3: \"Priya Raman\" | role as given: \"CTO, Kestrel Systems\" | why a guest: \"gives the day-one keynote\" | on the program: yes | sponsor contract: no | press: no | arrives with: \"nothing stated\" | stated visibility: \"introduced\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 4: \"Tomasz Wilk\" | role as given: \"VP Sales, Brightwave\" | why a guest: \"the platinum sponsorship covers the booth team\" | on the program: no | sponsor contract: yes | press: no | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 5: \"Hana Ito\" | role as given: \"CEO, Lumora Data\" | why a guest: \"the gold sponsorship covers the executive pass\" | on the program: no | sponsor contract: yes | press: no | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 6: \"Jonas Feld\" | role as given: \"Reporter, The Ledger Weekly\" | why a guest: \"accredited to cover the launch\" | on the program: no | sponsor contract: no | press: yes | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 7: \"Carl Aberg\" | role as given: \"Retired founder, Aberg Systems\" | why a guest: \"bought a ticket and is well known in the industry\" | on the program: no | sponsor contract: no | press: no | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"",
"notes": "From the deputy minister's advance office, 2027-05-20: a protective officer will walk the route from the north entrance to the keynote hall on 2027-06-13. The departure time must stay off the published schedule. The deputy minister would like to be introduced at the opening keynote. Please confirm in writing what the venue can and cannot do.",
"facts": "Verdict: \"fix first\" | ready to brief the greeters: no | fix-level findings: 2\nSelf-set lines: [a handful is at most 5 qualified guests; asking needs at least 3 days before doors; a roster kept more than 90 days after the event is flagged; at most 30 rows of each list are sent; a summary cap of 40 words; at most 5 caveats; the reading of the Q9 assets is the page's own; an unsaid pole reads as community]\nNever stated: [a guest, an obligation, a title or a stated preference the input does not hold; a security measure; a date or a person the input does not hold; anyone's importance, identity, gender or nationality; a visibility nobody said]\nRoute-out (step 1) - routed: 4 | rows below: 4 of 4 | cut: 0 (at most 30 sent, self-set) - in this order:\n- routed 1: name: \"Priya Raman\" | to: \"event-speaker-experience\" | why: on the program - every speaker belongs to speaker experience, however senior\n must: [name \"Priya Raman\" exactly; to \"event-speaker-experience\" exactly]\n- routed 2: name: \"Tomasz Wilk\" | to: \"event-sponsor-fulfillment\" | why: covered by a signed sponsorship - sponsor fulfillment delivers every promised perk\n must: [name \"Tomasz Wilk\" exactly; to \"event-sponsor-fulfillment\" exactly]\n- routed 3: name: \"Hana Ito\" | to: \"event-sponsor-fulfillment\" | why: covered by a signed sponsorship - sponsor fulfillment delivers every promised perk\n must: [name \"Hana Ito\" exactly; to \"event-sponsor-fulfillment\" exactly]\n- routed 4: name: \"Jonas Feld\" | to: \"event-press-relations\" | why: here to file copy - press relations claims accreditation, embargoes and on-site press handling\n must: [name \"Jonas Feld\" exactly; to \"event-press-relations\" exactly]\nIn scope after the route-out: 3 | qualified: 2 | stop: no\nQualification (step 2) - qualified, an obligation never a title: 2 | rows below: 2 of 2 | cut: 0 (at most 30 sent, self-set) - in this order:\n- qualified 1: name: \"Anouk Verhoeven\" | obligation: \"security, external protocol\" | stated: [arrives with a protective detail; arrives with a protocol officer; asked to be introduced]\n must: [name \"Anouk Verhoeven\" exactly; obligation uses the words \"security\" and \"external protocol\"]\n- qualified 2: name: \"Rafael Montoya\" | obligation: \"dependency exposure\" | stated: [the event depends on this relationship, and it recurs]\n must: [name \"Rafael Montoya\" exactly; obligation uses the words \"dependency exposure\"]\nNot qualified - no obligation, however senior the title: 1 | rows below: 1 of 1 | cut: 0 (at most 30 sent, self-set) - in this order:\n- not qualified 1: name: \"Carl Aberg\" | reason: \"no obligation stated - however senior the title, an attendee, the general attendee flow, unchanged\"\n must: [name \"Carl Aberg\" exactly; reason uses the word \"obligation\"]\nIdentification breadth menu (step 3), re-ranked - pick: \"Obligation + relationship list\"\n- rung 1: \"Obligation + relationship list\" | moved: promoted by Q3 and Q7: the relationship recurs and Rafael Montoya's visit is itself a deliverable to it\n- rung 2: \"Obligation-only list\"\n- rung 3: \"No defined list\"\n- rung 4: \"Broad notability list\"\n- notes: Value and effort run in the same order: zero dominance relations, clean by construction, not a pass. Promotion for the broad list: essentially none at a technical conference - ask which obligation each extra name carries.\nRoster (step 3): breadth: \"Obligation + relationship list\" | holder: \"Marta Kowal\" | viewers: [\"Sam Ortiz\"; \"Dee Rahman\"] | delete by: \"not set\" | fields - 6: [\"Name\"; \"Obligation type\"; \"Stated requirements\"; \"What was refused\"; \"Named organizer\"; \"Visibility answer\"]\n roster must: [breadth \"Obligation + relationship list\" exactly; fields copies the 6 fields above, in this order; holder \"Marta Kowal\" exactly; viewers copies the 2 names above, in this order; delete_by \"not set\" exactly]\nProgram posture menu (step 4), re-ranked - pick: \"Formal named program with dedicated staff\"\n- rung 1: \"Formal named program with dedicated staff\" | moved: made the pick by Q4 and Q7: a guest arrives with their own detail or advance team and it recurs - you are the standing counterpart to somebody else's standing process\n- rung 2: \"Defined criteria + protocol runbook\" | moved: promoted by Q9: a team member with protocol experience can write the runbook (the page's own reading of the asset)\n- rung 3: \"Ad hoc invisible accommodation\"\n- rung 4: \"No posture\"\n- notes: Value and effort run in the same order: zero dominance relations, clean by construction, not a pass. Compliance cost: the runbook triggers a data-handling review ad hoc skips; ad hoc spends the reversibility the runbook keeps.\nProgram: pick: \"Formal named program with dedicated staff\" | moved by: \"Q4 and Q7\"\n program must: [pick \"Formal named program with dedicated staff\" exactly; reason uses the word \"Q4 and Q7\"]\nVisibility and discretion menu (step 5), re-ranked at the vendor/corporate-run pole - pick: \"Public marker + recognition moment\"\n- rung 1: \"Public marker + recognition moment\" | moved: promoted by Q2 and Q5: Anouk Verhoeven asked to be introduced, in as many words, at a vendor-run event\n- rung 2: \"Staff-only signal\"\n- rung 3: \"Visible marker\" | moved: demoted by Q5: no guest asked for it in as many words - a marker nobody chose is a tier\n- rung 4: \"Invisible handling\"\n- notes: Dominance check, vendor pole - clean by construction: value and effort run in the same order, so the line rests on its own argument.\nVisibility (step 5) - per qualified guest, only what each said: 2 | rows below: 2 of 2 | cut: 0 (at most 30 sent, self-set) - in this order:\n- visibility 1: name: \"Anouk Verhoeven\" | posture: \"Public marker + recognition moment\" | said: \"introduced\" | moved by: \"Q2 and Q5\"\n must: [name \"Anouk Verhoeven\" exactly; posture \"Public marker + recognition moment\" exactly; said \"introduced\" exactly]\n- visibility 2: name: \"Rafael Montoya\" | posture: \"Staff-only signal\" | said: \"not said\" | moved by: \"Q5\"\n must: [name \"Rafael Montoya\" exactly; posture \"Staff-only signal\" exactly; said \"not said\" exactly]\nEscort depth menu (step 6), re-ranked - pick: \"Escort + protocol/security liaison\"\n- rung 1: \"Escort + protocol/security liaison\" | moved: made the pick by Q4: Anouk Verhoeven arrives with their own detail, protocol officer or advance team - you are the counterpart to somebody else's plan; seniority never promotes this rung\n- rung 2: \"Named greeter for arrival only\" | moved: promoted by Q9: a venue with a second entrance - one greeter at that door meets the arrival (the page's own reading of the asset)\n- rung 3: \"Printed contact card\"\n- rung 4: \"Dedicated escort for the visit\"\n- notes: Value and effort run in the same order: zero dominance relations, clean by construction, not a pass. Only the liaison rung carries a review, and it belongs to the guest's own institution.\nEscort: pick: \"Escort + protocol/security liaison\" | moved by: \"Q4\"\n escort must: [pick \"Escort + protocol/security liaison\" exactly; reason uses the word \"Q4\"]\nGreeter brief items (step 6): [who you are meeting - their name, and a photograph only if their office supplied one; when and where, with a fallback if they are late and a phone number that will be answered; the route: door, cloakroom, coffee, the room, the toilets and the exit they will leave by; what they asked for, quoted, and what was refused, quoted; the visibility instruction in one line, in plain words; your handoff: the person you hand them to, and what you do if that person is not there]\nWhat not to say: [never introduce the guest to anyone who has not been told they are coming; never say VIP, to the guest or anyone else, including on the radio; never explain the arrangements to a curious attendee; never volunteer a departure time to anyone]\nDeclining a photograph: [to an attendee: Not right now, sorry - we are on a tight schedule; to a photographer or someone filming: No photos of this group, please]\nDiscretion mechanics for the postures in use - 2:\n- \"Public marker + recognition moment\": the office asked for it in as many words; nothing about their movements is published that their security posture forbids; the run of show absorbs it - event-run-of-show's call\n- \"Staff-only signal\": the door lead gets a name and an arrival window, nothing else; the room leads get the name and one instruction - no announcement, no reserved seat, route any question to the named organizer; the code-of-conduct responders get the name\nLiaison intake (step 7) - guests with their own detail, protocol officer or advance team: 1 | rows below: 1 of 1 | cut: 0 (at most 30 sent, self-set) - in this order:\n- liaison 1: name: \"Anouk Verhoeven\" | arrives with: [a protective detail; a protocol officer]\n must: [name \"Anouk Verhoeven\" exactly; items use the words \"counterpart\", \"verbatim\", \"substitute\", \"route\", \"code of conduct\" and \"team\"]\nLiaison intake items: [name one counterpart on your side, with a number answered from the day before until the guest leaves; ask what they need and write it down verbatim; answer each item in writing - yes, no or a substitute - before the day; walk the route with them if they ask; state that the code of conduct applies to them, in the same message; tell your own team what changes and nothing more]\nDay-of decisions (step 8) - 2 - in this order:\n- decision 1: decision: \"photograph request\" | who: \"not named\"\n must: [decision uses the word \"photograph\"; who \"not named\" exactly]\n- decision 2: decision: \"say no on the guest's behalf\" | who: \"Marta Kowal\"\n must: [decision uses the word \"no\"; who \"Marta Kowal\" exactly]\nHand-offs (step 9) - 5 - in this order:\n- handoff 1: \"Seating against the grid\" | to: [event-schedule-design; event-run-of-show]\n must: [contains \"event-schedule-design\" and \"event-run-of-show\"]\n- handoff 2: \"Anything touching the general check-in desk\" | to: [event-attendee-experience]\n must: [contains \"event-attendee-experience\"]\n- handoff 3: \"The access needs of Anouk Verhoeven - an access question first, a guest question second\" | to: [event-accessibility-inclusion]\n must: [contains \"event-accessibility-inclusion\"]\n- handoff 4: \"Anything that becomes a crowd, medical or credible-threat question\" | to: [event-risk-management]\n must: [contains \"event-risk-management\"]\n- handoff 5: \"The scope clause that binds a guest's own detail like any third party\" | to: [event-code-of-conduct]\n must: [contains \"event-code-of-conduct\"]\nPosture must: [summary at most 40 words; verdict \"fix first\" exactly; routed copies the 4 rows above, in this order; qualified copies the 2 rows above, in this order; not_qualified copies the 1 row above, in this order; visibility copies the 2 rows above, in this order; decisions copies the 2 rows above, in this order; handoffs copies the 5 rows above, in this order; caveats carry the fix findings first, at most 5]\nBrief must: [title contains \"Port Avery Cloud Summit 2027\"; who_arrives copies the 2 rows above, in this order, with name and said exactly; how_to_greet uses the word \"liaison\"; what_not_to_say uses the words \"introduce\", \"VIP\", \"explain\" and \"departure\"; photos uses the words \"not named\" and \"photo\"; escalation contains \"Marta Kowal\"; liaison_intake copies the 1 row above, in this order; day_of copies the 2 rows above, in this order] | brief note must: [begin \"Not ready to brief:\" and say what to fix first]\nFindings (16):\n[fix] roster_delete (roster): Q9: set the roster's deletion date now, by the holder, in the same pass - not after the event, when nobody is looking. Default: the day the post-event follow-ups are sent.\n[fix] decision_photo (day): Step 8: name who decides on the spot when a photograph is requested - name someone in advance, or whoever is standing there decides under time pressure.\n[check] public_1 (visibility): \"Anouk Verhoeven\": a recognition moment, three checks before it goes in the run of show - their office asked for it in as many words; nothing about their movements is published that their security posture forbids (confirm it with the detail); the run of show absorbs it without pushing a talk, which is event-run-of-show's call.\n[check] ask_2 (visibility): Q5: \"Rafael Montoya\"'s visibility was never said - ask the guest or their office before deciding; a guest who has not been asked is a guess, not a preference. Until then: Staff-only signal.\n[check] print_soon (time): Q6: the badge print run closes on 2027-05-27, within the self-set 3 days - ask any guest whose visibility is not said before then, or the marker rungs go with it.\n[info] routed_speaker (route): Routed out to samber/dev-event-organizer-skills@event-speaker-experience: \"Priya Raman\" - on the program - every speaker belongs to speaker experience, however senior. Not yours.\n[info] routed_sponsor (route): Routed out to samber/dev-event-organizer-skills@event-sponsor-fulfillment: \"Tomasz Wilk\" and \"Hana Ito\" - covered by a signed sponsorship - sponsor fulfillment delivers every promised perk. Not yours.\n[info] routed_press (route): Routed out to samber/dev-event-organizer-skills@event-press-relations: \"Jonas Feld\" - here to file copy - press relations claims accreditation, embargoes and on-site press handling. Not yours.\n[info] press_exposure (route): Press relations owns accreditation, embargoes and the press room. Yours is only a guest's own exposure to press - declining a photograph on their behalf, keeping a departure time off the schedule.\n[info] not_qualified (qualify): Not in scope, on the test: \"Carl Aberg\" (no obligation stated - however senior the title, an attendee; the general attendee flow, unchanged). A senior person who arrives alone, unescorted, with no stated requirement is an attendee with an impressive job - route to samber/dev-event-organizer-skills@event-attendee-experience and do nothing.\n[info] roster_rules (roster): The roster never records a judgment about a person - no notable, no important, no seniority note; every field is a fact the guest's office supplied or a decision you can defend. The door lead needs the name and the arrival window, never the requirements or the reason.\n[info] liaison_rule (liaison): The intake receives a plan: it is not a negotiation about status, and not the moment to promote every other menu - a guest with a protective detail still gets the visibility posture their office asked for. Make contact before the run of show goes public.\n[info] consent_photo (day): Consent to a photograph is never implied by attendance, and it is not the organizer's to give. Where an image the guest's posture forbids was already taken, the ask goes to the person who took it, in private, immediately.\n[info] notes (context): The pasted notes are context: a request in the notes is answered in writing - yes, no or a substitute - never a silent commitment.\n[info] departure (context): Never volunteer a departure time to anyone, and keep it off the published schedule.\n[info] scope (scope): The page never infers anyone's importance, identity, gender, nationality or visibility from a name or a title: every obligation, requirement and visibility answer here was stated by the guest, their office or you."
}
Reply:
{
"task": "posture",
"summary": "Fix first: the roster has no deletion date and nobody decides on a photograph request - set both, then ask the funder's office how visible to be before the print run closes.",
"verdict": "fix first",
"routed": [
{
"name": "Priya Raman",
"to": "event-speaker-experience"
},
{
"name": "Tomasz Wilk",
"to": "event-sponsor-fulfillment"
},
{
"name": "Hana Ito",
"to": "event-sponsor-fulfillment"
},
{
"name": "Jonas Feld",
"to": "event-press-relations"
}
],
"qualified": [
{
"name": "Anouk Verhoeven",
"obligation": "security, external protocol - arrives with a protective detail; arrives with a protocol officer; asked to be introduced"
},
{
"name": "Rafael Montoya",
"obligation": "dependency exposure - the event depends on this relationship, and it recurs"
}
],
"not_qualified": [
{
"name": "Carl Aberg",
"reason": "No obligation stated - however senior the title, an attendee; the general attendee flow, unchanged."
}
],
"roster": {
"breadth": "Obligation + relationship list",
"fields": [
"Name",
"Obligation type",
"Stated requirements",
"What was refused",
"Named organizer",
"Visibility answer"
],
"holder": "Marta Kowal",
"viewers": [
"Sam Ortiz",
"Dee Rahman"
],
"delete_by": "not set"
},
"program": {
"pick": "Formal named program with dedicated staff",
"reason": "Q4 and Q7: a guest arrives with their own detail or advance team and it recurs - you are the standing counterpart to somebody else's standing process."
},
"visibility": [
{
"name": "Anouk Verhoeven",
"posture": "Public marker + recognition moment",
"said": "introduced"
},
{
"name": "Rafael Montoya",
"posture": "Staff-only signal",
"said": "not said"
}
],
"escort": {
"pick": "Escort + protocol/security liaison",
"reason": "Q4: Anouk Verhoeven arrives with their own detail, protocol officer or advance team - you are the counterpart to somebody else's plan."
},
"decisions": [
{
"decision": "photograph request",
"who": "not named"
},
{
"decision": "say no on the guest's behalf",
"who": "Marta Kowal"
}
],
"handoffs": [
"Seating against the grid - event-schedule-design and event-run-of-show",
"Anything touching the general check-in desk - event-attendee-experience",
"The access needs of Anouk Verhoeven - an access question first, a guest question second - event-accessibility-inclusion",
"Anything that becomes a crowd, medical or credible-threat question - event-risk-management",
"The scope clause that binds a guest's own detail like any third party - event-code-of-conduct"
],
"caveats": [
"Set the roster's deletion date now, by the holder, in the same pass - not after the event, when nobody is looking.",
"Name who decides on the spot when a photograph is requested - name someone in advance, or whoever is standing there decides under time pressure.",
"\"Anouk Verhoeven\": a recognition moment, three checks before it goes in the run of show - their office asked for it in as many words; nothing about their movements is published that their security posture forbids (confirm it with the detail); the run of show absorbs it without pushing a talk, which is event-run-of-show's call.",
"\"Rafael Montoya\"'s visibility was never said - ask the guest or their office before deciding; a guest who has not been asked is a guess, not a preference.",
"The badge print run closes on 2027-05-27, within the self-set 3 days - ask any guest whose visibility is not said before then, or the marker rungs go with it."
]
}
The page's check: kept - nothing to flag
The same, deletion date and photo decider named, the funder asked - ready to brief - brief
Verdict: ready to brief the greeters; ready to brief: yes; 7 named guests, 4 routed out, 2 qualified; roster: Obligation + relationship list; program: Formal named program with dedicated staff; escort: Escort + protocol/security liaison; liaison intakes: 1; 0 fix-level findings.
Input:
{
"task": "brief",
"event": "Event: \"Port Avery Cloud Summit 2027\" | dates: 2027-06-14 to 2027-06-15 | city: \"Port Avery\" | attendance: 1200 | as of: 2027-05-24 | days to doors: 21\nQ1 mode: \"set a posture before an edition\"\nQ2 pole: \"vendor/corporate-run\" | who owns it: \"Northwind Cloud, the host company\" | register: \"comfortable recognizing who is in the room\"\nQ4 a detailed guest's office: \"their office has actually contacted us\"\nQ6 badge print run: \"still open\" | print run closes: 2027-05-27 | seating plan: \"still open\" | run of show: \"still open\"\nQ7 the relationship: \"a relationship that recurs edition after edition\"\nQ8 effort ceiling: \"medium\" | people who can be pulled off on the day: 2 | owner: \"Marta Kowal\"\nQ9 named guests: 7 | compiler: \"Marta Kowal\" | viewers: [\"Sam Ortiz\"; \"Dee Rahman\"] | deletion date: \"2027-06-30\" | assets: [a venue with a second entrance; a team member with government or protocol experience]\nDay-of names: photograph decider: \"Dee Rahman\" | says no on the guest's behalf: \"Marta Kowal\" | counterpart for a detail: \"Marta Kowal\"",
"guests": "Named guests - 7, one per line, as entered (Q3 and Q5 per guest):\n- guest 1: \"Anouk Verhoeven\" | role as given: \"Deputy Minister for Digital Infrastructure\" | why a guest: \"the ministry's office wrote that the deputy minister will attend the opening keynote\" | on the program: no | sponsor contract: no | press: no | arrives with: [a protective detail; a protocol officer] | stated visibility: \"introduced\" | the event depends on the relationship: no | needs: \"step-free route to the keynote hall\"\n- guest 2: \"Rafael Montoya\" | role as given: \"Programme Director, Tessaly Foundation\" | why a guest: \"the foundation funds the open-source track every edition\" | on the program: no | sponsor contract: no | press: no | arrives with: \"nothing stated\" | stated visibility: \"unremarked\" | the event depends on the relationship: yes | needs: \"none stated\"\n- guest 3: \"Priya Raman\" | role as given: \"CTO, Kestrel Systems\" | why a guest: \"gives the day-one keynote\" | on the program: yes | sponsor contract: no | press: no | arrives with: \"nothing stated\" | stated visibility: \"introduced\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 4: \"Tomasz Wilk\" | role as given: \"VP Sales, Brightwave\" | why a guest: \"the platinum sponsorship covers the booth team\" | on the program: no | sponsor contract: yes | press: no | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 5: \"Hana Ito\" | role as given: \"CEO, Lumora Data\" | why a guest: \"the gold sponsorship covers the executive pass\" | on the program: no | sponsor contract: yes | press: no | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 6: \"Jonas Feld\" | role as given: \"Reporter, The Ledger Weekly\" | why a guest: \"accredited to cover the launch\" | on the program: no | sponsor contract: no | press: yes | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"\n- guest 7: \"Carl Aberg\" | role as given: \"Retired founder, Aberg Systems\" | why a guest: \"bought a ticket and is well known in the industry\" | on the program: no | sponsor contract: no | press: no | arrives with: \"nothing stated\" | stated visibility: \"not said\" | the event depends on the relationship: no | needs: \"none stated\"",
"notes": "From the deputy minister's advance office, 2027-05-20: a protective officer will walk the route from the north entrance to the keynote hall on 2027-06-13. The departure time must stay off the published schedule. The deputy minister would like to be introduced at the opening keynote. Please confirm in writing what the venue can and cannot do.",
"facts": "Verdict: \"ready to brief the greeters\" | ready to brief the greeters: yes | fix-level findings: 0\nSelf-set lines: [a handful is at most 5 qualified guests; asking needs at least 3 days before doors; a roster kept more than 90 days after the event is flagged; at most 30 rows of each list are sent; a summary cap of 40 words; at most 5 caveats; the reading of the Q9 assets is the page's own; an unsaid pole reads as community]\nNever stated: [a guest, an obligation, a title or a stated preference the input does not hold; a security measure; a date or a person the input does not hold; anyone's importance, identity, gender or nationality; a visibility nobody said]\nRoute-out (step 1) - routed: 4 | rows below: 4 of 4 | cut: 0 (at most 30 sent, self-set) - in this order:\n- routed 1: name: \"Priya Raman\" | to: \"event-speaker-experience\" | why: on the program - every speaker belongs to speaker experience, however senior\n must: [name \"Priya Raman\" exactly; to \"event-speaker-experience\" exactly]\n- routed 2: name: \"Tomasz Wilk\" | to: \"event-sponsor-fulfillment\" | why: covered by a signed sponsorship - sponsor fulfillment delivers every promised perk\n must: [name \"Tomasz Wilk\" exactly; to \"event-sponsor-fulfillment\" exactly]\n- routed 3: name: \"Hana Ito\" | to: \"event-sponsor-fulfillment\" | why: covered by a signed sponsorship - sponsor fulfillment delivers every promised perk\n must: [name \"Hana Ito\" exactly; to \"event-sponsor-fulfillment\" exactly]\n- routed 4: name: \"Jonas Feld\" | to: \"event-press-relations\" | why: here to file copy - press relations claims accreditation, embargoes and on-site press handling\n must: [name \"Jonas Feld\" exactly; to \"event-press-relations\" exactly]\nIn scope after the route-out: 3 | qualified: 2 | stop: no\nQualification (step 2) - qualified, an obligation never a title: 2 | rows below: 2 of 2 | cut: 0 (at most 30 sent, self-set) - in this order:\n- qualified 1: name: \"Anouk Verhoeven\" | obligation: \"security, external protocol\" | stated: [arrives with a protective detail; arrives with a protocol officer; asked to be introduced]\n must: [name \"Anouk Verhoeven\" exactly; obligation uses the words \"security\" and \"external protocol\"]\n- qualified 2: name: \"Rafael Montoya\" | obligation: \"discretion, dependency exposure\" | stated: [asked to move through the day unremarked; the event depends on this relationship, and it recurs]\n must: [name \"Rafael Montoya\" exactly; obligation uses the words \"discretion\" and \"dependency exposure\"]\nNot qualified - no obligation, however senior the title: 1 | rows below: 1 of 1 | cut: 0 (at most 30 sent, self-set) - in this order:\n- not qualified 1: name: \"Carl Aberg\" | reason: \"no obligation stated - however senior the title, an attendee, the general attendee flow, unchanged\"\n must: [name \"Carl Aberg\" exactly; reason uses the word \"obligation\"]\nIdentification breadth menu (step 3), re-ranked - pick: \"Obligation + relationship list\"\n- rung 1: \"Obligation + relationship list\" | moved: promoted by Q3 and Q7: the relationship recurs and Rafael Montoya's visit is itself a deliverable to it\n- rung 2: \"Obligation-only list\"\n- rung 3: \"No defined list\"\n- rung 4: \"Broad notability list\"\n- notes: Value and effort run in the same order: zero dominance relations, clean by construction, not a pass. Promotion for the broad list: essentially none at a technical conference - ask which obligation each extra name carries.\nRoster (step 3): breadth: \"Obligation + relationship list\" | holder: \"Marta Kowal\" | viewers: [\"Sam Ortiz\"; \"Dee Rahman\"] | delete by: \"2027-06-30\" | fields - 6: [\"Name\"; \"Obligation type\"; \"Stated requirements\"; \"What was refused\"; \"Named organizer\"; \"Visibility answer\"]\n roster must: [breadth \"Obligation + relationship list\" exactly; fields copies the 6 fields above, in this order; holder \"Marta Kowal\" exactly; viewers copies the 2 names above, in this order; delete_by \"2027-06-30\" exactly]\nProgram posture menu (step 4), re-ranked - pick: \"Formal named program with dedicated staff\"\n- rung 1: \"Formal named program with dedicated staff\" | moved: made the pick by Q4 and Q7: a guest arrives with their own detail or advance team and it recurs - you are the standing counterpart to somebody else's standing process\n- rung 2: \"Defined criteria + protocol runbook\" | moved: promoted by Q9: a team member with protocol experience can write the runbook (the page's own reading of the asset)\n- rung 3: \"Ad hoc invisible accommodation\"\n- rung 4: \"No posture\"\n- notes: Value and effort run in the same order: zero dominance relations, clean by construction, not a pass. Compliance cost: the runbook triggers a data-handling review ad hoc skips; ad hoc spends the reversibility the runbook keeps.\nProgram: pick: \"Formal named program with dedicated staff\" | moved by: \"Q4 and Q7\"\n program must: [pick \"Formal named program with dedicated staff\" exactly; reason uses the word \"Q4 and Q7\"]\nVisibility and discretion menu (step 5), re-ranked at the vendor/corporate-run pole - pick: \"Staff-only signal\"\n- rung 1: \"Staff-only signal\"\n- rung 2: \"Public marker + recognition moment\" | moved: promoted by Q2 and Q5: Anouk Verhoeven asked to be introduced, in as many words, at a vendor-run event; demoted by Q5: Rafael Montoya asked to move through the day unremarked\n- rung 3: \"Visible marker\" | moved: demoted by Q5: Rafael Montoya asked to move through the day unremarked; demoted by Q5: no guest asked for it in as many words - a marker nobody chose is a tier\n- rung 4: \"Invisible handling\"\n- notes: Dominance check, vendor pole - clean by construction: value and effort run in the same order, so the line rests on its own argument.\nVisibility (step 5) - per qualified guest, only what each said: 2 | rows below: 2 of 2 | cut: 0 (at most 30 sent, self-set) - in this order:\n- visibility 1: name: \"Anouk Verhoeven\" | posture: \"Public marker + recognition moment\" | said: \"introduced\" | moved by: \"Q2 and Q5\"\n must: [name \"Anouk Verhoeven\" exactly; posture \"Public marker + recognition moment\" exactly; said \"introduced\" exactly]\n- visibility 2: name: \"Rafael Montoya\" | posture: \"Staff-only signal\" | said: \"unremarked\" | moved by: \"Q5\"\n must: [name \"Rafael Montoya\" exactly; posture \"Staff-only signal\" exactly; said \"unremarked\" exactly]\nEscort depth menu (step 6), re-ranked - pick: \"Escort + protocol/security liaison\"\n- rung 1: \"Escort + protocol/security liaison\" | moved: made the pick by Q4: Anouk Verhoeven arrives with their own detail, protocol officer or advance team - you are the counterpart to somebody else's plan; seniority never promotes this rung\n- rung 2: \"Named greeter for arrival only\" | moved: promoted by Q9: a venue with a second entrance - one greeter at that door meets the arrival (the page's own reading of the asset)\n- rung 3: \"Printed contact card\"\n- rung 4: \"Dedicated escort for the visit\"\n- notes: Value and effort run in the same order: zero dominance relations, clean by construction, not a pass. Only the liaison rung carries a review, and it belongs to the guest's own institution.\nEscort: pick: \"Escort + protocol/security liaison\" | moved by: \"Q4\"\n escort must: [pick \"Escort + protocol/security liaison\" exactly; reason uses the word \"Q4\"]\nGreeter brief items (step 6): [who you are meeting - their name, and a photograph only if their office supplied one; when and where, with a fallback if they are late and a phone number that will be answered; the route: door, cloakroom, coffee, the room, the toilets and the exit they will leave by; what they asked for, quoted, and what was refused, quoted; the visibility instruction in one line, in plain words; your handoff: the person you hand them to, and what you do if that person is not there]\nWhat not to say: [never introduce the guest to anyone who has not been told they are coming; never say VIP, to the guest or anyone else, including on the radio; never explain the arrangements to a curious attendee; never volunteer a departure time to anyone]\nDeclining a photograph: [to an attendee: Not right now, sorry - we are on a tight schedule; to a photographer or someone filming: No photos of this group, please]\nDiscretion mechanics for the postures in use - 2:\n- \"Public marker + recognition moment\": the office asked for it in as many words; nothing about their movements is published that their security posture forbids; the run of show absorbs it - event-run-of-show's call\n- \"Staff-only signal\": the door lead gets a name and an arrival window, nothing else; the room leads get the name and one instruction - no announcement, no reserved seat, route any question to the named organizer; the code-of-conduct responders get the name\nLiaison intake (step 7) - guests with their own detail, protocol officer or advance team: 1 | rows below: 1 of 1 | cut: 0 (at most 30 sent, self-set) - in this order:\n- liaison 1: name: \"Anouk Verhoeven\" | arrives with: [a protective detail; a protocol officer]\n must: [name \"Anouk Verhoeven\" exactly; items use the words \"counterpart\", \"verbatim\", \"substitute\", \"route\", \"code of conduct\" and \"team\"]\nLiaison intake items: [name one counterpart on your side, with a number answered from the day before until the guest leaves; ask what they need and write it down verbatim; answer each item in writing - yes, no or a substitute - before the day; walk the route with them if they ask; state that the code of conduct applies to them, in the same message; tell your own team what changes and nothing more]\nDay-of decisions (step 8) - 2 - in this order:\n- decision 1: decision: \"photograph request\" | who: \"Dee Rahman\"\n must: [decision uses the word \"photograph\"; who \"Dee Rahman\" exactly]\n- decision 2: decision: \"say no on the guest's behalf\" | who: \"Marta Kowal\"\n must: [decision uses the word \"no\"; who \"Marta Kowal\" exactly]\nHand-offs (step 9) - 5 - in this order:\n- handoff 1: \"Seating against the grid\" | to: [event-schedule-design; event-run-of-show]\n must: [contains \"event-schedule-design\" and \"event-run-of-show\"]\n- handoff 2: \"Anything touching the general check-in desk\" | to: [event-attendee-experience]\n must: [contains \"event-attendee-experience\"]\n- handoff 3: \"The access needs of Anouk Verhoeven - an access question first, a guest question second\" | to: [event-accessibility-inclusion]\n must: [contains \"event-accessibility-inclusion\"]\n- handoff 4: \"Anything that becomes a crowd, medical or credible-threat question\" | to: [event-risk-management]\n must: [contains \"event-risk-management\"]\n- handoff 5: \"The scope clause that binds a guest's own detail like any third party\" | to: [event-code-of-conduct]\n must: [contains \"event-code-of-conduct\"]\nPosture must: [summary at most 40 words; verdict \"ready to brief the greeters\" exactly; routed copies the 4 rows above, in this order; qualified copies the 2 rows above, in this order; not_qualified copies the 1 row above, in this order; visibility copies the 2 rows above, in this order; decisions copies the 2 rows above, in this order; handoffs copies the 5 rows above, in this order; caveats carry the fix findings first, at most 5]\nBrief must: [title contains \"Port Avery Cloud Summit 2027\"; who_arrives copies the 2 rows above, in this order, with name and said exactly; how_to_greet uses the word \"liaison\"; what_not_to_say uses the words \"introduce\", \"VIP\", \"explain\" and \"departure\"; photos contains \"Dee Rahman\" and the word \"photo\"; escalation contains \"Marta Kowal\"; liaison_intake copies the 1 row above, in this order; day_of copies the 2 rows above, in this order] | brief note must: [use the word \"brief\" and say what happens next]\nCarried from the posture: summary: \"Ready to brief the greeters: two guests qualify on an obligation, the deputy minister's detail has one counterpart, the roster is deleted on 2027-06-30 and both day-of decisions carry a name.\" | parts matching the page: 5 of 5\nFindings (13):\n[check] public_1 (visibility): \"Anouk Verhoeven\": a recognition moment, three checks before it goes in the run of show - their office asked for it in as many words; nothing about their movements is published that their security posture forbids (confirm it with the detail); the run of show absorbs it without pushing a talk, which is event-run-of-show's call.\n[check] print_soon (time): Q6: the badge print run closes on 2027-05-27, within the self-set 3 days - ask any guest whose visibility is not said before then, or the marker rungs go with it.\n[info] routed_speaker (route): Routed out to samber/dev-event-organizer-skills@event-speaker-experience: \"Priya Raman\" - on the program - every speaker belongs to speaker experience, however senior. Not yours.\n[info] routed_sponsor (route): Routed out to samber/dev-event-organizer-skills@event-sponsor-fulfillment: \"Tomasz Wilk\" and \"Hana Ito\" - covered by a signed sponsorship - sponsor fulfillment delivers every promised perk. Not yours.\n[info] routed_press (route): Routed out to samber/dev-event-organizer-skills@event-press-relations: \"Jonas Feld\" - here to file copy - press relations claims accreditation, embargoes and on-site press handling. Not yours.\n[info] press_exposure (route): Press relations owns accreditation, embargoes and the press room. Yours is only a guest's own exposure to press - declining a photograph on their behalf, keeping a departure time off the schedule.\n[info] not_qualified (qualify): Not in scope, on the test: \"Carl Aberg\" (no obligation stated - however senior the title, an attendee; the general attendee flow, unchanged). A senior person who arrives alone, unescorted, with no stated requirement is an attendee with an impressive job - route to samber/dev-event-organizer-skills@event-attendee-experience and do nothing.\n[info] roster_rules (roster): The roster never records a judgment about a person - no notable, no important, no seniority note; every field is a fact the guest's office supplied or a decision you can defend. The door lead needs the name and the arrival window, never the requirements or the reason.\n[info] liaison_rule (liaison): The intake receives a plan: it is not a negotiation about status, and not the moment to promote every other menu - a guest with a protective detail still gets the visibility posture their office asked for. Make contact before the run of show goes public.\n[info] consent_photo (day): Consent to a photograph is never implied by attendance, and it is not the organizer's to give. Where an image the guest's posture forbids was already taken, the ask goes to the person who took it, in private, immediately.\n[info] notes (context): The pasted notes are context: a request in the notes is answered in writing - yes, no or a substitute - never a silent commitment.\n[info] departure (context): Never volunteer a departure time to anyone, and keep it off the published schedule.\n[info] scope (scope): The page never infers anyone's importance, identity, gender, nationality or visibility from a name or a title: every obligation, requirement and visibility answer here was stated by the guest, their office or you."
}
Reply:
{
"task": "brief",
"greeter_brief": {
"title": "Port Avery Cloud Summit 2027 - greeter brief",
"who_arrives": [
{
"name": "Anouk Verhoeven",
"arrival": "By the north entrance on 2027-06-14, on the route the protective officer walks on 2027-06-13 - the exact time is not given; confirm it with the protocol officer.",
"said": "introduced"
},
{
"name": "Rafael Montoya",
"arrival": "Not given - confirm the arrival time and the door with the foundation's office.",
"said": "unremarked"
}
],
"how_to_greet": "Meet each guest at the door they arrive by. For Anouk Verhoeven, follow the liaison plan agreed with their own detail and protocol officer: Marta Kowal is the one counterpart, and the detail leads the route. Visibility, in plain words: Anouk Verhoeven: introduced as the office asked - nothing about the departure is published; Rafael Montoya: no announcement, no reserved seat - an attendee like any other.",
"what_not_to_say": [
"Never introduce the guest to anyone who has not been told they are coming.",
"Never say VIP, to the guest or anyone else, including on the radio.",
"Never explain the arrangements to a curious attendee.",
"Never volunteer a departure time to anyone."
],
"photos": "Dee Rahman decides on the spot when a photograph is requested. To an attendee: Not right now, sorry - we are on a tight schedule. To a photographer or someone filming: No photos of this group, please. Consent is never implied by attendance.",
"escalation": "If anything goes wrong, or the person you hand the guest to is not there, call Marta Kowal before doing anything else."
},
"liaison_intake": [
{
"name": "Anouk Verhoeven",
"items": [
"Name one counterpart on your side - Marta Kowal, with a number answered from the day before until the guest leaves.",
"Ask what they need and write it down verbatim.",
"Answer each item in writing - yes, no or a substitute - before the day.",
"Walk the route with them if they ask.",
"State that the code of conduct applies to them, in the same message.",
"Tell your own team what changes and nothing more."
]
}
],
"day_of": [
{
"decision": "photograph request",
"who": "Dee Rahman"
},
{
"decision": "say no on the guest's behalf",
"who": "Marta Kowal"
}
],
"note": "Brief the greeters now: hand each greeter this page before doors, and walk the route with the protective officer on 2027-06-13."
}
The page's check: kept - nothing to flag
The free greeter brief skeleton for the resolved sample
# Port Avery Cloud Summit 2027 - greeter brief (the page's skeleton)
_Verdict: ready to brief the greeters._
## Who you are meeting
- Anouk Verhoeven - said: introduced - Public marker + recognition moment - arrives with a protective detail and a protocol officer
- Rafael Montoya - said: unremarked - Staff-only signal
## When and where
- [ ] The arrival time and the door, with a fallback if they are late and a phone number that will be answered
## The route
- [ ] Door, cloakroom, coffee, the room, the toilets and the exit they will leave by - walk it once before doors
## What they asked for, and what was refused
- Anouk Verhoeven: arrives with a protective detail; arrives with a protocol officer; asked to be introduced - refused: [ ] to fill in
- Rafael Montoya: asked to move through the day unremarked; the event depends on this relationship, and it recurs - refused: [ ] to fill in
## The visibility instruction
- Anouk Verhoeven: Public marker + recognition moment - the office asked for it in as many words; nothing about their movements is published that their security posture forbids; the run of show absorbs it - event-run-of-show's call
- Rafael Montoya: Staff-only signal - the door lead gets a name and an arrival window, nothing else; the room leads get the name and one instruction - no announcement, no reserved seat, route any question to the named organizer; the code-of-conduct responders get the name
## What not to say
- Never introduce the guest to anyone who has not been told they are coming.
- Never say VIP, to the guest or anyone else, including on the radio.
- Never explain the arrangements to a curious attendee.
- Never volunteer a departure time to anyone.
## Photographs
- Decided on the spot by: Dee Rahman
- Says no on the guest's behalf: Marta Kowal
- To an attendee: Not right now, sorry - we are on a tight schedule
- To a photographer or someone filming: No photos of this group, please
## Your handoff
- Hand the guest to: Marta Kowal - and if that person is not there, call them before doing anything else
## Liaison intake - Anouk Verhoeven
- Counterpart: Marta Kowal
- [ ] Name one counterpart on your side, with a number answered from the day before until the guest leaves
- [ ] Ask what they need and write it down verbatim
- [ ] Answer each item in writing - yes, no or a substitute - before the day
- [ ] Walk the route with them if they ask
- [ ] State that the code of conduct applies to them, in the same message
- [ ] Tell your own team what changes and nothing more
Made with Guest Protocol - https://guest-protocol.skillsafe.ai/
Build the input yourself
Load the engine in node (global.window = global; require("./guestkit.js"); require("./guestreply.js")), then:
const K = GuestKit, R = GuestReply;
const f = K.form({ name: "My Conf 2027", q1: "guest", pole: "community", register: "flat", q7: "recurring", start: "2027-09-14",
guests: "Ana Ruiz | Grant officer, Halden Trust | the grant renews each edition | no | no | no | none | not said | yes |",
q8Owner: "Joss Mercer", q9Compiler: "Joss Mercer", q9Viewers: "nobody else", q9Delete: "2027-09-30", photo: "Joss Mercer", sayNo: "Joss Mercer" });
// f.routed, f.qualified, f.notQualified, f.roster, f.menuA..D, f.vis, f.escort, f.liaison, f.decisions, f.handoffs, f.verdict, f.findings
K.rosterCsv(f); K.routingCsv(f); K.greeterMd(f); K.board(f) // the free exports
const b = K.buildInput(f, "posture"); // or "brief"
const wire = K.toWire(b.input); // POST this to /estimate and /run
// then: const reply = R.normalize(R.parseReply(job.output.output), "posture");
// R.check(reply, b) // {status: kept or flagged, notes}
// R.carryText(reply) // the lines the brief 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://guest-protocol.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://guest-protocol.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"]
// guest-protocol.mjs -- Node 18+ (global fetch)
const BASE = "https://api.skillsafe.ai/v1/app-api";
let TOKEN = "YOUR_TOKEN"; // from https://guest-protocol.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://guest-protocol.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
}
// GuestProtocol.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 GuestProtocol {
static final String BASE = "https://api.skillsafe.ai/v1/app-api";
static String token = "YOUR_TOKEN"; // from https://guest-protocol.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://guest-protocol.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://guest-protocol.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://guest-protocol.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":"guest-protocol"}' | 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": "guest-protocol"})["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: "guest-protocol" })).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": "guest-protocol"}, 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", "guest-protocol"), 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: "guest-protocol" })["token"])
// a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
$TOKEN = "";
$TOKEN = api("POST", "/guest", ["slug" => "guest-protocol"])["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 = "guest-protocol" }))!["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": "posture", "event": "Event: ... | dates: ... | days to doors: ...", "guests": "Named guests - 7 ...", "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": "posture", "event": "Event: ... | dates: ... | days to doors: ...", "guests": "Named guests - 7 ...", "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: "posture" or "brief", event, guests, 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 guest-protocol:<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 posture carries summary, verdict, routed, qualified, not_qualified, roster, program, visibility, escort, decisions, handoffs and caveats; a brief carries greeter_brief, liaison_intake, day_of and note. The code below prints the headline of either.
KEY="guest-protocol:posture:$(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 // .greeter_brief.title' reply.json
jq -r '.routed[]? | "\(.name) -> \(.to)"' reply.json # a posture; a brief has .greeter_brief.who_arrives
import hashlib, time
key = "guest-protocol:" + 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("routed") or (reply.get("greeter_brief") or {}).get("who_arrives") or []:
print("-", row["name"], row.get("to") or row.get("said"))
import { createHash } from "node:crypto";
const key = `guest-protocol:${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.routed || (reply.greeter_brief || {}).who_arrives || []) console.log("-", row.name, row.to ?? row.said);
sum := sha256.Sum256(raw) // add "crypto/sha256", "encoding/hex", "time" to the imports
key := "guest-protocol:" + 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["routed"].([]any) // a posture's route-out; a brief has greeter_brief.who_arrives
for _, row := range rows {
fmt.Println("-", row.(map[string]any)["name"], row.(map[string]any)["to"])
}
var digest = java.security.MessageDigest.getInstance("SHA-256").digest(M.writeValueAsBytes(input));
String key = "guest-protocol:" + 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("routed")) System.out.println("- " + row.path("name").asText() + " " + row.path("to").asText());
require "digest"
key = "guest-protocol:#{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["routed"] || []).each { |row| puts "- #{row["name"]} #{row["to"]}" }
$key = "guest-protocol:" . $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["routed"] ?? [] as $row) echo "- ", $row["name"], " ", $row["to"], "\n";
var digest = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(input.ToJsonString()));
var key = $"guest-protocol:{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["routed"] as JsonArray ?? new JsonArray()) Console.WriteLine("- " + row!["name"] + " " + row["to"]);
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: guest-protocol:posture:$(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": "posture", "event": "Event: ... | dates: ... | days to doors: ...", "guests": "Named guests - 7 ...", "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": "guest-protocol:posture:" + 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": `guest-protocol:posture:${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", "guest-protocol:posture:"+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", "guest-protocol:posture:" + 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" => "guest-protocol:posture:#{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: guest-protocol:posture:" . 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", $"guest-protocol:posture:{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);