Skip to content

dev.superpipeline.question.v2

An agent’s question in the decision envelope, beside the v1 card. Options say what they mean and may ask for input; a question with no options carries free_text. A strict decision or a board-dispatched harness permission carries its subject; a SuperToolkit approval request carries approval_request_id and belongs to no card, run or stage. Readers ignore properties they do not know. x-uniqueBy lists paths whose values must not repeat (JSON Schema cannot say so): a[].b is field b of each item of list a.

An m.room.message whose content carries suite_event_type: "dev.superpipeline.question.v2".

The carrier is whichever service carries the board’s chat: AgentPod’s hub, or SuperExchange for a board that has moved to it.

Field Type Required Description Constraints
msgtype "m.text" yes
body string yes
suite_event_type "dev.superpipeline.question.v2" yes
schema_version integer yes at least 1
elicitation_id string yes at least 1 character
board_id string yes
card_id string yes
run_id string yes
stage_key string yes
card_title string yes
asked_by string yes
question string yes
options array of object yes at most 20 items
options[].id string yes at least 1 character; at most 200 characters
options[].label string yes at most 200 characters
options[].meaning one of "approve", "reject", "revise", "choose", "defer" yes
options[].needs_comment boolean yes
options[].input object no
options[].input.kind one of "text", "url" yes
options[].input.label string yes at most 200 characters
options[].input.required boolean yes
options[].input.max_length integer yes at least 1; at most 4000
options[].scope one of "once", "run", "always" no
options[].requires one of "workspace-admin" no
free_text object no
free_text.max_length integer yes at least 1; at most 2000
subject object no The exact thing an approving answer approves, re-bounded by the carrier. The sender still lists approving options when preview_complete is false; a client must not offer them, and the carrier refuses an approving answer to an incomplete preview.
subject.id string yes at least 1 character; at most 512 characters
subject.digest string yes at least 1 character; at most 512 characters
subject.schema string yes at least 1 character; at most 200 characters
subject.revision integer yes at least 0
subject.expires_at string or null yes When the binding lapses: an RFC 3339 date-time with seconds and an explicit offset (2030-01-02T03:04:05Z, 2030-01-02T08:34:05.5+05:30), or null for none. The pattern states it for a validator that does not assert format. format date-time; pattern ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])T([01]\d|2[0-3]):[0-5]\d:[0-5]\d(\.\d+)?(Z|[+-]([01]\d|2[0-3]):[0-5]\d)$; at most 200 characters
subject.preview array of object (type = “text”) or object (type = “field”) or object (type = “link”) yes at most 20 items
subject.preview[].type "text" yes in the type = "text" shape
subject.preview[].label string no in the type = "text" shape; at most 200 characters
subject.preview[].text string yes in the type = "text" shape; at most 4000 characters
subject.preview[].type "field" yes in the type = "field" shape
subject.preview[].label string yes in the type = "field" shape; at most 200 characters
subject.preview[].value string yes in the type = "field" shape; at most 200 characters
subject.preview[].type "link" yes in the type = "link" shape
subject.preview[].label string yes in the type = "link" shape; at most 200 characters
subject.preview[].url string yes in the type = "link" shape; pattern ^https?://[^\s<>]+$; at most 4000 characters
subject.preview_complete boolean yes
approval_request_id string no at least 1 character
deadline object no
deadline.remind_at string no pattern ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?(Z|[+-]\d{2}:\d{2})$; at most 40 characters
deadline.escalate_at string no pattern ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?(Z|[+-]\d{2}:\d{2})$; at most 40 characters
deep_link string no

The schema also states these rules across fields, as written:

{
"allOf": [
{
"description": "free_text only on a question with no options: text alone answers only a question with nothing to choose. Without free_text, there is at least one option to answer with.",
"if": {
"required": [
"free_text"
]
},
"then": {
"properties": {
"options": {
"maxItems": 0
}
}
},
"else": {
"properties": {
"options": {
"minItems": 1
}
}
}
},
{
"description": "A SuperToolkit approval request belongs to no card: it names its request, links nowhere, is bound to an stk-capability/v1 subject, and only a workspace owner or admin may approve it.",
"if": {
"required": [
"card_id"
],
"properties": {
"card_id": {
"const": ""
}
}
},
"then": {
"required": [
"approval_request_id"
],
"not": {
"required": [
"deep_link"
]
},
"properties": {
"subject": {
"properties": {
"schema": {
"const": "stk-capability/v1"
}
}
},
"options": {
"items": {
"if": {
"required": [
"meaning"
],
"properties": {
"meaning": {
"const": "approve"
}
}
},
"then": {
"required": [
"requires"
],
"properties": {
"requires": {
"const": "workspace-admin"
}
}
}
}
}
}
}
}
]
}

