ActorApprovalAnswer actor.approval-answer@1
Generated at from
openvibe-contracts v0.419.0 and
openvibe-sdk v0.161.0.
- Version
- 1.0.0
- Owner
- actor
- Visibility
- public
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/actor/approval-answer.v1.json
actor.approval-answer@1: the person's answer to a device approval (plan HO12, the phone as the agent's eyes and hands). The agent asked for the phone's camera or its location, the person did the thing themselves after reading why, and this document carries the result back to the step as untrusted input, never as an instruction. DECISION is "answer"; declining an approval stays the ordinary denial and is not this document. Exactly one of PHOTO and LOCATION is present. PHOTO is a private Media object the person took in the system camera (JPEG, PNG or WebP, at most 10 MB, EXIF stripped by Actor): a picture of the world, not a secret, a token or a URL. LOCATION is shared once, after the person allowed it: LAT is -90 to 90, LNG -180 to 180 and ACCURACY_M is 0 to 100000 metres. PRECISE is true only when the step asked for precise and the person allowed it; when it is false the share is coarse and LAT and LNG carry at most two decimals (about a kilometre). JSON Schema cannot count decimal places, so the two-decimal rule lives in the description, is enforced by Actor and is checked by this repository's suite.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
decision | const | yes | The only decision this document carries: the person answered the ask. A decline is the approval's ordinary denial, not a data-carrying answer. |
|
photo | object | The photo the person took in the system camera after reading why. It is stored as a private Media object in Actor's tenant, and the step reaches it through a short-lived signed URL; this document carries only the object's id. |
| |
photo.media_id | string | yes | The private Media object holding the photo (media.object@1's id: med_<ULID>). |
|
location | object | The place the person shared once. When PRECISE is false, LAT and LNG carry at most two decimals (about a kilometre); JSON Schema cannot count decimal places, so Actor enforces the rounding and the repository's suite holds it. A precise location is shared only when the step asked for it and the person allowed it. |
| |
location.lat | number | yes | Latitude in degrees, -90 to 90. |
|
location.lng | number | yes | Longitude in degrees, -180 to 180. |
|
location.accuracy_m | number | yes | The device's accuracy radius in metres, 0 to 100000. |
|
location.precise | boolean | yes | True only when the step asked for a precise location and the person allowed it; false for a one-time coarse share (LAT and LNG at most two decimals). |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: location-coarse
{
"decision": "answer",
"location": {
"lat": 52.31,
"lng": 4.76,
"accuracy_m": 1200,
"precise": false
}
}Valid: location-precise
{
"decision": "answer",
"location": {
"lat": 52.367612,
"lng": 4.904123,
"accuracy_m": 8,
"precise": true
}
}Valid: photo
{
"decision": "answer",
"photo": {
"media_id": "med_01JAB2C3D4E5F6G7H8J9K0MNPQ"
}
}Rejected: coarse-four-decimals
{
"decision": "answer",
"location": {
"lat": 52.3676,
"lng": 4.9041,
"accuracy_m": 1200,
"precise": false
}
}Rejected: extra-field
{
"decision": "answer",
"photo": {
"media_id": "med_01JAB2C3D4E5F6G7H8J9K0MNPQ"
},
"note": "an extra field is never part of an answer"
}Rejected: lat-91
{
"decision": "answer",
"location": {
"lat": 91,
"lng": 4.76,
"accuracy_m": 8,
"precise": true
}
}Rejected: photo-and-location
{
"decision": "answer",
"photo": {
"media_id": "med_01JAB2C3D4E5F6G7H8J9K0MNPQ"
},
"location": {
"lat": 52.31,
"lng": 4.76,
"accuracy_m": 1200,
"precise": false
}
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('actor.approval-answer@1', value); // { valid, errors: [{ path, message }] }