@ours.network/cowork 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,7 @@ In the web console, choose Create room, enter Name, Goal, and Briefing, and subm
12
12
 
13
13
  Update the display name with `ours-cowork room settings <room-id> --name "New name"`; other mutable mission fields use the same `room settings` command. A new room identity is `ours-cowork:<bounded creation name>`: NFC normalization followed by the first 52 Unicode code points, for a 64-code-point maximum including the prefix. That authenticated name is persisted and frozen. Messenger displays the retained human-readable prefix from the identity itself; longer local `room_name` metadata remains available in Cowork. Renaming a room changes only mutable local metadata; it does not change the identity name, CID, contacts, invites, URLs, history, or earlier author labels. Because identity names are daemon-global, the same normalized name—or distinct long names sharing the retained prefix—collides and fails cleanly without a losing room sentinel. Earlier unreleased ID- and slug-based formats are unsupported and receive no migration. Inspect admitted seats with `room participants`. A room activates only when its recorded invite requirement is satisfied.
14
14
 
15
- Runtime membership commands are default-deny. Per-CID grants use `command-grant` and `command-revoke`. An operator may instead register a durable role policy with `role-command-set <room-id> --role <label> --commands <comma-list>` and inspect it with `role-command-grants`; use `--commands none` to remove it. A role policy authorizes only an authenticated, active seat whose durable admission role exactly matches the policy. Display names, message labels, pending seats, removed seats, and caller-supplied role text never confer authority. Removing a role policy does not remove an independently configured per-CID grant.
15
+ Runtime commands are default-deny. Per-CID grants use `command-grant` and `command-revoke`. An operator may instead register a durable role policy with `role-command-set <room-id> --role <label> --commands <comma-list>` and inspect it with `role-command-grants`; use `--commands none` to remove it. A role policy authorizes only an authenticated, active seat whose durable admission role exactly matches the policy. Display names, message labels, pending seats, removed seats, and caller-supplied role text never confer authority. Removing a role policy does not remove an independently configured per-CID grant.
16
16
 
17
17
  Membership changes are deliberately independent operator actions. Add a participant by issuing an invite for the intended role and admitting that identity; remove a participant with `ours-cowork room remove <room-id> <participant>`. To preserve coverage, add and confirm the new participant before removing the old one. To remove a dead participant first, remove it and issue a new invite afterward. Cowork does not combine these actions into a replacement operation or infer successor lineage.
18
18
 
@@ -25,3 +25,15 @@ If the shared daemon restarts or a room SDK lease is lost, Cowork automatically
25
25
  Use `ours-cowork room rebind <room-id>` for explicit recovery. This canonical operation applies the same name-and-CID proof, refreshes SDK contact/invite state, reconciles the room, and resumes durable pending fanout before reporting success. It refuses closing or closed rooms. Structured daemon logs emit `identity_rebind_*` and `startup_room_recovery_failed` events for diagnosis.
26
26
 
27
27
  Every web action has an equivalent CLI fallback in the room commands above and in the invites and messaging topics.
28
+
29
+ ## Shared ours command calls
30
+
31
+ Room-scoped operations also appear in the room identity's ours catalog with their RPC names: `room.settings`, `room.briefing.role.set`, `room.briefing.role.delete`, `room.invite`, `room.participant.remove`, `room.revoke`, `room.recover`, `room.recover.confirm`, `room.show`, `room.participants`, `room.command.grants`, `room.command.role.grants`, `room.command.role.set`, `room.command.grant`, `room.command.revoke`, `room.history`, `room.message`, `room.say`, `room.role.rest.add`, `room.role.rest.remove`, `room.accept`, `room.rebind`, `room.close`, and `room.delete`.
32
+
33
+ Use the RPC arguments without `room_id`; the receiving room fixes the target. For example, an operator grants `ours-cowork room command-grant <room-id> <caller-cid> room.settings`, then that active member calls `room.settings` with `{"status":"review"}` using ours command transport. A grant for one name grants none of the other names. The SDK returns a correlated result containing `{ok:true,result:<service value>}` or `{ok:false,error:<code>}`. History returns one page; follow `seq` with `after` to fetch more.
34
+
35
+ `list-members` retains its contact-safe roster. `remove-member` retains its epoch, confirm and no-self-removal gates. The separate `room.participant.remove` command instead grants the full operator removal behavior. `room.show`, `room.participants` and operator-view history return operator metadata. Policy-administration commands can delegate more privileges; `room.message` and `room.say` authorize room/role authorship. Assign these permissions deliberately. Command results may include invite material; do not relay them into chat.
36
+
37
+ Host lifecycle and global room creation/listing are excluded. `room.accept` accepts invitation input through its separate grant and remains unavailable through REST. Ours close/delete return a durable accepted receipt before closing the reply channel; verify completion through management. Close retains archive/files; delete requires `confirm:true`, closes first, and erases local room data. Pending lifecycle requests resume after restart; failed requests remain visible in room metadata for explicit management retry. Missing replies do not prove a mutation failed. Dynamic consumer registration is not implemented.
38
+
39
+ The SDK owns command reply delivery and its size limits. Large history pages or a single large file record may exceed that transport's capacity; use CLI/REST for those results. No additional result-omission contract is introduced.
@@ -50,9 +50,9 @@ name, slug, or room ID.
50
50
 