x-uniqueBy: the values at these paths must not repeat, the one rule JSON Schema cannot state. a[].b is field b of each item of list a.

  • options[].id

From fixtures/matrix-events/examples.json, case “a question with options, one of which asks for text”:

{
"msgtype": "m.text",
"body": "An agent is waiting on you — \"Upgrade the build image\" at stage `build`.\n\nThe tests need network access. May I run them?\n\n1. Run the tests\n2. Skip them\n3. Something else\n\nReply with the number, or the option's name. [Open the card](https://superpipeline.dev/b/brd_7c1f/c/crd_51d0)",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "elc_7f3c",
"board_id": "brd_7c1f",
"card_id": "crd_51d0",
"run_id": "run_12",
"stage_key": "build",
"card_title": "Upgrade the build image",
"asked_by": "agt_31d0",
"question": "The tests need network access. May I run them?",
"options": [
{
"id": "run_them",
"label": "Run the tests",
"meaning": "choose",
"needs_comment": false
},
{
"id": "skip",
"label": "Skip them",
"meaning": "choose",
"needs_comment": false
},
{
"id": "other",
"label": "Something else",
"meaning": "choose",
"needs_comment": false,
"input": {
"kind": "text",
"label": "What should I do instead?",
"required": true,
"max_length": 500
}
}
],
"deep_link": "https://superpipeline.dev/b/brd_7c1f/c/crd_51d0"
}

The corpus has 8 valid cases in all:

a question with no options, answered by typing
{
"msgtype": "m.text",
"body": "An agent is waiting on you — \"Upgrade the build image\" at stage `build`.\n\nWhich branch should I base the fix on?\n\nAnswer this one on the board. [Open the card](https://superpipeline.dev/b/brd_7c1f/c/crd_51d0)",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "elc_8a21",
"board_id": "brd_7c1f",
"card_id": "crd_51d0",
"run_id": "run_12",
"stage_key": "build",
"card_title": "Upgrade the build image",
"asked_by": "agt_31d0",
"question": "Which branch should I base the fix on?",
"options": [],
"free_text": {
"max_length": 2000
},
"deep_link": "https://superpipeline.dev/b/brd_7c1f/c/crd_51d0"
}
subject-bound: a strict decision with a complete preview
{
"msgtype": "m.text",
"body": "An agent is waiting on you — \"Upgrade the build image\" at stage `build`.\n\nEdit app.js in the workspace?\n\n1. Approve\n2. Approve for this run\n3. Always allow\n4. Deny\n\nReply with the number, or the option's name. [Open the card](https://superpipeline.dev/b/brd_7c1f/c/crd_51d0)\n\nThis approves an exact operation. Approve it in an updated app, which shows what it does, or on the board. A reply here can only decline it.",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "elc_9b44",
"board_id": "brd_7c1f",
"card_id": "crd_51d0",
"run_id": "run_12",
"stage_key": "build",
"card_title": "Upgrade the build image",
"asked_by": "agt_31d0",
"question": "Edit app.js in the workspace?",
"options": [
{
"id": "approve",
"label": "Approve",
"meaning": "approve",
"needs_comment": false,
"scope": "once"
},
{
"id": "approve-run",
"label": "Approve for this run",
"meaning": "approve",
"needs_comment": false,
"scope": "run"
},
{
"id": "always",
"label": "Always allow",
"meaning": "approve",
"needs_comment": false,
"scope": "always",
"requires": "workspace-admin"
},
{
"id": "deny",
"label": "Deny",
"meaning": "reject",
"needs_comment": false,
"scope": "once"
}
],
"subject": {
"id": "8f9a0d0e-4b2a-4c1e-9c55-1a2b3c4d5e6f",
"digest": "0588c96c7eff47e1a83d9fc1d0ecda3cc3b72e559a5c402bb9da29d9851dbceb",
"schema": "salaam-operation/v1",
"revision": 1,
"expires_at": "2026-11-07T10:30:00.000Z",
"preview": [
{
"type": "text",
"text": "Edit app.js in the workspace"
},
{
"type": "field",
"label": "File",
"value": "app.js · edit · 16 bytes"
},
{
"type": "text",
"text": "console.log(1);\n"
}
],
"preview_complete": true
},
"deep_link": "https://superpipeline.dev/b/brd_7c1f/c/crd_51d0"
}
approval-request: an issues.create request with its preview complete
{
"msgtype": "m.text",
"body": "A SuperToolkit approval request is waiting on a workspace owner or admin.\n\nAllow github issues.create on acme/site?\n\nService: github\n\nCapability: issues.create\n\nTarget: acme/site\n\nArguments:\n```\n{\n \"title\": \"Flaky login test\",\n \"labels\": [\"ci\"]\n}\n```\n\nStation: station-7\n\nRequested by: prn_agent_31d0\n\n1. Allow once\n2. Deny\n\nOnly workspace owners and admins can allow this. Allow it in an updated app, which shows exactly what it does. A reply here can only deny it.",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "apr_5d2e9c41",
"board_id": "brd_7c1f",
"card_id": "",
"run_id": "",
"stage_key": "",
"card_title": "Approval request",
"asked_by": "prn_agent_31d0",
"question": "Allow github issues.create on acme/site?",
"options": [
{
"id": "allow_once",
"label": "Allow once",
"meaning": "approve",
"needs_comment": false,
"scope": "once",
"requires": "workspace-admin"
},
{
"id": "deny",
"label": "Deny",
"meaning": "reject",
"needs_comment": false,
"scope": "once"
}
],
"subject": {
"id": "stkreq_8f2c",
"digest": "sha256:4be1c0de9a7f30b2",
"schema": "stk-capability/v1",
"revision": 1,
"expires_at": "2026-11-08T10:30:00.000Z",
"preview": [
{
"type": "field",
"label": "Service",
"value": "github"
},
{
"type": "field",
"label": "Capability",
"value": "issues.create"
},
{
"type": "field",
"label": "Target",
"value": "acme/site"
},
{
"type": "text",
"label": "Arguments",
"text": "{\n \"title\": \"Flaky login test\",\n \"labels\": [\"ci\"]\n}"
},
{
"type": "field",
"label": "Station",
"value": "station-7"
},
{
"type": "field",
"label": "Requested by",
"value": "prn_agent_31d0"
}
],
"preview_complete": true
},
"approval_request_id": "apr_5d2e9c41"
}
deadline: a question that only escalates
{
"msgtype": "m.text",
"body": "An agent is waiting on you — \"Launch post\" at stage `draft`.\n\nWhich headline?\n\n1. Ship it today\n2. Ship it Monday\n\nReply with the number, or the option's name. [Open the card](https://superpipeline.dev/b/brd_7c1f/c/crd_6b40)",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "elc_5d21",
"board_id": "brd_7c1f",
"card_id": "crd_6b40",
"run_id": "run_e074a2160c4b4f28",
"stage_key": "draft",
"card_title": "Launch post",
"asked_by": "agt_31d0",
"question": "Which headline?",
"options": [
{
"id": "a",
"label": "Ship it today",
"meaning": "choose",
"needs_comment": false
},
{
"id": "b",
"label": "Ship it Monday",
"meaning": "choose",
"needs_comment": false
}
],
"deadline": {
"escalate_at": "2026-11-08T18:00:00.000Z"
},
"deep_link": "https://superpipeline.dev/b/brd_7c1f/c/crd_6b40"
}
built: a question with two options
{
"msgtype": "m.text",
"body": "An agent is waiting on you — \"Upgrade the build image\" at stage `build`.\n\nThe tests need network access. May I run them?\n\n1. Run the tests\n2. Skip them\n\nReply with the number, or the option's name. [Open the card](https://superpipeline.dev/b/brd_7c1f/c/crd_6b40)",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "elc_7f3c",
"board_id": "brd_7c1f",
"card_id": "crd_51d0",
"run_id": "run_12",
"stage_key": "build",
"card_title": "Upgrade the build image",
"asked_by": "agt_31d0",
"question": "The tests need network access. May I run them?",
"options": [
{
"id": "run_them",
"label": "Run the tests",
"meaning": "choose",
"needs_comment": false
},
{
"id": "skip",
"label": "Skip them",
"meaning": "choose",
"needs_comment": false
}
],
"deep_link": "https://superpipeline.dev/b/brd_7c1f/c/crd_6b40"
}
built: a question answered by typing
{
"msgtype": "m.text",
"body": "An agent is waiting on you — \"Upgrade the build image\" at stage `build`.\n\nThe tests need network access. May I run them?\n\nAnswer this one on the board. [Open the card](https://superpipeline.dev/b/brd_7c1f/c/crd_6b40)",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "elc_7f3c",
"board_id": "brd_7c1f",
"card_id": "crd_51d0",
"run_id": "run_12",
"stage_key": "build",
"card_title": "Upgrade the build image",
"asked_by": "agt_31d0",
"question": "The tests need network access. May I run them?",
"options": [],
"free_text": {
"max_length": 500
},
"deep_link": "https://superpipeline.dev/b/brd_7c1f/c/crd_6b40"
}
built: a SuperToolkit approval request
{
"msgtype": "m.text",
"body": "A SuperToolkit approval request is waiting on a workspace owner or admin.\n\nAllow github issues.create on acme/site?\n\nPost:\n```\nOur next release ships today.\n```\n\nAccount: @fixture_account on X\n\n1. Allow once\n2. Deny\n\nOnly workspace owners and admins can allow this. Allow it in an updated app, which shows exactly what it does. A reply here can only deny it.",
"suite_event_type": "dev.superpipeline.question.v2",
"schema_version": 1,
"elicitation_id": "apr_5d2e9c41",
"board_id": "brd_7c1f",
"card_id": "",
"run_id": "",
"stage_key": "",
"card_title": "Approval request",
"asked_by": "agt_31d0",
"question": "Allow github issues.create on acme/site?",
"options": [
{
"id": "allow_once",
"label": "Allow once",
"meaning": "approve",
"needs_comment": false,
"scope": "once",
"requires": "workspace-admin"
},
{
"id": "deny",
"label": "Deny",
"meaning": "reject",
"needs_comment": false,
"scope": "once"
}
],
"subject": {
"id": "stkreq_8f2c",
"digest": "sha256:9a1e",
"schema": "stk-capability/v1",
"revision": 1,
"expires_at": "2030-01-02T03:04:05Z",
"preview": [
{
"type": "text",
"label": "Post",
"text": "Our next release ships today."
},
{
"type": "field",
"label": "Account",
"value": "@fixture_account on X"
}
],
"preview_complete": true
},
"approval_request_id": "apr_5d2e9c41"
}

