This is the filed review document, copied at 09:19 EDT. Its dated claims remain historical. See the current update before acting on an old sign-in request or delivery status. Reply in chat with decisions or feedback.
20 October 2026 · proposed implementation spec for WOB-75.
JR should let the team pick up work in a Slack thread without rebuilding the context every time. If Ben asks about a venue and Deja adds the missing detail, both turns belong to the same piece of work. If someone starts an unrelated sound question in the same channel, it gets its own work record. The application knows who spoke, which work they mean and who can see the answer before it gives a model any prior material.
Toberton's 20 October remit, recorded in WOB-75, authorizes writing this specification and its tickets. That record dates the old Slack watcher's retirement to 17 October. This document does not describe a running replacement. Deployment, new Slack grants, a team trial and production memory writes remain later steps. Both production memory switches stay off. The companion Slack source review supports Socket Mode and identifies the acknowledgment, thread-read and List-write conditions below. It is source evidence, not a running integration.
A teammate asks JR in an ordinary team thread. JR binds the request to a durable WobOS Work record, reads the sources that this requester and conversation are allowed to use, and replies with a useful answer or proposed action. A later contribution continues that Work, even after the local process restarts. The Work owns the status and receipts; the model conversation is one way of carrying out its next turn.
JR remains the JA role within Wob's system. Wob is Toberton's personal agent and owns the personal phone conversation. JR works in team channels and sends Toberton the agreed Slack DM digest. It can return a JA development to Wob without creating another personal phone voice.
The settled WOB-72 scope governs this design:
| Request or destination | Existing decision applied |
|---|---|
| Toberton or Ben requests JA finance | Both may read JA finance, including bank details, in an allowed audience. Private replies remain available to them. |
| Teammate Tobi requests event economics (read as Tobi A. by inference until the account mapping is verified; see below) | Event revenue, costs and payouts are allowed; bank details remain with Toberton and Ben. |
| A wider channel contains somebody outside that scope | The answer cannot contain the restricted information, even when Ben asked. |
| Another teammate privately messages JR | Redirect to a suitable group forum without importing the private message into it. |
| A teammate asks to update their own task | Requested progress, completion and an explicitly requested due-date change are allowed after fresh ownership verification. |
| A request affects somebody else's task | Prepare the exact change for review. |
| Personal Himmerton records (WOB-72's term) or a private passage in a mixed recording | Keep it outside the team answer and outside any model session used for that audience. |
“Tobi” is not an identity key. WOB-72 names a teammate Tobi. Reading that name as Tobi A., the recorded co-founder distinct from Toberton, is an inference, not a settled identity. Until installation binds and verifies Tobi A.'s immutable Slack account ID, the teammate-Tobi permissions attach to no account, and every row above that names Tobi A. is read the same way. Installation must bind verified Slack account IDs to those people. An unresolved account match holds that person's restricted operation; it does not reopen the permission interview.
| Piece | Decision | Reason and evidence |
|---|---|---|
| WobOS Work and its SDK adapters | Keep and extend narrowly. | Current Work already saves a task, turn ownership, continuation state and provider session ID. run_session starts or resumes an adapter and claims one owner. JR needs Slack actors and destinations attached to that same record, plus an ordered pending-input list. The list is new: the current claim refuses a second owner, and the record holds one pending_ask value. |
| Scope and correction checks around a return | Keep. | Current Work can hold a stale return and invalidate a provider session when its permission generation changes. JR also needs audience and source revision checks; the existing personal generation alone does not encode Slack membership. |
| Known Slack thread routing | Keep as a direct lookup. | A linked thread already identifies its Work. Calling a model to rediscover that link adds uncertainty without helping. |
| New-request routing | Change to one authorized JEV selection. | The accepted design selects among relevant active JA workstreams, plus new/none. Today's routing.select chooses a helper profile; it is not an implemented Slack workstream router. |
| Resumable model conversations | Keep, scoped to the Work's audience. | Current Claude and Codex adapters provide the execution seam. A conversation that has seen restricted content cannot simply be resumed for a broader audience. |
| Old JR watcher and resurrection launchd | Replace with the WobOS-owned runtime path. | They were retired. Restarting the old daemon would restore a second lifecycle and the earlier architecture. |
| Old fixed source pack and prompts | Keep useful examples, replace fixed coverage. | The preserved candidate demonstrated source-linked reviews, but a small named file list does not establish coverage of current JA work. Select actual current sources and report gaps. |
| Old Asana writes | Replace with existing Slack Lists items. | Slack Lists now own live team task state. Event records continue to own durable decisions and context. Do not create another task database. |
| Source-summary correction and return receipts | Keep the mechanism, rebind to Work. | The old document review retained the original ask and corrected its answer. A durable handoff should identify the source, its revision and the consuming Work. |
| Honcho JA memory | Keep the approved identity, separate activation. | The recorded peer is justanother beside toberton in workspace captain. It supplies relevant evidence and craft; it never determines task status or permission. |
| Existing shared tools | Keep their maintained entry points. | JR should use the same source and action interfaces as Wob. New Slack adaptation belongs at the channel boundary, not in duplicate Google, calendar or finance clients. |
| Feedback into Squeaky | Keep and make observable in the trial. | A real routing or correction failure needs a source-linked repair item and readback, rather than disappearing into a model transcript. |
The old candidates are prior art, not deployable foundations:
6795c87b2fec44770b2f57f92fa7c601b9136c78, has the source/permission work, adoption notes and source-summary comparison.cb25c758e6e51eb5fd3e12c4e8f9bd225fe4edaf, demonstrated a real runner reading a complete document and returning it to the original JR request. Slack and task writes in that proof were stand-ins. One earlier overbroad read failed with a Mercury access error; the later bounded document path succeeded. That is useful evidence for bounded source admission, not proof of today's Slack integration.Suppose Deja writes, “Can we use the venue's side room for check-in?” in an event thread that JR has already linked.
The same Work survives a restart. Its stored session ID helps resume reasoning, but the source references and action receipts are what make the continuation accountable.
Use Slack Socket Mode through its native Python SDK/Bolt pattern inside WobOS's existing service lifecycle. Its outbound connection fits the local Mac without an incoming public endpoint. A bot token performs Web API operations; a separate app-level token with connections:write opens the socket. The actual app-level credential, event subscriptions and interactivity settings still need inspection. This spec does not authorize a new scope, account, public endpoint or launchd service.
Persist each admitted event and its pending input on the existing Work record before any acknowledgment. The save runs in Bolt's global middleware, which precedes every acknowledgment path, for Events API envelopes and interactive payloads alike. The reviewed Bolt source acknowledges ordinary event listeners before their handler runs, so saving only inside that handler leaves a crash window. An interactive listener gets three seconds (ack_timeout, default 3) for its own acknowledgment, after which Bolt sends an empty one, so the save has to finish inside that budget too. The save is a short read-modify-write under the Work's existing lock, with no provider call and no wait for a running turn. The lock helper blocks until it is acquired and has no timeout, so the first checkpoint measures lock wait during a live turn before the design depends on it. Failure and retry then follow four cases:
Qualify this order against the exact SDK version adopted, rather than assuming the starter's default is durable.
Retain native event IDs for replay handling and message IDs for edits. A repeated event does not create another Work or repeat an outward effect. A first message creates its Work by an exclusive create, and that create refuses a path that already exists. The refusal has two meanings, and the middleware separates them. If the event ID is already in the Work's accepted list, the event is a replay: acknowledge it and add nothing. If the ID is not there, a different first event for the same thread won the create race while this one was being saved. Reload the record and append this event under the same lock, because it is new input and dropping it would lose it. Each input records its Slack actor in a per-input field. The record's author field is fixed to captain: plus the task ID and cannot carry a Slack speaker. A later edit is a revision of the original input, not an unrelated new request. A deletion removes that input from future admitted context while preserving the minimum application receipt needed to explain an earlier action.
Resume uses the Work's stored pending inputs and source references, not Slack thread history. conversations.replies may supply a backfill or a scoped source read for a thread the requester is allowed to see. Its token rule and rate tier are unverified and the checkpoint decides them, so no resume path depends on them.
A known (workspace, channel, thread) link resolves to its Work through a linked_threads list on the existing Work record, which holds every thread attached to that Work. An unknown thread is looked up by a bounded scan of the permitted open Work records in the same workspace and channel. The scan reads JSON files that already exist, and no new index or database is added. The choice receipt records how many records the scan read, and the first slice decides from that count whether an index is ever needed. A new request gets a minimal list of workstreams already allowed for that actor and audience. JEV chooses an existing Work, new work or no match. It receives permitted summaries only, never a private global work inventory. A clear exact reference may resolve without JEV. An ambiguous reference gets a stronger bounded check or one short question; it must not silently join two jobs.
The choice receipt records the candidate IDs, selected ID and reason. No numerical confidence threshold is invented here. Qualify that decision with the actual ambiguous JA examples in the scenario set.
Extend existing Work records with linked_threads, a per-input list of Slack actor IDs kept apart from author, request origin, destination, permitted source references, action owner and audience/source revision used for the current turn. Keep current task state on the owning Slack List or private record; Work records execution and follow-through.
The existing session claim keeps one owner per provider conversation, so two concurrent Slack inputs cannot run two owners against it. The ordered queue is new work, not an existing mechanism: today's claim refuses a second owner, and the record holds a single pending_ask value. JR adds a pending_inputs list whose entries are queued, in_turn or done, under the same Work lock. Claiming a turn takes the oldest queued input and marks it in_turn in the same locked write that sets the owner. The existing acceptance write, mark_turn_accepted, sets that input to done. If the owner's run disappears before that write, restart returns the in_turn input to queued before a new owner is claimed. This gives at-least-once delivery of the model turn: a crash between the provider accepting a turn and the acceptance write can run that turn twice, so outward effects rely on their action receipts, not on the model turn. Different Work records may progress independently. A new contribution does not silently impersonate the original requester or inherit their restricted authority.
On restart, reconcile the existing Work owner and pending input before resuming. An interrupted read may be retried. An outward action with an uncertain receipt must be reconciled through the native service; a missing success receipt is not evidence that no send occurred.
Treat requester identity, source access, allowed operation and answer audience as four separate fields. They are simple application checks against the existing decisions and current source/service state, not a new policy platform.
Before source injection and again before delivery, verify every recipient can receive the selected information. The check must include private-channel members, group-DM members and external/shared-channel participants as applicable. A channel name or a model's assurance is insufficient. The membership read and the send are separate calls, and Slack's send has no precondition tied to the read, so a member who joins between them can receive the message. JR does not claim atomicity here. A membership event that arrives later for that thread holds further sends there and rebuilds the context for the new audience before any reply. Content already delivered cannot be taken back in the sense that matters: a bot's own post can be deleted with chat.delete, but that does not remove what a member has already read.
If membership expands, identity changes or permission narrows, hold the pending return and any draft action. Preserve the canonical Work, clear reuse of the old provider session, and start a scoped conversation containing only evidence allowed for the new audience. Do not try to “forget” private provider history with a prompt. A narrowed audience also gets an explicit recheck; it does not automatically inherit earlier privileges.

For personal-line evidence, apply the later W03 approval: JR may discover and directly read task-relevant JA material within the already authorized accounts. Apple does not have to pre-tag a thread first. Relevance is still required, unrelated personal history remains outside the task, and permission to read a source does not make it suitable for a Slack reply.
Reuse WobOS's exact-content and revision receipts for prepared actions. The current personal action path can treat an owner-origin input as Toberton's instruction; a Slack adapter must supply an explicit verified actor and must never treat every teammate input as owner-origin.
For a permitted own-task change, read the existing List item, resolve the requester to its current owner, apply only the requested change, then read it back. Dates are changed only when requested; unknown dates stay blank. Reassignment, another person's task, a changed audience or a materially changed action goes to the already established review route with the exact proposed effect.
A stale button or reply cannot approve a newer draft. Bind any Slack interaction to the verified actor, destination, Work, action revision and actual proposed content. Do not add a generic approval system or change Wob's existing personal approval semantics.
Slack's reviewed List update method has no native “only if unchanged” precondition. Serialize JR's writes to a given item through existing Work ownership, re-read its owner and relevant values immediately before writing, stop on a detected change, and read back afterward. Another human can still edit between that read and write. The first implementation must demonstrate and disclose that remaining race; it must not describe its local revision check as an atomic service guarantee. Update only the requested cells and retain any conflicting readback for reconciliation. Slack modal updates have a native hash precondition, but that does not extend to List rows or message edits.
Use current JA records and fresh service evidence. A local export is a dated source snapshot. The event's README and registry locate its owning records; Slack Lists provide current team task state. A source gap is visible in the answer and the Work.
Reuse the existing JA meeting home and ja-meetings workflow: internal records under meetings/team/, partnership records in their existing homes, minutes/transcript filing through the established Drive arrangement. The later Wispr integration may supply new or updated source material, but transcript availability does not authorize sharing a private passage.
Keep a transcript's words, an uncertain speaker label and Toberton's personal debrief distinct. “Toberton reports that Ben questioned the date” is Toberton's account, not a direct Ben quote. A corrected transcript or changed meeting note revises dependent evidence and pending work; it must not create duplicate meeting records on every collection.
The JA seed proposal is a separate review surface. A team-safe batch and restricted candidates must remain distinguishable. A JSON audience label does not prove Honcho enforces that audience. JR's first useful Work path must function with production memory off. A later memory slice qualifies permitted retrieval and write boundaries before activation.
Honcho also writes to the peer without any JR action. The 3 October guidance records that dreaming, on by default, can delete facts it judges outdated, add derived conclusions and rewrite the peer card, and that the deriver adds conclusions from ordinary sessions unless reasoning is off for that session. Derived items are memory in their own right. Before activation, every JR read must filter by requester and audience whether an item was seeded or derived, and a test must show that a restricted-audience session writes no conclusion into the shared peer. Which derivation settings stay on for the justanother peer is an activation decision, made after the isolation check. This specification does not decide it, and its review did not read the peer's current settings.
JR can follow an accepted task through its next useful contribution, using existing Work continuations and the owning record. Requested progress and completion notices refer to the actual task, source change or due obligation. Do not invent new timer cadences or release the saved job holds in this spec.
Return JA developments to Wob through a source-linked Work handoff. Wob may combine authorized JA context with personal context for Toberton; JR does not receive that broader personal context in reverse by default. Retain the original request, source revisions, current outcome and any pending decision so the consumer can answer without a second investigation.
These are required later application demonstrations, not claims that the proposed implementation already works.
| Scenario | Expected visible behavior | Decisive evidence |
|---|---|---|
Two unrelated requests in #all-justanother |
Venue planning and sound preparation create separate Work records and continue independently. | Native thread links, different Work/session IDs, no cross-task source injection. |
| Ben starts a thread; Deja adds information | One Work continues with both actors correctly attributed. Deja does not inherit Ben's finance access. | Accepted input IDs, actor-bound source reads and the actual Slack reply. |
| A teammate refers to work started elsewhere | An authorized exact link resumes the right Work; an ambiguous “that venue thing” gets a bounded clarification. | Candidate-selection receipt with only permitted work summaries. |
| A private finance thread gains a wider audience | The pending sensitive return is held and rebuilt in a fresh scoped session before any reply. | Actual membership change, old session no longer resumed, withheld draft and safe replacement. |
| Teammate Tobi (read as Tobi A. by inference until the account is bound) asks about an event payout in a team group | Answer only where every recipient is allowed; omit bank details and route the restricted part appropriately. | Source classification, membership read and resulting answer. |
| Another teammate sends JR a DM | JR gives the agreed group-forum route without forwarding their private text. | Native DM receipt and the bounded response, no new group disclosure. |
| A teammate completes their own List item | The exact requested change is written once after current ownership verification and read back. | Native item ID, before/after value, requester ID and service receipt. |
| The same request targets somebody else's task | JR prepares the change for review and makes no task write. | Proposed action revision and unchanged service readback. |
| WobOS restarts mid-conversation | The same Work continues and does not duplicate a completed action. | Pre/post-restart Work/session linkage and reconciled action receipt. |
| A mixed meeting is corrected | The team answer uses the corrected public passage; private sections and personal debrief attribution remain separate. | Source revision, scoped evidence packet and corrected reply. |
| A useful follow-up becomes due | JR makes one permitted, relevant contribution tied to the owning task; the owner DM digest and Wob handoff retain attribution. | Trigger, Work continuation, destination readback and no unrelated schedule activation. |
| A real user corrects JR during the team trial | JR preserves the correction, repairs its answer and files a source-linked Squeaky issue when the mechanism failed. | Native conversation, repaired output and the accepted repair record. |
Use bounded disposable test records and verified self-only destinations first. The later team trial must be expressly authorized before contacting people. Reuse meaningful regression checks, then demonstrate the real Slack/Work/List path at its implementation milestone. Fake-client checks alone cannot close these scenarios.
The ticket breakdown follows complete user-visible slices: a durable scoped Slack conversation; routing and multi-person continuation; own-task changes; source review and handoff; separately gated JA memory; then useful follow-through and the authorized team trial.
The runtime start still depends on WOB-45's installed, usable foundation and actual SDK continuation evidence. Relevant memory failures must have a disposition, but unrelated features do not block the memory-off Slack slice. WOB-114's current candidate has not yet proven later native recall; WOB-112's disposition is owned by A. Those are live implementation facts, not reasons to reactivate the retired JR.
Fresh access reads on 20 October found the existing Slack user identity toberton (U0AVAFDASMT) and bot justanotheragent (U0BRM7JT8F4) in workspace T0AUYDT2V2B. Neither observed scope list showed Slack Lists scopes. App-level event transport credentials, event subscriptions and native List access remain to be established from the actual app configuration and vendor contracts. Chat connector access does not prove unattended runtime access.
Existing Lists remain the task home. Refresh them on relevant requests and authorized Work continuations; the vendor event index reviewed here did not establish a List-change event and does not justify a new polling schedule. The exact bot/user access rule for conversations.replies remains an implementation checkpoint: the reviewed page does not explicitly settle it, so the source note labels the related history rule as an inference.
No new product decision is required to write or review this spec. Any actual additional Slack scope or account grant will be presented as its exact effect after app inspection establishes the gap.
c15b3c43886b39e951df8c844cd887155de8cb7d: Work start/steer/session claims, SDK start/resume, permission-generation holds, source-result rechecks, worker environment and personal action contracts. These source reads establish available seams, not a running JR.AGENTS.md, Toberton's local overlay, team.md, current Slack/meeting skills and owning records at zoovie base 8c59dd9a353bfa8c58bfc2a339a58aa168d3fcdd; fresh Slack identity/member reads supplement the snapshots.c15b3c4 base and the source review's 8a986ec; neither that checkout's pyproject.toml nor its lock contains Slack/Bolt. The later implementation must select and qualify the dependency. No service rehearsal, app installation, task change or production memory write was performed to author this spec.