|
| 1 | +# Jidoka Continuity Integration Boundary |
| 2 | + |
| 3 | +Status: implemented contract for issue |
| 4 | +[#83](https://github.com/agentjido/jido_messaging/issues/83). |
| 5 | + |
| 6 | +## Decision |
| 7 | + |
| 8 | +Jidoka is the first-party agent authoring and execution surface. Jidoka owns |
| 9 | +agent sessions, memory, snapshots, request state, resume work, and handoff |
| 10 | +state. Jido Messaging owns rooms, threads, participants, canonical messages, |
| 11 | +authorization scope, and the small correlation record that connects a thread |
| 12 | +to Jidoka. |
| 13 | + |
| 14 | +The dependency direction is one way: |
| 15 | + |
| 16 | +1. A Jidoka-owned integration writes and resolves Jido Messaging correlation |
| 17 | + records. |
| 18 | +2. The integration requests a scoped canonical transcript from Jido |
| 19 | + Messaging. |
| 20 | +3. The integration passes the opaque reference and messages to Jidoka public |
| 21 | + APIs. |
| 22 | + |
| 23 | +Jido Messaging does not call Jidoka. It has no Jidoka or `jido_harness` |
| 24 | +dependency. |
| 25 | + |
| 26 | +This boundary follows the first-party Jidoka guidance for |
| 27 | +[architecture boundaries](https://github.com/agentjido/jidoka/blob/main/guides/architecture-boundaries.md), |
| 28 | +[sessions and stores](https://github.com/agentjido/jidoka/blob/main/guides/sessions-and-stores.md), |
| 29 | +[snapshots and resume](https://github.com/agentjido/jidoka/blob/main/guides/snapshots-and-resume.md), |
| 30 | +[memory](https://github.com/agentjido/jidoka/blob/main/guides/memory.md), and |
| 31 | +[handoffs](https://github.com/agentjido/jidoka/blob/main/guides/handoffs.md). |
| 32 | + |
| 33 | +## Ownership |
| 34 | + |
| 35 | +| Concern | Owner | Jido Messaging record | |
| 36 | +| --- | --- | --- | |
| 37 | +| Room and thread | Jido Messaging | Canonical room and thread IDs | |
| 38 | +| Agent principal | Jido Messaging | Canonical agent participant ID | |
| 39 | +| Canonical transcript | Jido Messaging | Message records in one authorized thread | |
| 40 | +| Session and request history | Jidoka | Opaque session and request IDs only | |
| 41 | +| Memory and prompt assembly | Jidoka | None | |
| 42 | +| Snapshot data and resume | Jidoka | Opaque snapshot ID only | |
| 43 | +| Agent handoff state | Jidoka | Opaque transition reference only | |
| 44 | + |
| 45 | +## Contract |
| 46 | + |
| 47 | +`JidokaContinuityRef` contains: |
| 48 | + |
| 49 | +- one integration ID; |
| 50 | +- a fixed `%{system: :jidoka, id: ...}` agent reference; |
| 51 | +- one Jidoka session ID; |
| 52 | +- optional request, turn, snapshot, and expiry references. |
| 53 | + |
| 54 | +`ThreadContinuityLink` adds the messaging room, thread, and agent principal. |
| 55 | +It also adds a sequential source revision, source time, availability status, |
| 56 | +safe reason code, and optional transition reference. The link ID is stable for |
| 57 | +the room and thread. |
| 58 | + |
| 59 | +Both constructors use an allow list. They reject extra fields. Session data, |
| 60 | +memory entries, prompts, serialized snapshots, provider clients, credentials, |
| 61 | +and arbitrary metadata are not valid input. |
| 62 | + |
| 63 | +## Write and replacement rules |
| 64 | + |
| 65 | +- The first source revision is `1`. |
| 66 | +- A byte-equivalent source revision is idempotent. |
| 67 | +- Each changed write increments the revision by one. |
| 68 | +- Conflicting, stale, and skipped revisions return different errors. |
| 69 | +- A principal, Jidoka agent, or session replacement needs a non-secret opaque |
| 70 | + `transition_ref`. |
| 71 | +- One live `{integration_id, session_id}` can belong to only one messaging |
| 72 | + thread in one messaging instance. |
| 73 | +- `:expired`, `:deleted`, and `:cleared` are terminal for the same session. |
| 74 | + A later active link must identify a replacement session or agent and include |
| 75 | + a transition reference. |
| 76 | +- Terminal links remove request, turn, and snapshot references. They keep the |
| 77 | + stable session reference as a durable correlation and deletion marker. |
| 78 | + |
| 79 | +The ETS and SQLite adapters enforce the same rules. SQLite persists the link |
| 80 | +across a messaging restart. Room or principal deletion removes its orphaned |
| 81 | +link. |
| 82 | + |
| 83 | +## Read and authorization rules |
| 84 | + |
| 85 | +Every link read and transcript request needs an instance-bound |
| 86 | +`HistoryScope`. The link room must be in the supplied room list. Jido |
| 87 | +Messaging checks that scope before it reads messages. A cursor from another |
| 88 | +room or thread cannot expand the result. |
| 89 | + |
| 90 | +`jidoka_continuity_context/3` returns a `JidokaContinuityContext` with the link |
| 91 | +and canonical messages for the linked thread. It does not return a prompt or |
| 92 | +memory projection. The caller must authorize the rooms before it builds the |
| 93 | +scope. Jido Messaging does not make this policy decision. |
| 94 | + |
| 95 | +The resolver also requires an active messaging thread and a live link: |
| 96 | + |
| 97 | +| Stored or effective state | Result | |
| 98 | +| --- | --- | |
| 99 | +| Missing link | `{:error, :not_found}` | |
| 100 | +| Active | Opaque `JidokaContinuityRef` | |
| 101 | +| Unavailable | `{:error, {:continuity_unavailable, reason}}` | |
| 102 | +| Expired | `{:error, {:continuity_expired, reason}}` | |
| 103 | +| Deleted | `{:error, {:continuity_deleted, reason}}` | |
| 104 | +| Cleared | `{:error, {:continuity_cleared, reason}}` | |
| 105 | +| Closed or archived messaging thread | `{:error, {:continuity_thread_not_active, status}}` | |
| 106 | + |
| 107 | +An `expires_at` value has read-time effect. A Jidoka-owned integration should |
| 108 | +also write an explicit terminal state when it confirms deletion or expiry. |
| 109 | + |
| 110 | +## Handoff and recovery |
| 111 | + |
| 112 | +The `transition_ref` is a correlation value, not a handoff record. Jidoka |
| 113 | +creates and interprets it. Jido Messaging only uses its presence to approve an |
| 114 | +identity replacement. It does not copy Jidoka ownership, private context, or |
| 115 | +handoff state. |
| 116 | + |
| 117 | +After a Jido Messaging restart, the integration can resolve the same session |
| 118 | +ID and request a scoped canonical transcript. Jidoka then decides whether to |
| 119 | +load, recover, fork, or reject its session. A missing Jidoka session must be |
| 120 | +reported back with `set_thread_continuity_status/4`; Jido Messaging does not |
| 121 | +attempt recovery. |
| 122 | + |
| 123 | +## Compatibility and follow-up work |
| 124 | + |
| 125 | +The core contract uses the existing agent participant and `HistoryScope` |
| 126 | +types, so it does not need a Jidoka package. Future Jidoka-owned integration |
| 127 | +work can align the opaque agent reference with the canonical principal and |
| 128 | +endpoint contracts from issues |
| 129 | +[#77](https://github.com/agentjido/jido_messaging/issues/77) and |
| 130 | +[#78](https://github.com/agentjido/jido_messaging/issues/78). Authorization |
| 131 | +grants and activity projections remain separate concerns. |
| 132 | + |
| 133 | +Applications must not put private Jidoka values in message, thread, or bridge |
| 134 | +metadata as a workaround. The strict continuity types are the only supported |
| 135 | +messaging-side continuity record. |
0 commit comments