-
Notifications
You must be signed in to change notification settings - Fork 7
Register the CallSession ontology #1106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "e815ba40-ef85-4a2b-b6cf-e05a86d4afbd", | ||
| "title": "CallSession", | ||
| "description": "One audio/video call in a chat, transport-agnostic (full-mesh WebRTC or an SFU). Generalises the ad-hoc 'call' Message so a call and its recording are readable across applications: who was in it, when, how long, and where the recording and transcript live. The canonical envelope is written ONCE, on the vault that already holds the chat's canonical Chat envelope (the group's own vault for a group, the chat owner's vault for a 1:1) — never on the caller's vault, which changes from call to call. Every other participant holds a reference-mixin (isReference + canonicalOwnerEName + canonicalEnvelopeId) on their own vault, never a copy. The body carries references and metadata only: media and transcript are w3ds:// file URIs, never bytes.", | ||
| "type": "object", | ||
| "properties": { | ||
| "id": { | ||
| "type": "string", | ||
| "description": "Stable call id, shared by every participant's record of the same call" | ||
| }, | ||
| "chatId": { | ||
| "type": "string", | ||
| "description": "The conversation this call belongs to" | ||
| }, | ||
| "transport": { | ||
| "type": "string", | ||
| "enum": ["mesh", "livekit"], | ||
| "description": "How the media was carried: peer-to-peer full mesh, or an SFU" | ||
| }, | ||
| "callType": { | ||
| "type": "string", | ||
| "enum": ["audio", "video"], | ||
| "description": "Whether the call carried video" | ||
| }, | ||
| "initiator": { | ||
| "type": "string", | ||
| "description": "eName of whoever started the call" | ||
| }, | ||
| "participants": { | ||
| "type": "array", | ||
| "items": { "type": "string" }, | ||
| "description": "eNames of everyone in the call, including the initiator" | ||
| }, | ||
| "roomName": { | ||
| "type": "string", | ||
| "description": "SFU room name, when the transport used one" | ||
| }, | ||
| "startedAt": { | ||
| "type": "string", | ||
| "format": "date-time", | ||
| "description": "When the call began" | ||
| }, | ||
| "endedAt": { | ||
| "type": "string", | ||
| "format": "date-time", | ||
| "description": "When the call ended; absent while it is still running" | ||
| }, | ||
| "durationSec": { | ||
| "type": "number", | ||
| "description": "Talk time in seconds; absent when unknown" | ||
| }, | ||
| "status": { | ||
| "type": "string", | ||
| "enum": ["active", "ended", "missed", "declined"], | ||
| "description": "Outcome of the call" | ||
| }, | ||
| "recording": { | ||
| "type": "object", | ||
| "description": "Present only when the call was recorded. References only — no media bytes and no transcript text.", | ||
| "properties": { | ||
| "mode": { | ||
| "type": "string", | ||
| "enum": ["egress", "client"], | ||
| "description": "Recorded server-side by the SFU, or by a participant's client" | ||
| }, | ||
| "mediaUri": { | ||
| "type": "string", | ||
| "description": "w3ds:// file URI of the composite recording" | ||
| }, | ||
| "mediaSegments": { | ||
| "type": "array", | ||
| "items": { "type": "string" }, | ||
| "description": "w3ds:// file URIs, when the composite was split into parts" | ||
|
Comment on lines
+67
to
+74
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Validate These fields accept any string, including an HTTP URL or non-URI value. This conflicts with the cross-application file-reference contract. Add a shared Draft-07 Also applies to: 85-88, 94-96 🤖 Prompt for AI Agents |
||
| }, | ||
| "mediaIsVideo": { | ||
| "type": "boolean", | ||
| "description": "Whether the composite carries video as well as audio" | ||
| }, | ||
| "tracks": { | ||
| "type": "array", | ||
| "description": "Per-speaker media, one entry per participant captured", | ||
| "items": { | ||
| "type": "object", | ||
| "properties": { | ||
| "eName": { "type": "string" }, | ||
| "uri": { "type": "string" }, | ||
| "mime": { "type": "string" } | ||
| }, | ||
| "required": ["eName", "uri"], | ||
| "additionalProperties": false | ||
| } | ||
| }, | ||
| "transcriptUri": { | ||
| "type": "string", | ||
| "description": "w3ds:// file URI of the transcript" | ||
| }, | ||
| "transcriptStatus": { | ||
| "type": "string", | ||
| "enum": ["pending", "done", "error", "skipped", "none"] | ||
| }, | ||
| "analysisStatus": { | ||
| "type": "string", | ||
| "enum": ["pending", "done", "error", "skipped", "none"] | ||
| }, | ||
| "recordedBy": { | ||
| "type": "string", | ||
| "description": "eName of whoever started the recording" | ||
| }, | ||
| "recordingVault": { | ||
| "type": "string", | ||
| "description": "eName of the vault the media and transcript files live on" | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| }, | ||
| "isReference": { | ||
| "type": "boolean", | ||
| "description": "True on a participant's pointer to a canonical CallSession held elsewhere" | ||
| }, | ||
| "canonicalOwnerEName": { | ||
| "type": "string", | ||
| "description": "On a reference: the vault holding the canonical envelope" | ||
| }, | ||
| "canonicalEnvelopeId": { | ||
| "type": "string", | ||
| "description": "On a reference: the canonical envelope's id on that vault" | ||
|
Comment on lines
+117
to
+127
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== locate file =="
git ls-files | grep -F 'services/ontology/schemas/callSession.json' || true
echo "== file outline/size =="
wc -l services/ontology/schemas/callSession.json
echo "== relevant schema sections =="
sed -n '1,220p' services/ontology/schemas/callSession.json | cat -n
echo "== search related definitions/usages =="
rg -n "isReference|canonicalOwnerEName|canonicalEnvelopeId"| head -n 200Repository: MetaState-Prototype-Project/prototype Length of output: 8080 🌐 Web query:
💡 Result: In JSON Schema 2020-12, the if, then, and else keywords provide conditional validation, functioning similarly to an if-then-else programming construct [1][2][3]. Interaction with Boolean Schemas and Defaults When the then or else keywords are missing, they are effectively treated as the boolean true schema, which always passes validation [1][3]. Specifically: - If the if subschema validates successfully and then is missing, the validation succeeds as if the then subschema were true [1][3]. - If the if subschema fails to validate and else is missing, the validation succeeds as if the else subschema were true [1][3]. - If the if keyword is entirely absent, then and else are ignored [2][4]. Interaction with the Required Keyword The required keyword behaves consistently within the conditional structure [3]. When then or else is applied, the required constraint is evaluated just like any other validation keyword [2][4]. Common patterns for conditional requirements include: - If a condition is met (if subschema passes), use then to mandate specific fields using required [5][6]. - If a condition is not met (if subschema fails), use else to mandate different fields [6]. Key Behavioral Rules - The evaluation result of the if subschema determines which branch (then or else) is evaluated [2][3]. The result of the if subschema itself does not directly dictate the overall validation outcome; rather, the success of the chosen branch (then or else) determines the success of the conditional block [1][2][4]. - Only the applicable branch (then or else) is evaluated for validation; the other is completely ignored [2][4]. - Annotations from the if subschema are collected regardless of the outcomes of the then or else branches [1][2]. - These keywords do not interact across subschema boundaries (e.g., within branches of an allOf) [2][4]. Citations:
Require complete canonical reference mixins. The schema only requires 🤖 Prompt for AI Agents |
||
| }, | ||
| "sharedBy": { | ||
| "type": "string", | ||
| "description": "On a reference: who wrote the pointer" | ||
| }, | ||
| "sharedAt": { | ||
| "type": "string", | ||
| "format": "date-time", | ||
| "description": "On a reference: when the pointer was written" | ||
| }, | ||
| "createdAt": { | ||
| "type": "string", | ||
| "format": "date-time", | ||
| "description": "When this envelope was created" | ||
| }, | ||
| "updatedAt": { | ||
| "type": "string", | ||
| "format": "date-time", | ||
| "description": "Body version: bumped whenever the body changes, so readers know a cached copy is stale" | ||
| }, | ||
| "isArchived": { | ||
| "type": "boolean", | ||
| "description": "Whether the record is archived" | ||
| } | ||
| }, | ||
| "required": ["id"], | ||
| "additionalProperties": false | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Reject negative durations.
durationSecaccepts negative values. A call duration cannot be negative.Add
"minimum": 0to this property.🤖 Prompt for AI Agents