Each of these must fail. The corpus says why:

  • an option with no meaning. A sender must say what each option means. (refused by schema)
  • camelCase on the Matrix wire. maxLength is the board’s push field; the Matrix field is max_length. (refused by schema)
  • duplicate option ids. Answering is by id. (refused by unique)
  • free_text beside options. Text alone answers only a question with nothing to choose. (refused by schema)
  • no body. A stock client would show nothing. (refused by schema)
  • subject-bound: the subject in camelCase. The Matrix wire is snake_case. (refused by schema)
  • subject-bound: an option scope outside once | run | always (refused by schema)
  • subject-bound: a subject with no digest: nothing to bind an answer to (refused by schema)
  • approval-request: a deep link to a card that does not exist (refused by schema)
  • approval-request: no approval_request_id (refused by schema)
  • approval-request: allow_once without requires: workspace-admin (refused by schema)
  • approval-request: a subject of another schema (refused by schema)
  • a subject revision that is not a whole number (refused by schema)
  • an expiry that is a date only (refused by schema)
  • an expiry written as a person would (refused by schema)
  • an expiry with no offset (refused by schema)
  • an expiry with no seconds (refused by schema)
  • an expiry with a space for the T (refused by schema)
  • an expiry whose offset has no colon (refused by schema)
  • an expiry in lower case (refused by schema)
  • an expiry on a day the month does not have (refused by schema)
  • no options: nothing to answer with (refused by schema)