51
51
  Incoming message listings contain authorization metadata but no body. Cowork resolves each selected wire ID through persistent SDK history, verifies that the history row matches the listing, archives the message and complete recipient-intent fan-out, and then asks the SDK to read one oldest unread row. If an older introduction becomes unread between listing and acknowledgement, that authoritative row is archived through the same intake path before cowork retries the expected row. There is no defer operation; an empty acknowledgement means another reader already advanced the expected row.
52
52
 
53
- For a file, cowork reads the identity-scoped immutable blob while the item is still unread and verifies its length and SHA-256 against SDK metadata. It then durably archives the exact bytes as canonical base64 together with the reply reference and every per-recipient relay intent before selecting that exact 64-hex wire ID with `getFiles`. Each other active seat receives two SDK items: an authenticated `room_file` metadata envelope and a binary file containing the original bytes. The SDK receives bytes, never a local filesystem path, so there is no staging-file or path-permission dependency. A seat removed after fan-out is skipped terminally without receiving metadata or bytes. A crash can redrive an unfinished recipient from the cowork archive; an already terminal recipient is not retried.
53
+ For a file, cowork reads the identity-scoped immutable blob while the item is still unread and verifies its length and SHA-256 against SDK metadata. It then durably archives the exact bytes as canonical base64 together with the reply reference and every per-recipient relay intent before selecting that exact 64-hex wire ID with `getFiles`. Each other active seat receives two SDK items: a standard `room_msg` envelope authored by the room with the text `<Participant> sent a file`, followed by a binary file containing the original bytes. The notice text uses the stored participant display name, or the room-scoped alias in anonymous rooms. This replaces the previous `room_file` JSON notice; the full author and file metadata remain in Cowork’s archive. The file still identifies the room as its transport sender. These are separate deliveries, so sending the notice first does not guarantee adjacent display. The SDK receives bytes, never a local filesystem path, so there is no staging-file or path-permission dependency. A seat removed after fan-out is skipped terminally without receiving the notice or bytes. A crash can redrive an unfinished recipient from the cowork archive; an already terminal recipient is not retried.
54
54
 
55
- In an anonymous room, SDK-authenticated file metadata identifies the author only by participant ID and alias. The operator archive still retains the real author and exact file bytes. The participant-facing history projection currently contains messages only; file records remain visible in the complete operator Archive/CLI history, while recipients retrieve file bytes through their ordinary ours file inbox.
55
+ In an anonymous room, the notice text names only the room-scoped alias; it includes no participant ID or real participant identity. The envelope author is the room. The binary file’s authenticated sender remains the room. The operator archive still retains the real author and exact file bytes. The participant-facing history projection currently contains messages only; file records remain visible in the complete operator Archive/CLI history, while recipients retrieve file bytes through their ordinary ours file inbox.
56
56
 
57
57
  Cowork history records include messages, files, and the durable relay intent/result trail used for restart recovery. This application archive is distinct from the shared daemon's per-identity `history.sqlite3` and immutable blob store; neither is a substitute backup for the other.
58
58
 
@@ -10,7 +10,7 @@
10
10
  - The shared daemon's history database and cowork's room archive are separate durable stores with no cross-store transaction. Cowork orders archive and recipient-intent durability before advancing SDK unread state, but a crash can still leave an already-archived SDK row unread; source IDs make that replay idempotent.
11
11
  - Backups require a stopped cowork daemon. Back up and restore the complete cowork state directory as one unit, preserving ownership and modes; protect shared identity state separately through the shared daemon's operator procedure.
12
12
  - Service uninstall retains data. It removes the cowork systemd or launchd definition, not configuration, archives, room metadata, or identities in the shared daemon.
13
- - Closing and deleting are separate. First close the room explicitly with `ours-cowork room close <room-id>`. Only a closed room can then be deleted with `ours-cowork room delete <room-id> --yes`.
13
+ - Closing retains room metadata, archive and files. `ours-cowork room delete <room-id> --yes` closes the room if necessary, then erases all local room data. Ours close/delete replies acknowledge durable acceptance; management state determines completion.
14
14
  - Confirmed deletion removes the retained archive and metadata from this host only. It does not claim remote purge, backup erasure, key wipe, or secure erase.
15
15
  - The web console and HTTP room RPC have no authentication. They bind only to `127.0.0.1` and must not be forwarded, proxied, or exposed remotely.
16
16
  - Web updates use periodic polling rather than push. A view can lag daemon state until its next refresh; confirmed mutations trigger an immediate refresh.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/cowork",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Durable ours mission rooms on the shared ours daemon.",
5
5
  "type": "module",
6
6
  "license": "FSL-1.1-Apache-2.0",