-
Notifications
You must be signed in to change notification settings - Fork 7
Register seven Meshenger-authored ontologies (Relation, AvailabilityStatus, ChatPreference, DraftMessage, Summary, PreferredHandlers, FileContext) #1103
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,19 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "47478875-c0cf-4b62-97b3-5b0b62d7f491", | ||
| "title": "AvailabilityStatus", | ||
| "type": "object", | ||
| "description": "A person's self-declared availability ('do not disturb', busy, away), append-only on their OWN vault with a public ACL so any platform can honour it before notifying or calling them. The newest envelope by `since` is the current state; earlier ones are history. `until` makes a state self-expiring; a reader treats an expired state as 'available'. Never written by anyone but the owner.", | ||
| "properties": { | ||
| "statusId": { "type": "string", "description": "Body id of this status entry" }, | ||
| "ownerEName": { "type": "string", "description": "@-prefixed eName of the person the status belongs to" }, | ||
| "state": { "type": "string", "enum": ["available", "dnd", "busy", "away"] }, | ||
| "since": { "type": "string", "format": "date-time", "description": "When this state began; newest `since` wins" }, | ||
| "updatedAt": { "type": "string", "format": "date-time" }, | ||
| "until": { "type": "string", "format": "date-time", "description": "Optional self-expiry; past it the person is available again" }, | ||
| "note": { "type": "string", "description": "Optional human note shown next to the state" }, | ||
| "autoReply": { "type": "string", "description": "Optional text a platform may send back when someone @-mentions the owner while unavailable" } | ||
| }, | ||
| "required": ["statusId", "ownerEName", "state", "since"], | ||
| "additionalProperties": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "eb69c8ad-fec0-4b74-8727-3acd17f34f1b", | ||
| "title": "ChatPreference", | ||
| "type": "object", | ||
| "description": "One person's per-chat viewing preferences — mute, archive, pin — stored on THEIR OWN vault (ACL = self), NOT on the chat: whether I muted a conversation is my data, not the group's, and it must follow me across devices and across W3DS messengers. Keyed by `chatId` (the CANONICAL chat id); at most one envelope per (owner, chatId). Absent fields mean 'no preference', not 'off'.", | ||
| "properties": { | ||
| "id": { "type": "string", "description": "Body id" }, | ||
| "chatId": { "type": "string", "description": "Canonical Chat metaEnvelope id the preference applies to" }, | ||
| "updatedAt": { "type": "string", "format": "date-time" }, | ||
| "muted": { "type": "boolean", "description": "Suppress notifications from this chat (an @-mention may still pierce)" }, | ||
| "archived": { "type": "boolean", "description": "Hide from the main list; never deletes anything" }, | ||
| "pinned": { "type": "boolean", "description": "Float the chat to the top of the owner's list" }, | ||
| "pinnedAt": { "type": "string", "format": "date-time", "description": "When pinned — orders multiple pinned chats" } | ||
| }, | ||
| "required": ["id", "chatId", "updatedAt"], | ||
| "additionalProperties": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "55606983-2744-4d77-9200-b609029a4b3d", | ||
| "title": "DraftMessage", | ||
| "type": "object", | ||
| "description": "An unsent composer draft, on the AUTHOR's own vault (ACL = self), so a message started on one device can be finished on another. At most one draft per (owner, chatId); an empty `text` means the draft is cleared. Reply/edit context is REPLACED wholesale on every write, never merged — otherwise stale context outlives the draft that carried it. A consumer must never let a synced draft overwrite text the person is typing right now: an empty local composer adopts the draft, a non-empty one wins.", | ||
| "properties": { | ||
| "id": { "type": "string", "description": "Body id" }, | ||
| "chatId": { "type": "string", "description": "Canonical Chat id the draft belongs to" }, | ||
| "authorEName": { "type": "string", "description": "@-prefixed owner of the draft" }, | ||
| "text": { "type": "string", "description": "The draft text; empty = cleared" }, | ||
| "updatedAt": { "type": "string", "format": "date-time", "description": "Newest wins across devices" }, | ||
| "deviceId": { "type": "string", "description": "Which device last wrote it — lets a device skip echoes of its own writes" }, | ||
| "replyToId": { "type": "string", "description": "Message being replied to, if the draft is a reply" }, | ||
| "editingId": { "type": "string", "description": "Message being edited, if the draft is an edit" } | ||
| }, | ||
| "required": ["id", "chatId", "authorEName", "text", "updatedAt"], | ||
| "additionalProperties": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "b65218b4-62fb-44ea-b2f6-ffb34d83a629", | ||
| "title": "FileContext", | ||
| "type": "object", | ||
| "description": "An m:n join between a File and a context it appears in (a chat message, a task, a post): `fileRef` and `contextRef` are w3ds envelope URIs. Exists because the same File can be referenced by many contexts and a context can carry many files, while neither side should embed the other. Written by the platform that placed the file into the context; public ACL so any platform can answer 'where has this file been used'.", | ||
| "properties": { | ||
| "fileRef": { "type": "string", "description": "w3ds://file?id=@vault/<fileId> — the File being placed" }, | ||
| "contextRef": { "type": "string", "description": "w3ds://envelope?id=@vault/<envelopeId> — where it was placed" }, | ||
| "kind": { "type": "string", "description": "The context's nature: 'message', 'task', 'post', …" } | ||
| }, | ||
| "required": ["fileRef", "contextRef", "kind"], | ||
| "additionalProperties": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "9a1b2c3d-4e5f-4a60-8b1c-1122334455ff", | ||
| "title": "PreferredHandlers", | ||
| "type": "object", | ||
| "description": "One person's choice of which platform opens which ontology — the W3DS analogue of OS default apps, on their OWN vault (ACL = self). Keyed by ontology schemaId: `handlers[<schemaId>] = {openUrl, platform?}` where `openUrl` is a template another platform may navigate to when the person taps an envelope of that ontology. One envelope per owner; writes merge one key at a time.", | ||
| "properties": { | ||
| "id": { "type": "string", "description": "Body id" }, | ||
| "type": { "type": "string", "const": "preferred-handlers" }, | ||
| "handlers": { | ||
| "type": "object", | ||
| "description": "schemaId → {openUrl, platform?}", | ||
| "additionalProperties": { | ||
| "type": "object", | ||
| "properties": { | ||
| "openUrl": { "type": "string", "description": "URL template that opens this ontology in the chosen platform" }, | ||
| "platform": { "type": "string", "description": "Human label of the chosen platform (informational)" } | ||
| }, | ||
| "required": ["openUrl"] | ||
| } | ||
| }, | ||
| "updatedAt": { "type": "string", "format": "date-time" } | ||
| }, | ||
| "required": ["id", "type", "handlers", "updatedAt"], | ||
| "additionalProperties": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "f9ff8527-f3af-4733-b8df-fa0c97ba03ff", | ||
| "title": "Relation", | ||
| "type": "object", | ||
| "description": "A reified triple: `subject —predicate→ object`, authored by a person and stored on THEIR vault. One ontology for every lightweight edge between envelopes — a reaction (predicate 'react', value '👍'), a pin (predicate 'pin', value 'me'|'all'), a mention notification, a response to an activity (predicate 'respond') — instead of one bespoke ontology per edge kind. `object` is a w3ds envelope URI so the edge survives relocation. Distinct from the registered `Reference` ontology (c20e9437-…), which is a review/score OF a target; a Relation is a statement BETWEEN two envelopes. A cross-vault copy uses the reference mixin (isReference + canonicalOwnerEName + canonicalRelationId): the source-of-truth edge stays on the author's vault.", | ||
| "properties": { | ||
| "id": { "type": "string", "description": "Body id (mirrors the metaEnvelope id on the canonical)" }, | ||
| "subject": { "type": "string", "description": "Who/what the statement is about — an eName or a w3ds envelope URI" }, | ||
| "predicate": { "type": "string", "description": "The edge kind: 'react', 'pin', 'respond', 'mention', …" }, | ||
| "object": { "type": "string", "description": "Target envelope, as `w3ds://envelope?id=@vault/<metaEnvelopeId>`" }, | ||
| "value": { "type": "string", "description": "Predicate-specific payload: the emoji for 'react', 'me'|'all' for 'pin'" }, | ||
| "authorId": { "type": "string", "description": "@-prefixed eName of whoever asserted the relation" }, | ||
| "createdAt": { "type": "string", "format": "date-time" }, | ||
| "isReference": { "type": "boolean", "description": "True on a cross-vault copy pointing at the canonical" }, | ||
| "canonicalOwnerEName": { "type": "string", "description": "Reference mixin: whose vault holds the canonical" }, | ||
| "canonicalRelationId": { "type": "string", "description": "Reference mixin: metaEnvelope id of the canonical" }, | ||
| "sharedBy": { "type": "string", "description": "Reference mixin: who fanned the copy out" }, | ||
| "sharedAt": { "type": "string", "format": "date-time" } | ||
| }, | ||
| "required": ["id", "predicate", "authorId"], | ||
| "additionalProperties": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "schemaId": "5b1a2c3d-6e7f-4a80-9b1c-2d3e4f5a6b7c", | ||
| "title": "Summary", | ||
| "type": "object", | ||
| "description": "A generated summary of a bounded subject — a call, or a day of conversation — stored ONCE on the subject's vault (the chat/group vault for a call, the group vault for a day digest) rather than recomputed per reader. `subject` names what is summarised; `actionItems`/`events` are structured extractions any platform may render or turn into Tasks/CalendarEvents. Cross-vault copies use the reference mixin (isReference + canonicalOwnerEName + canonicalSummaryId) — the canonical is never duplicated.", | ||
| "properties": { | ||
| "id": { "type": "string", "description": "Body id" }, | ||
| "type": { "type": "string", "const": "summary" }, | ||
| "subject": { | ||
| "type": "object", | ||
| "description": "What is summarised: {kind: 'call'|'day', chatId?, callId?, dayKey?, ref?} — `ref` is a w3ds envelope URI of the source", | ||
| "properties": { | ||
| "kind": { "type": "string" }, | ||
| "chatId": { "type": "string" }, | ||
| "callId": { "type": "string" }, | ||
| "dayKey": { "type": "string", "description": "YYYY-MM-DD for a day digest" }, | ||
| "ref": { "type": "string" } | ||
| } | ||
| }, | ||
| "summaryLine": { "type": "string", "description": "One-line headline" }, | ||
| "summary": { "type": "string", "description": "The full summary text" }, | ||
| "actionItems": { "type": "array", "items": { "type": "object" }, "description": "Structured to-dos extracted from the subject" }, | ||
| "events": { "type": "array", "items": { "type": "object" }, "description": "Structured calendar-shaped extractions" }, | ||
| "startedAt": { "type": "string", "format": "date-time", "description": "When the summarised call actually started" }, | ||
| "endedAt": { "type": "string", "format": "date-time" }, | ||
| "durationSeconds": { "type": "number" }, | ||
| "generatedBy": { "type": "string", "description": "@-prefixed eName on whose behalf the summary was generated" }, | ||
| "generatedAt": { "type": "string", "format": "date-time" }, | ||
| "isReference": { "type": "boolean" }, | ||
| "canonicalOwnerEName": { "type": "string" }, | ||
| "canonicalSummaryId": { "type": "string" }, | ||
| "sharedBy": { "type": "string" }, | ||
| "sharedAt": { "type": "string", "format": "date-time" } | ||
|
Comment on lines
+30
to
+34
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 Require a canonical locator for references. An object with 🤖 Prompt for AI Agents |
||
| }, | ||
| "required": ["id", "type", "subject"], | ||
| "additionalProperties": true | ||
| } | ||
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.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Require and constrain
subject.kind.subject: {}and{"kind":"other"}both validate. The documented contract permits onlycallorday. Consumers cannot reliably select the summary subject type.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents