# agree_promise_meaning

Turn one proposal into a promise, because its named owner read it and agreed to it. The promise enters agreed-but-unprotected: it is context, not protection, until a verifier qualifies. Protection then starts on its own, with Balladeer recorded as the actor and the qualification receipt as the cause, so do not offer to turn it on for anybody. When the person you are talking to is the proposal's named owner and this is their own connection, they can agree here: show them the proposal in full from get_proposal, ask plainly whether they agree its meaning, and on a clear yes call this with shownDigest and their quoted words; no code and no browser. Then, because building the check is your work and needs no further sign-off, prepare_qualification and build the verifier unless they said not to. Obtain explicit sign-off for THIS act in THIS conversation before calling this. Never call it on your own initiative, and never on a person's general approval of some earlier act. Quote the person's own words in signOff.quotedWords, not your summary of them. When a result includes forThePerson, tell the person what it says in your own words, in about one line.

Reviewed 2026-10-01. Read the [current operating instructions](https://app.balladeer.ai/agent) and the [tool index](/docs/mcp-reference.md). This reference does not authorize the action.

## Parameters

```json
{
  "type": "object",
  "properties": {
    "signOff": {
      "type": "object",
      "properties": {
        "who": {
          "description": "The person who signed this off: their membership ID from get_promise_setup, or the email address they signed in with. It must be the named owner of the thing being acted on; anybody else is refused.",
          "type": "string",
          "minLength": 1,
          "maxLength": 320
        },
        "quotedWords": {
          "description": "What the person actually said, in their words. Not your paraphrase, not a restatement of the act, and never words you supplied for them to agree to.",
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        "at": {
          "description": "When they said it, in this conversation.",
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
        }
      },
      "required": [
        "who",
        "quotedWords",
        "at"
      ],
      "additionalProperties": false
    },
    "grantCode": {
      "description": "The one-time code the person was shown after they signed off on the sign-off page. Ask them for it; you cannot produce one, and a wrong or missing code is refused with the link to hand them rather than something to retry.",
      "type": "string",
      "minLength": 8,
      "maxLength": 200
    },
    "shownDigest": {
      "description": "Agreeing from the conversation, with no code: the `proposalDigest` from the get_proposal answer you showed the person, verbatim. Only the person this connection belongs to can agree this way, and only when they are the proposal's named owner; put their exact words in signOff.quotedWords and their membership id or email in signOff.who. The server refuses if the proposal changed since you showed it. Anyone else, or any other act, needs the sign-off page and its code.",
      "type": "string",
      "pattern": "^(?:sha256:)?[a-f0-9]{64}$"
    },
    "proposalId": {
      "description": "The proposal whose meaning the owner agreed to.",
      "type": "string",
      "pattern": "^cand_[a-z0-9]{8,64}$"
    },
    "candidateId": {
      "description": "Deprecated alias for `proposalId`, still accepted so a caller written against the older tool keeps working. Send `proposalId`; sending both names at once is refused.",
      "type": "string",
      "pattern": "^cand_[a-z0-9]{8,64}$"
    }
  },
  "required": [
    "signOff"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false
}
```

## Effect annotations

```json
{
  "readOnlyHint": false,
  "destructiveHint": false,
  "idempotentHint": false,
  "openWorldHint": false
}
```
