From 2dbc48ec8121bd1e132cc5a238fecc30530facfc Mon Sep 17 00:00:00 2001 From: ajspig Date: Tue, 25 Aug 2026 16:16:23 -0400 Subject: [PATCH] docs: add scopes to README architecture and fix changelog prefix --- CHANGELOG.md | 2 +- README.md | 31 ++++++++++++++++++++++++++++--- docs/changelog/introduction.mdx | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8705c2dd..3bef42b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added -- Scopes: a named grouping of sessions that acts as a visibility boundary on recall, implemented as a facade over an observer peer (`scope__{name}` with `{"kind": "scope"}`). Developers manage them exclusively through `/v3/workspaces/{workspace_id}/scopes` (create-or-get, list, get, add/list/remove session membership) and an optional `scopes` field on session create — never through the observer/observed mechanics. Scope peers cannot author messages, cannot be a chat or representation `target`, are excluded from `peers.list` by default (`PeerGet.kind` = `"scope"` / `"all"` switches the view), and are rejected on the generic session-peer routes. Workspace-level key required; peer- and session-scoped keys get 401. Legacy peers occupying a reserved `scope__` name without the kind flag are refused with 409, never adopted (#884) +- Scopes: a named grouping of sessions that acts as a visibility boundary on recall, implemented as a facade over an observer peer (`scope.{name}` with `{"kind": "scope"}`). Developers manage them exclusively through `/v3/workspaces/{workspace_id}/scopes` (create-or-get, list, get, add/list/remove session membership) and an optional `scopes` field on session create — never through the observer/observed mechanics. Scope peers cannot author messages, cannot be a chat or representation `target`, are excluded from `peers.list` by default (`PeerGet.kind` = `"scope"` / `"all"` switches the view), and are rejected on the generic session-peer routes. Workspace-level key required; peer- and session-scoped keys get 401. Legacy peers occupying a reserved `scope.` name without the kind flag are refused with 409, never adopted (#884) - `scope` read option on chat, representation, session context, and workspace search. A single scope swaps the observer to the backing scope peer so conclusion recall, peer cards, and message tools stay inside that scope's membership. A list of scopes takes the union of member sessions (capped at `MAX_SESSION_ALLOWLIST_ENTRIES`) and executes via the session-allowlist path. Empty scopes fail closed. `scope` is mutually exclusive with `filters` and `session_id`. Workspace- or admin-level key required (403 otherwise). Scope peers are also rejected as `peer_target` / `peer_perspective` on session context and as the path peer or `target` on `GET /peers/{id}/context` (#897) - Scope backfill-by-copy and removal reconciliation. Adding a session that already has messages copies its explicit-level documents into the scope's collections (no LLM re-derivation; idempotent via `copied_from`). Removing a session soft-deletes those copies and fail-closed cascades to derived documents whose `source_ids` intersect anything removed, then enqueues a `card_refresh` dream with `rebuild=True` plus an omni dream. `GET /v3/workspaces/{workspace_id}/scopes/{scope_id}/status` reports per-session backfill state (`pending` / `completed` / `failed`, plus `docs_copied`) (#904) - Workspace-level chat at `POST /v3/workspaces/{workspace_id}/chat`: agentic dialectic over the whole workspace instead of a single (observer, observed) pair. Prefetches workspace stats and the top active peers' self cards, then searches pair-scoped memory with `[observer->observed]` attribution. Supports `session_id`, `scope`, `reasoning_level`, `response_format`, and SSE streaming (#931) diff --git a/README.md b/README.md index 36755200..7c66cca3 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,7 @@ Peers exchange messages within sessions; Honcho reasons over those messages to b - **Workspace** (formerly App): top-level container; isolates data between use cases. - **Peer** (formerly User): any participant — human user or AI agent. - **Session**: a conversation context; many-to-many with peers. +- **Scope**: a named grouping of sessions that bounds recall (chat, representation, search) to those members. - **Message**: an atomic data unit (peer-to-peer communication or ingested document chunk). What you query out of Honcho: @@ -470,7 +471,7 @@ See the [configuration reference](https://honcho.dev/docs/v3/contributing/config ## Architecture -Honcho splits into two services: **Storage** (workspaces, peers, sessions, messages, internal collections) and **Insights** (reasoning, conclusions, representations, summaries, the chat endpoint). Storage is synchronous via the API; Insights is asynchronous via a background queue consumed by the deriver worker process. +Honcho splits into two services: **Storage** (workspaces, peers, sessions, scopes, messages, internal collections) and **Insights** (reasoning, conclusions, representations, summaries, the chat endpoint). Storage is synchronous via the API; Insights is asynchronous via a background queue consumed by the deriver worker process. **Key features:** @@ -498,16 +499,18 @@ Workspaces │ ├── Sessions │ │ └── (internal collections, keyed by observer/observed peer pair) │ │ +├── Scopes ←─────────────────┤ (many-to-many with sessions) │ │ -└── Sessions ←───────────────┤ (many-to-many) +└── Sessions ←───────────────┤ (many-to-many with peers) ├── Peers ───────────────┘ └── Messages (session-level) ``` **Relationship Details:** -- A **Workspace** contains multiple **Peers**. +- A **Workspace** contains multiple **Peers** and **Scopes**. - **Peers** and **Sessions** have a many-to-many relationship (peers can participate in multiple sessions, sessions can have multiple peers). +- **Scopes** and **Sessions** have a many-to-many relationship (a session can belong to several scopes; a scope groups many sessions). - **Messages** belong to a session and are labelled by their source peer. - **Internal collections** of vector-embedded **documents** are keyed by `(observer, observed)` peer pairs. They are not directly exposed via the API; the observations stored in them are exposed as **Conclusions**. @@ -531,6 +534,28 @@ This unified model enables complex multi-participant interactions. The `Session` object represents a set of interactions between `Peers` within a `Workspace`. Other applications may refer to this as a thread or conversation. Sessions can involve multiple peers with configurable observation settings. +A session can optionally join one or more **Scopes** at creation, or later via +the scopes API. + +#### Scopes + +A `Scope` is a named grouping of sessions inside a `Workspace`. It is a +visibility boundary on recall: chat, representation, session context, and +workspace search answered through a scope see only what happened in that +scope's member sessions. The underlying peers keep their unified +representations across everything they have participated in. + +Developers manage scopes through the scopes API (`honcho.scope(...)` / +`honcho.scopes()`) and an optional `scopes` field on session create — not +through observer/observed configuration. Adding a session that already has +messages copies its existing explicit conclusions into the scope (no +re-derivation); removing one reconciles those copies back out. Query +backfill progress with the scope `status` endpoint. + +A single scope name answers from that scope's collection and card. A list of +scopes restricts recall to the union of their member sessions. Empty scopes +fail closed. `scope` is mutually exclusive with `session` / `filters` on the +same read. #### Messages diff --git a/docs/changelog/introduction.mdx b/docs/changelog/introduction.mdx index e0b7cf51..15003c7d 100644 --- a/docs/changelog/introduction.mdx +++ b/docs/changelog/introduction.mdx @@ -30,7 +30,7 @@ Welcome to the Honcho changelog! This section documents all notable changes to t ### Added - - Scopes: a named grouping of sessions that acts as a visibility boundary on recall, implemented as a facade over an observer peer (`scope__{name}` with `{"kind": "scope"}`). Developers manage them exclusively through `/v3/workspaces/{workspace_id}/scopes` (create-or-get, list, get, add/list/remove session membership) and an optional `scopes` field on session create — never through the observer/observed mechanics. Scope peers cannot author messages, cannot be a chat or representation `target`, are excluded from `peers.list` by default (`PeerGet.kind` = `"scope"` / `"all"` switches the view), and are rejected on the generic session-peer routes. Workspace-level key required; peer- and session-scoped keys get 401. Legacy peers occupying a reserved `scope__` name without the kind flag are refused with 409, never adopted (#884) + - Scopes: a named grouping of sessions that acts as a visibility boundary on recall, implemented as a facade over an observer peer (`scope.{name}` with `{"kind": "scope"}`). Developers manage them exclusively through `/v3/workspaces/{workspace_id}/scopes` (create-or-get, list, get, add/list/remove session membership) and an optional `scopes` field on session create — never through the observer/observed mechanics. Scope peers cannot author messages, cannot be a chat or representation `target`, are excluded from `peers.list` by default (`PeerGet.kind` = `"scope"` / `"all"` switches the view), and are rejected on the generic session-peer routes. Workspace-level key required; peer- and session-scoped keys get 401. Legacy peers occupying a reserved `scope.` name without the kind flag are refused with 409, never adopted (#884) - `scope` read option on chat, representation, session context, and workspace search. A single scope swaps the observer to the backing scope peer so conclusion recall, peer cards, and message tools stay inside that scope's membership. A list of scopes takes the union of member sessions (capped at `MAX_SESSION_ALLOWLIST_ENTRIES`) and executes via the session-allowlist path. Empty scopes fail closed. `scope` is mutually exclusive with `filters` and `session_id`. Workspace- or admin-level key required (403 otherwise). Scope peers are also rejected as `peer_target` / `peer_perspective` on session context and as the path peer or `target` on `GET /peers/{id}/context` (#897) - Scope backfill-by-copy and removal reconciliation. Adding a session that already has messages copies its explicit-level documents into the scope's collections (no LLM re-derivation; idempotent via `copied_from`). Removing a session soft-deletes those copies and fail-closed cascades to derived documents whose `source_ids` intersect anything removed, then enqueues a `card_refresh` dream with `rebuild=True` plus an omni dream. `GET /v3/workspaces/{workspace_id}/scopes/{scope_id}/status` reports per-session backfill state (`pending` / `completed` / `failed`, plus `docs_copied`) (#904) - Workspace-level chat at `POST /v3/workspaces/{workspace_id}/chat`: agentic dialectic over the whole workspace instead of a single (observer, observed) pair. Prefetches workspace stats and the top active peers' self cards, then searches pair-scoped memory with `[observer->observed]` attribution. Supports `session_id`, `scope`, `reasoning_level`, `response_format`, and SSE streaming (#931)