roncho requirements: divergences by behaviour, checked at a9708f1
roncho moved twice while the requirements were written. Line numbers are gone; each divergence is described by what the code does, rechecked at a9708f1, which added the Workspaces API: O1 and O7 now name the async functions, and workspace delete does not tell the 409 conflict apart. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
**For:** the agent that develops `roncho` (`git.wntrmute.dev/kyle/roncho`, `~/src/roncho` on titan).
|
**For:** the agent that develops `roncho` (`git.wntrmute.dev/kyle/roncho`, `~/src/roncho` on titan).
|
||||||
**From:** Boxmaker's design model, 2026-09-25, for milestone M5b. **Status:** requirements, for the
|
**From:** Boxmaker's design model, 2026-09-25, for milestone M5b. **Status:** requirements, for the
|
||||||
owner to hand over. Boxmaker's M5b spec is written against the release this produces. Code
|
owner to hand over. Boxmaker's M5b spec is written against the release this produces.
|
||||||
references are to `roncho` at `f24fc4a` ("Initial commit").
|
`roncho` was being reworked while this was written: the divergences in 3.4 were last checked at
|
||||||
|
`a9708f1` and are described by behaviour, not by line. Check each one before fixing it.
|
||||||
|
|
||||||
## 1. Why
|
## 1. Why
|
||||||
|
|
||||||
@@ -16,8 +17,8 @@ through `roncho`, not through a second client. Today `roncho` cannot be used fro
|
|||||||
with threads, no async runtime, and `memoryd` is the smallest-authority daemon of the set.
|
with threads, no async runtime, and `memoryd` is the smallest-authority daemon of the set.
|
||||||
- Some of its request and response shapes disagree with the live server. sift's Go client,
|
- Some of its request and response shapes disagree with the live server. sift's Go client,
|
||||||
checked against rift on 2026-09-22, found that workspace search takes `{"query", "limit"}` and
|
checked against rift on 2026-09-22, found that workspace search takes `{"query", "limit"}` and
|
||||||
returns a bare JSON array, not a `Page` (`~/src/sift/internal/fleetctx/fleetctx.go:115-147`,
|
returns a bare JSON array, not a `Page` (`~/src/sift/internal/fleetctx/fleetctx.go`,
|
||||||
`~/src/sift/docs/P2.md:103-105`).
|
`~/src/sift/docs/P2.md`).
|
||||||
- It defaults to `https://api.honcho.dev`. For Boxmaker, memory text must never leave the owner's
|
- It defaults to `https://api.honcho.dev`. For Boxmaker, memory text must never leave the owner's
|
||||||
hosts, so a default that points at a cloud service is a hazard, not a convenience.
|
hosts, so a default that points at a cloud service is a hazard, not a convenience.
|
||||||
|
|
||||||
@@ -28,11 +29,11 @@ the transport and the types: correct, small, and predictable.
|
|||||||
|
|
||||||
| Fact | Value | Source |
|
| Fact | Value | Source |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Honcho API | `http://rift.scylla-hammerhead.ts.net:8000`, plain HTTP over the tailnet | `imladris/hw/orion/default.nix:105`; `sift/docs/PLAN.md:38` |
|
| Honcho API | `http://rift.scylla-hammerhead.ts.net:8000`, plain HTTP over the tailnet | `imladris/hw/orion/default.nix`; `sift/docs/PLAN.md` |
|
||||||
| Version | 3.2.0, image `3.2.0-pr1092-7e57fe2` (roncho's SPEC targets 3.2.1) | `imladris/docs/metrics-plan.md` |
|
| Version | 3.2.0, image `3.2.0-pr1092-7e57fe2` (roncho's SPEC targets 3.2.1) | `imladris/docs/metrics-plan.md` |
|
||||||
| Authentication | apparently none: sift sends no `Authorization` header and succeeds. **Not confirmed.** | `sift/internal/fleetctx/fleetctx.go:117-127` |
|
| Authentication | apparently none: sift sends no `Authorization` header and succeeds. **Not confirmed.** | `sift/internal/fleetctx/fleetctx.go` |
|
||||||
| Models | deriver, summaries and dialectic on dixie's `ornith-1.5-9b-uncensored`; dialectic answers take 30 to 50 s | `imladris/hw/dixie/default.nix`; `sift/docs/PLAN.md:236-237` |
|
| Models | deriver, summaries and dialectic on dixie's `ornith-1.5-9b-uncensored`; dialectic answers take 30 to 50 s | `imladris/hw/dixie/default.nix`; `sift/docs/PLAN.md` |
|
||||||
| Workspaces in use | `hermes-fleet`, `guardian-star` (other agents'); each Boxmaker will have its own | `imladris/hw/orion/default.nix:106-107` |
|
| Workspaces in use | `hermes-fleet`, `guardian-star` (other agents'); each Boxmaker will have its own | `imladris/hw/orion/default.nix` |
|
||||||
|
|
||||||
**Never write to a workspace you did not create for testing.** `hermes-fleet` and
|
**Never write to a workspace you did not create for testing.** `hermes-fleet` and
|
||||||
`guardian-star` hold other agents' live memory. Write tests go to a throwaway workspace (for
|
`guardian-star` hold other agents' live memory. Write tests go to a throwaway workspace (for
|
||||||
@@ -84,8 +85,8 @@ MUST: Boxmaker cannot use `roncho` without it. SHOULD: Boxmaker can work around
|
|||||||
- **R11 (MUST)** The workspace is set explicitly per client. A client is cheap to clone and one
|
- **R11 (MUST)** The workspace is set explicitly per client. A client is cheap to clone and one
|
||||||
client serves one workspace, as today. A client is `Send + Sync`.
|
client serves one workspace, as today. A client is `Send + Sync`.
|
||||||
- **R12 (MUST)** The blocking client takes its configuration only from the caller. It reads no
|
- **R12 (MUST)** The blocking client takes its configuration only from the caller. It reads no
|
||||||
environment variables: not `HONCHO_*` (today `build()` falls back to `HONCHO_WORKSPACE_ID` and
|
environment variables: not `HONCHO_*` (today `build()` falls back to `HONCHO_WORKSPACE_ID`,
|
||||||
`HONCHO_API_KEY`, `src/client.rs:244-253`), not proxy settings (`HTTP_PROXY`, `ALL_PROXY` and so
|
`HONCHO_API_KEY` and `HONCHO_BASE_URL`), not proxy settings (`HTTP_PROXY`, `ALL_PROXY` and so
|
||||||
on). It does not follow redirects: a 3xx is returned as an error. Memory text is sent only to
|
on). It does not follow redirects: a 3xx is returned as an error. Memory text is sent only to
|
||||||
the configured host.
|
the configured host.
|
||||||
- **R13 (MUST)** Timeouts are set by the caller, per client: a connect timeout, and a read
|
- **R13 (MUST)** Timeouts are set by the caller, per client: a connect timeout, and a read
|
||||||
@@ -104,13 +105,13 @@ Each operation is verified against rift (3.4) before it is released. Names are s
|
|||||||
|
|
||||||
| # | Operation | Honcho endpoint (as roncho has it today; verify) | Boxmaker's use |
|
| # | Operation | Honcho endpoint (as roncho has it today; verify) | Boxmaker's use |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| O1 | get or create the workspace | not in roncho at `f24fc4a`; find it in Honcho 3.2's docs | first start |
|
| O1 | get or create the workspace | `POST /v3/workspaces` (in the async client as `get_or_create_workspace`) | first start |
|
||||||
| O2 | get or create a peer, with metadata and configuration | `POST peers` | the owner, the agent, other agents met in channels |
|
| O2 | get or create a peer, with metadata and configuration | `POST peers` | the owner, the agent, other agents met in channels |
|
||||||
| O3 | get or create a session, with its peers and each peer's `observe_me` / `observe_others` | `POST sessions` | one Honcho session per Boxmaker session |
|
| O3 | get or create a session, with its peers and each peer's `observe_me` / `observe_others` | `POST sessions` | one Honcho session per Boxmaker session |
|
||||||
| O4 | add messages in a batch, each with `peer_id`, `content`, `metadata` (a JSON object) and `created_at` | `POST sessions/{s}/messages` | the sync of finished turns; the metadata holds Boxmaker's session id, record number and labels |
|
| O4 | add messages in a batch, each with `peer_id`, `content`, `metadata` (a JSON object) and `created_at` | `POST sessions/{s}/messages` | the sync of finished turns; the metadata holds Boxmaker's session id, record number and labels |
|
||||||
| O5 | list a session's messages, paged, with filters | `POST sessions/{s}/messages/list` | checking what a sync already sent |
|
| O5 | list a session's messages, paged, with filters | `POST sessions/{s}/messages/list` | checking what a sync already sent |
|
||||||
| O6 | delete a session | `DELETE sessions/{s}` | rebuilding |
|
| O6 | delete a session | `DELETE sessions/{s}` | rebuilding |
|
||||||
| O7 | delete the workspace, and report the "active sessions" conflict (409) as its own error, if Honcho has one | not in roncho at `f24fc4a` | rebuilding |
|
| O7 | delete the workspace, and report the "active sessions" conflict (409) as its own error | `DELETE /v3/workspaces/{id}` (the async `delete_workspace` returns it as a generic error) | rebuilding |
|
||||||
| O8 | create conclusions in a batch (1 to 100), `content`, `observer_id`, `observed_id`, optional `session_id` | `POST conclusions` | entries moved out of identity; trusted notes |
|
| O8 | create conclusions in a batch (1 to 100), `content`, `observer_id`, `observed_id`, optional `session_id` | `POST conclusions` | entries moved out of identity; trusted notes |
|
||||||
| O9 | list, query and delete conclusions | `POST conclusions/list`, `POST conclusions/query`, `DELETE conclusions/{id}` | rebuilding; checks |
|
| O9 | list, query and delete conclusions | `POST conclusions/list`, `POST conclusions/query`, `DELETE conclusions/{id}` | rebuilding; checks |
|
||||||
| O10 | search the workspace, with a result limit | `POST search` (rift: `{"query", "limit"}` and a bare array) | `recall` |
|
| O10 | search the workspace, with a result limit | `POST search` (rift: `{"query", "limit"}` and a bare array) | `recall` |
|
||||||
@@ -134,23 +135,26 @@ Each operation is verified against rift (3.4) before it is released. Names are s
|
|||||||
may use `hermes-fleet`, writes never), and the result recorded in a compatibility document in
|
may use `hermes-fleet`, writes never), and the result recorded in a compatibility document in
|
||||||
the repository: endpoint, method, request shape, response shape, the date, and the server's
|
the repository: endpoint, method, request shape, response shape, the date, and the server's
|
||||||
version. Where Honcho's docs and rift disagree, rift wins and the document says so.
|
version. Where Honcho's docs and rift disagree, rift wins and the document says so.
|
||||||
- **R20 (MUST)** Fix these, found reading the current code, in the async client too:
|
- **R20 (MUST)** Fix these divergences, found by reading the async client; they apply to the
|
||||||
- search request and response shapes (O10, O11): rift takes `{"query", "limit"}` at the top
|
blocking client too, and any fix to shared models or request code applies to both:
|
||||||
level and returns a bare array (sift, above). roncho's workspace search sends `{"query"}` with
|
- **Search shapes (O10, O11).** rift takes `{"query", "limit"}` at the top level and answers
|
||||||
no limit and expects a `Page` (`src/api/workspace.rs:13-19`); peer and session search send
|
with a bare array (sift, above). roncho's workspace search sends `{"query"}` with no limit, and
|
||||||
`{"filters": {"query"}}` and expect a `Page` (`src/api/peers.rs:174-184`,
|
its peer and session searches send `{"filters": {"query"}}`; all three decode the answer as a
|
||||||
`src/api/sessions.rs:178-186`).
|
`Page`. There is no way to set a limit.
|
||||||
- `list_messages` computes the `page`, `size` and `reverse` query but never sends it
|
- **Paging of messages (O5).** `list_messages` builds the `page`, `size` and `reverse` query and
|
||||||
(`src/api/sessions.rs:110-120`), so a paged read can loop on the first page.
|
never sends it, so a paged read can keep getting the first page.
|
||||||
- `Message.role` is required when decoding (`src/models/message.rs:5-16`); sift's verified field
|
- **Message fields.** `Message.role` is required when decoding; sift's verified field list has no
|
||||||
list has no `role`.
|
`role`. Make every field Boxmaker does not need optional, and check which fields rift sends.
|
||||||
- peer and session lists use `GET` (`src/api/peers.rs:23-28`, `src/api/sessions.rs:18-23`);
|
- **List methods.** Peer and session lists use `GET`, while Honcho 3's other lists (messages,
|
||||||
Honcho 3's other lists are `POST …/list`. Settle on what rift does, and the same for
|
conclusions, workspaces) are `POST …/list`. Settle on what rift does, and the same for
|
||||||
`peers/{p}/context` (`src/resources/peer.rs:136-141`).
|
`peers/{p}/context`.
|
||||||
- the SSE reader splits each network chunk into lines on its own, so a line split across two
|
- **Streaming.** The SSE reader splits each network chunk into lines on its own, so a line split
|
||||||
chunks is misparsed (`src/api/peers.rs:122-135`, `src/api/workspace.rs:107-120`).
|
across two chunks is misparsed. Buffer until a newline.
|
||||||
- `build()` reports a missing workspace as `MissingApiKey` (`src/client.rs:244-248`).
|
- **Build errors.** A missing workspace is reported as `MissingApiKey`, and a missing key is an
|
||||||
- `max_retries` is stored and never read (`src/client.rs:20`, `264`; R13).
|
error at all (R10).
|
||||||
|
- **Retries.** `max_retries` is stored and never read (R13).
|
||||||
|
- **Workspace delete.** The "active sessions" conflict is not told apart from other failures
|
||||||
|
(O7, R18).
|
||||||
- **R21 (MUST)** Tests for the blocking client against a fake server in the test process
|
- **R21 (MUST)** Tests for the blocking client against a fake server in the test process
|
||||||
(`std::net::TcpListener`), covering each O-operation's request bytes and response decoding, and
|
(`std::net::TcpListener`), covering each O-operation's request bytes and response decoding, and
|
||||||
also: a refused connection, a server that sends nothing (read timeout), a server that stops
|
also: a refused connection, a server that sends nothing (read timeout), a server that stops
|
||||||
@@ -185,7 +189,7 @@ and record what you found (or "not found") in the compatibility document. Do not
|
|||||||
|
|
||||||
- Which turns are synced, trust per workspace, taint, sanitising text: Boxmaker's `memoryd`.
|
- Which turns are synced, trust per workspace, taint, sanitising text: Boxmaker's `memoryd`.
|
||||||
- Queues and progress tracking of a sync: `memoryd` keeps its own.
|
- Queues and progress tracking of a sync: `memoryd` keeps its own.
|
||||||
- A CLI. `roncho` has none at `f24fc4a`, and Boxmaker does not need one.
|
- A CLI. Boxmaker does not need one.
|
||||||
|
|
||||||
## 5. Done when
|
## 5. Done when
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user