ak.schema.signal_presence.v1
ak.schema.signal_presence.v1 · file: schemas/signal-presence.schema.json Closed decrypted Signal plaintext payload profile for ak.presence, carried only inside ak.schema.signal_envelope.v1 with signal_class=session. Presence is never a durable Event; the exact kind, actor, state and activity time MUST stay inside the ciphertext. Realm scope and sender identity come from the enclosing signed envelope and are not duplicated here; receivers MUST require actor_id == envelope sender_actor_id. See zh/discovery/profiles-presence.md section 3.3 and zh/sync/signal.md section 1.1.
* $ · object
Closed decrypted Signal plaintext payload profile for ak.presence, carried only inside ak.schema.signal_envelope.v1 with signal_class=session. Presence is never a durable Event; the exact kind, actor, state and activity time MUST stay inside the ciphertext. Realm scope and sender identity come from the enclosing signed envelope and are not duplicated here; receivers MUST require actor_id == envelope sender_actor_id. See zh/discovery/profiles-presence.md section 3.3 and zh/sync/signal.md section 1.1.
* kind ·
const "ak.presence"enum:
"ak.presence"* payload_sequence ·
integerStrictly increasing but non-contiguous u64 within (sender_actor_id, sender_device_id, canonical scope_ref), including the complete ActorId. Multi-device presence accepts arbitrary forward gaps and only considers signals that advance the Actor/device/scope high-water.
* actor_id · oneOf[2] · $ref ./common-ids.schema.json#/$defs/actor_id
Complete protocol identity for an Event author or Realm member: account carries the exact AccountId for every Station-hosted principal; service identifies a service acting as itself. The discriminator is validated against accepted registration and admission evidence; it never authorizes itself. Account and service are distinct, and no comparison may fall back to a bare principal_id. Agent and integration classification, provisioning, controller binding and credential authorization are independently verified facts, not identity variants. Account actors at different Stations MUST NOT share or inherit authority merely because their principal_id, DID controller or signing key matches, including membership, capability, RealmCommit-signing and recovery authority.
oneOf · oneOf[0] · object
* kind ·
const "account"enum:
"account"* account_id ·
$ref #/$defs/account_id · $ref #/$defs/account_idoneOf · oneOf[1] · object
* kind ·
const "service"enum:
"service"* service_id ·
$ref #/$defs/did_core_id · $ref #/$defs/did_core_id* state ·
string (enum)Closed v1 presence state set. Unknown values MUST be dropped or rejected as schema_violation; receivers MUST NOT map them onto an approximate state. Invisibility is not a state value: it is expressed by ak.presence.visibility=nobody.
enum:
"online" "idle" "offline" "dnd"status_message ·
stringOptional NFC status text, at most 256 Unicode code points. U+0009 and U+000A are the only permitted control characters; all other C0/C1 controls are rejected. NFC normalization is enforced after decryption by the receiver.
pattern:
^[^\u0000-\u0008\u000B-\u001F\u007F-\u009F]*$last_active_at · oneOf[2]
Optional and omitted by default. Either an RFC 3339 UTC instant or a Unix-epoch-aligned ISO 8601 <start>/<end> interval bucket. The bucket duration MUST be at least PT60S and MUST match the Realm policy granularity; that bound and the epoch alignment cannot be expressed in JSON Schema and are enforced by the receiver, which MUST fail closed on malformed values.
oneOf · oneOf[0] ·
string (date-time) · format=date-time · $ref ./time.schema.json#/$defs/timestampCanonical Arkret-owned absolute instant. UTC Z form with exactly three millisecond digits. Whole seconds MUST use .000Z; offsets, missing/finer fractions, lowercase separators, leap seconds, and invalid Gregorian calendar dates are forbidden. Shape validation by this pattern is supplemented by semantic date validation.
pattern:
^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z$oneOf · oneOf[1] ·
stringpattern:
^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z$* ttl_ms ·
integerPlaintext presence lifetime. It MUST NOT widen the outer Signal TTL, whose session-class ceiling is 30 seconds (zh/sync/signal.md section 2); receivers treat the effective lifetime as the minimum of this value and the envelope expires_at.
Source
- registry row:
spec/v1/artifacts/registry/schema-registry.json - schema document:
spec/v1/artifacts/schemas/signal-presence.schema.json