P24: M5b is hardening, M5c Honcho, M5d the scheduler
Owner's decision. The hardening half (sanitizer, tag neutralisation, image links escaped, the invalid-arguments reason, and the secret store available to every role) needs neither roncho nor Honcho and can be specified now. Honcho waits on roncho's tagged release. Earlier documents keep the old numbers; P24 says so. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,8 +22,10 @@ M5a, M5b and M5c by P17 to P21 (applied 2026-09-24). M5a (local memory, `memoryd
|
|||||||
`docs/specs/2026-09-24-m5a-local-memory.md`, 22 tasks) is done and merged, reviewed in
|
`docs/specs/2026-09-24-m5a-local-memory.md`, 22 tasks) is done and merged, reviewed in
|
||||||
`docs/implementer-log.md` and checked on straylight against the owner's Mattermost; the device
|
`docs/implementer-log.md` and checked on straylight against the owner's Mattermost; the device
|
||||||
check found that a recalled tainted note left a session trusted, fixed by task 21. Its one open
|
check found that a recalled tainted note left a session trusted, fixed by task 21. Its one open
|
||||||
item, a reason in invalid-arguments refusals, is in `docs/decisions.md` for M5b. M5b (Honcho and
|
item, a reason in invalid-arguments refusals, is in `docs/decisions.md` for M5b. P24 split the
|
||||||
hardening) is next and has no spec yet. P22 (proposed, not applied) makes Boxmaker a fleet of
|
rest of M5: M5b is hardening (sanitizer, tag neutralisation, the secret store for every role) and
|
||||||
|
is next, with no spec yet; M5c is Honcho, through the owner's `roncho` once it has a tagged
|
||||||
|
release (`docs/specs/2026-09-25-roncho-requirements.md`); M5d is the scheduler. P22 (proposed, not applied) makes Boxmaker a fleet of
|
||||||
independent agents, one per host, deployed with Nix in a last milestone, M8; `flake.nix` builds
|
independent agents, one per host, deployed with Nix in a last milestone, M8; `flake.nix` builds
|
||||||
every binary, the tool image and a dev shell. Work happens on titan (macOS, no Nix); build and run
|
every binary, the tool image and a dev shell. Work happens on titan (macOS, no Nix); build and run
|
||||||
on straylight, where `~/src/boxmaker-m5a` is a clone built with `nix build`. The owner's Honcho
|
on straylight, where `~/src/boxmaker-m5a` is a clone built with `nix build`. The owner's Honcho
|
||||||
@@ -85,7 +87,7 @@ Separate binaries in one Cargo workspace. Each role holds as little authority as
|
|||||||
- `loopd` owns sessions and prompt assembly. It has no credentials and no network. Its only I/O
|
- `loopd` owns sessions and prompt assembly. It has no credentials and no network. Its only I/O
|
||||||
is Unix sockets to `gatewayd`, `brokerd`, `inferproxy` and (from M5a) `memoryd`.
|
is Unix sockets to `gatewayd`, `brokerd`, `inferproxy` and (from M5a) `memoryd`.
|
||||||
- `memoryd` (M5) owns memory: `memory/soul.md`, `memory.md`, `user.md` (identity), `notes.md` (experience), the FTS5
|
- `memoryd` (M5) owns memory: `memory/soul.md`, `memory.md`, `user.md` (identity), `notes.md` (experience), the FTS5
|
||||||
index, and from M5b the sync to the fleet's Honcho. It runs memory tool calls `brokerd` has
|
index, and from M5c the sync to the fleet's Honcho. It runs memory tool calls `brokerd` has
|
||||||
decided, and reaches Honcho and nothing else.
|
decided, and reaches Honcho and nothing else.
|
||||||
- `brokerd` is the only place authority lives. It reads owner-written grants (it cannot write
|
- `brokerd` is the only place authority lives. It reads owner-written grants (it cannot write
|
||||||
them), runs each approved tool call in a fresh rootless container, and writes a hash-chained
|
them), runs each approved tool call in a fresh rootless container, and writes a hash-chained
|
||||||
|
|||||||
+5
-4
@@ -6,6 +6,7 @@ Newest first. A decision that changes `docs/design.md` lands in the same commit
|
|||||||
|
|
||||||
| Date | Decision | Reason |
|
| Date | Decision | Reason |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|
| 2026-09-25 | P24, Milestones: M5b splits. M5b is hardening (the sanitizer, tag neutralisation in `loopd`, image links escaped in `gatewayd`, the invalid-arguments reason, and the secret store made available to every role, which the Honcho keys of M5c will need), which needs neither `roncho` nor Honcho and closes a gap open since M3. Honcho becomes M5c, planned once `roncho` has a tagged release. The scheduler and compaction move from M5c to M5d. Documents and decision rows written before this date use the old numbers. | Owner's decision, 2026-09-25. The hardening can be specified and run now; the Honcho half waits on `roncho` (`docs/specs/2026-09-25-roncho-requirements.md`). |
|
||||||
| 2026-09-25 | `memoryd` reaches Honcho through the owner's `roncho`, not a client of its own. `roncho` first gains a blocking client with a small dependency graph (no async runtime), no default server, no hidden environment settings or redirects, and request shapes checked against rift; the requirements are `docs/specs/2026-09-25-roncho-requirements.md`, handed to `roncho`'s developer. Boxmaker will allow that one git source in `deny.toml`, pinned by tag. | Owner's decision (M5b design). One client for the fleet. As it stands `roncho` is async only (tokio, reqwest), defaults to `api.honcho.dev`, and differs from rift in its search shapes, so it cannot be used unchanged. |
|
| 2026-09-25 | `memoryd` reaches Honcho through the owner's `roncho`, not a client of its own. `roncho` first gains a blocking client with a small dependency graph (no async runtime), no default server, no hidden environment settings or redirects, and request shapes checked against rift; the requirements are `docs/specs/2026-09-25-roncho-requirements.md`, handed to `roncho`'s developer. Boxmaker will allow that one git source in `deny.toml`, pinned by tag. | Owner's decision (M5b design). One client for the fleet. As it stands `roncho` is async only (tokio, reqwest), defaults to `api.honcho.dev`, and differs from rift in its search shapes, so it cannot be used unchanged. |
|
||||||
| 2026-09-24 | M5a's check on memory writes stays short and fixed: control characters, invisible characters, chat-template markup, six phrases. A research thread on prompt-injection defences feeds a sanitizer module for memory writes (and possibly other persisted text), built as hardening in M5b. Memory writes are not posted to the chat; `bxctl memory log` lists them. | Owner. The archive routing of untrusted sessions' writes is the main defence; a pattern list is defence in depth and should rest on research, not guesses. |
|
| 2026-09-24 | M5a's check on memory writes stays short and fixed: control characters, invisible characters, chat-template markup, six phrases. A research thread on prompt-injection defences feeds a sanitizer module for memory writes (and possibly other persisted text), built as hardening in M5b. Memory writes are not posted to the chat; `bxctl memory log` lists them. | Owner. The archive routing of untrusted sessions' writes is the main defence; a pattern list is defence in depth and should rest on research, not guesses. |
|
||||||
| 2026-09-24 | Memory writes need no approval, as in Hermes (the owner's `~/.hermes` has no `write_approval`). What a session that has seen untrusted content wants remembered becomes a note, labelled untrusted, not identity in the prompt (refined the same day: identity and experience are separate kinds of memory). Every write is scanned, journalled (listed by `bxctl memory log`, not posted anywhere) and can be undone; nothing is deleted. Brief change P21 proposed; the M5a spec is revised to match. Session-scoped approvals for other tools become an open decision. | Owner: an agent harness should act without a stream of questions, and reading and writing memory is what an agent is. The only risk the approval guarded is injected text reaching every future prompt, and that needs a session that read untrusted content; `brokerd` knows which sessions those are. |
|
| 2026-09-24 | Memory writes need no approval, as in Hermes (the owner's `~/.hermes` has no `write_approval`). What a session that has seen untrusted content wants remembered becomes a note, labelled untrusted, not identity in the prompt (refined the same day: identity and experience are separate kinds of memory). Every write is scanned, journalled (listed by `bxctl memory log`, not posted anywhere) and can be undone; nothing is deleted. Brief change P21 proposed; the M5a spec is revised to match. Session-scoped approvals for other tools become an open decision. | Owner: an agent harness should act without a stream of questions, and reading and writing memory is what an agent is. The only risk the approval guarded is injected text reaching every future prompt, and that needs a session that read untrusted content; `brokerd` knows which sessions those are. |
|
||||||
@@ -70,9 +71,9 @@ Newest first. A decision that changes `docs/design.md` lands in the same commit
|
|||||||
| How an approval whose arguments do not fit one Mattermost post is shown. Settled on 2026-09-18: what is being approved is never truncated, in any channel, because the unseen tail is where injected text would put its payload; `bxctl` prints arguments in full. Leading option for Mattermost: a thread of numbered chunks split on character boundaries of the escaped text, where only a reply or reaction on the last post counts and that post repeats the id, the chunk count and the hash of the whole; above some number of chunks, the post points to `bxctl approvals` and approval is local only. The post size limit and rate limits must be checked against the Mattermost API reference first. | M4 |
|
| How an approval whose arguments do not fit one Mattermost post is shown. Settled on 2026-09-18: what is being approved is never truncated, in any channel, because the unseen tail is where injected text would put its payload; `bxctl` prints arguments in full. Leading option for Mattermost: a thread of numbered chunks split on character boundaries of the escaped text, where only a reply or reaction on the last post counts and that post repeats the id, the chunk count and the hash of the whole; above some number of chunks, the post points to `bxctl approvals` and approval is local only. The post size limit and rate limits must be checked against the Mattermost API reference first. | M4 |
|
||||||
| Secret store: settled 2026-09-23 (systemd credentials, environment, owner-only file; P15 proposed). Where `brokerd` reads tool secrets from, and whether `SecretStore` moves out of `gatewayd` into a shared place, is decided when a tool first needs a secret. | when a tool needs a secret |
|
| Secret store: settled 2026-09-23 (systemd credentials, environment, owner-only file; P15 proposed). Where `brokerd` reads tool secrets from, and whether `SecretStore` moves out of `gatewayd` into a shared place, is decided when a tool first needs a secret. | when a tool needs a secret |
|
||||||
| Whether cloud-led sessions are ever allowed, and for which data classes. | M6 |
|
| Whether cloud-led sessions are ever allowed, and for which data classes. | M6 |
|
||||||
| Neutralizing chat-template tags in everything `loopd` sends (the owner's and other agents' messages, tool results, recalled text): measured 2026-09-24, a tag inside any message becomes Ornith's control token, so a fetched page can end its tool result and forge a system turn (`docs/research/2026-09-24-chat-template-tokens.md`). Proposed: replace each tag in a fixed list with an escaped look-alike when the text is first appended and logged (replay stays byte-identical), the list checked against the tokenizer by the self-test. Memory writes already refuse the tags (M5a). | before M5b; the exposure exists since M3 |
|
| Neutralizing chat-template tags in everything `loopd` sends (the owner's and other agents' messages, tool results, recalled text): measured 2026-09-24, a tag inside any message becomes Ornith's control token, so a fetched page can end its tool result and forge a system turn (`docs/research/2026-09-24-chat-template-tokens.md`). Proposed: replace each tag in a fixed list with an escaped look-alike when the text is first appended and logged (replay stays byte-identical), the list checked against the tokenizer by the self-test. Memory writes already refuse the tags (M5a). | M5b; the exposure exists since M3 |
|
||||||
| Session-scoped and standing approvals for tools other than memory: answering an approval with `!approve 42 session` (the same pattern for the rest of the session) or `!approve 42 always` (standing), words after the id as `!deny 42 <reason>` has (owner's syntax, 2026-09-24). To settle: what "session" covers (this call's tool and path or host, or the whole grant it matched); and where "always" writes, since `brokerd` cannot write grants (a proposed grant for the owner, or a separate directory of chat-approved grants). A temporary grant is new authority (the grants are the owner's files, and `brokerd` cannot write them), so it needs its own design. Owner's point, 2026-09-24: a harness should not ask a stream of questions. | after M5 |
|
| Session-scoped and standing approvals for tools other than memory: answering an approval with `!approve 42 session` (the same pattern for the rest of the session) or `!approve 42 always` (standing), words after the id as `!deny 42 <reason>` has (owner's syntax, 2026-09-24). To settle: what "session" covers (this call's tool and path or host, or the whole grant it matched); and where "always" writes, since `brokerd` cannot write grants (a proposed grant for the owner, or a separate directory of chat-approved grants). A temporary grant is new authority (the grants are the owner's files, and `brokerd` cannot write them), so it needs its own design. Owner's point, 2026-09-24: a harness should not ask a stream of questions. | after M5 |
|
||||||
| Projects in memory. Honcho can separate projects by a workspace per project (hard walls, shared naturally by every agent on the project, but Honcho's picture of the owner splits per workspace) or by scopes inside one workspace (one picture, recall filtered by project; semantics not yet read). Either way a project is a `memoryd` setting: its channels and threads, its workspace or scope, `write` and `trust`. A shared project workspace is written by several agents, so its trust is the owner's call per project. Test both on rift before choosing. Owner's idea, 2026-09-24. | M5b or a later M5d |
|
| Projects in memory. Honcho can separate projects by a workspace per project (hard walls, shared naturally by every agent on the project, but Honcho's picture of the owner splits per workspace) or by scopes inside one workspace (one picture, recall filtered by project; semantics not yet read). Either way a project is a `memoryd` setting: its channels and threads, its workspace or scope, `write` and `trust`. A shared project workspace is written by several agents, so its trust is the owner's call per project. Test both on rift before choosing. Owner's idea, 2026-09-24. | M5c or later |
|
||||||
|
|
||||||
## Applied to the design brief
|
## Applied to the design brief
|
||||||
|
|
||||||
@@ -112,5 +113,5 @@ Later changes to the brief:
|
|||||||
|
|
||||||
| # | Change | Reason |
|
| # | Change | Reason |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| P22 | Target environment, Roles and Milestones: Boxmaker becomes a fleet of independent agents, one per host. Each has its own identity (`soul.md`), memory, grants, audit log and credentials (its own Mattermost bot); they share only the fleet's memory, through Honcho (M5b). Each agent's inference is a configured endpoint that speaks llama-server's API: the host's own router, another host's, or a router such as crossbar. A new last milestone, M8, fleet deployment: `nixosModules.boxmaker` (`nix/module.nix`) for the owner's NixOS hosts, used from their system flake; `dist/` units, a config example and `make install` for other Linux hosts (an Omarchy machine); a host's inference measured, as M0 did on straylight, before an agent runs there. The flake itself (packages, the tool image, a dev shell) comes first, without the module. Open for M8: whether the roles run as systemd user units, as Hermes does on straylight (`linger`), or in M7's rootless containers; and what an endpoint must provide (`id_slot` pinning and queueing, `return_progress`, `timings_per_token`, `reasoning_control` and `/v1/chat/completions/control`, `/props`, `/slots`, prefix reuse on one slot), which the owner passes to crossbar's developer. Crossbar's answer (checked against its main, 4c64158, 2026-09-25): it cannot serve Boxmaker as deployed. It routes by the path's first segment or an `X-Crossbar-Route` header, never proxies `/slots` or `/tokenize`, may send `/control`, `/props` and `/slots` to a different host from the stream's, puts `/control` behind its limiter, and answers errors in its own shape. Until then an agent's `inferproxy` points straight at one host's llama-server. Crossbar's minimum for Boxmaker (a v2.3): a default route per listener, every call of a route on one host (a route per agent), side calls outside the limiter, and llama-server's error shape. Still open after that: a request queued in crossbar looks idle on the host's `/slots`, so Boxmaker retries it after 30 s; pinned routes should not queue in crossbar. Two agents on one host need different `[slots] main`. | Owner's direction, 2026-09-25: three agents run on three machines; boxmaker deploys to NixOS nodes from the system config and to an Omarchy machine; dixie gets an agent after its second GPU. |
|
| P22 | Target environment, Roles and Milestones: Boxmaker becomes a fleet of independent agents, one per host. Each has its own identity (`soul.md`), memory, grants, audit log and credentials (its own Mattermost bot); they share only the fleet's memory, through Honcho (M5c). Each agent's inference is a configured endpoint that speaks llama-server's API: the host's own router, another host's, or a router such as crossbar. A new last milestone, M8, fleet deployment: `nixosModules.boxmaker` (`nix/module.nix`) for the owner's NixOS hosts, used from their system flake; `dist/` units, a config example and `make install` for other Linux hosts (an Omarchy machine); a host's inference measured, as M0 did on straylight, before an agent runs there. The flake itself (packages, the tool image, a dev shell) comes first, without the module. Open for M8: whether the roles run as systemd user units, as Hermes does on straylight (`linger`), or in M7's rootless containers; and what an endpoint must provide (`id_slot` pinning and queueing, `return_progress`, `timings_per_token`, `reasoning_control` and `/v1/chat/completions/control`, `/props`, `/slots`, prefix reuse on one slot), which the owner passes to crossbar's developer. Crossbar's answer (checked against its main, 4c64158, 2026-09-25): it cannot serve Boxmaker as deployed. It routes by the path's first segment or an `X-Crossbar-Route` header, never proxies `/slots` or `/tokenize`, may send `/control`, `/props` and `/slots` to a different host from the stream's, puts `/control` behind its limiter, and answers errors in its own shape. Until then an agent's `inferproxy` points straight at one host's llama-server. Crossbar's minimum for Boxmaker (a v2.3): a default route per listener, every call of a route on one host (a route per agent), side calls outside the limiter, and llama-server's error shape. Still open after that: a request queued in crossbar looks idle on the host's `/slots`, so Boxmaker retries it after 30 s; pinned routes should not queue in crossbar. Two agents on one host need different `[slots] main`. | Owner's direction, 2026-09-25: three agents run on three machines; boxmaker deploys to NixOS nodes from the system config and to an Omarchy machine; dixie gets an agent after its second GPU. |
|
||||||
| P23 | Memory 4 and 5, Milestones (M5b): each agent writes to two Honcho workspaces of its own, a trusted one and an untrusted one. A finished turn is written as two messages, the owner's (or other speaker's) from their peer and the agent's final reply from the agent's peer; tool calls, tool results and intermediate reasoning are not written. A turn is clean when the session is still clean at the turn's end, because the reply is made from the whole context: clean turns go to the trusted workspace, the rest to the untrusted one, which `recall` and `ask_memory` read as `memory-tainted`. The gate is `brokerd`'s session state, asked over a read-only socket query when `memoryd` learns the turn ended; a late answer can only file a clean turn as untrusted, never the reverse. `loopd`'s log labels are a second check. M5b's check "a turn from a tainted session never reaches Honcho" becomes "never reaches the trusted workspace". | Owner's direction and approval, 2026-09-25 (M5b design): Honcho holds untrusted memories too, labelled by workspace since conclusions carry no per-entry provenance. Reading `brokerd`'s state file instead was rejected: a wrong path reads as clean (fails open), its modes block other users (M7), and it would make a private file an interface. To be applied to the brief with the M5b spec. |
|
| P23 | Memory 4 and 5, Milestones (M5c): each agent writes to two Honcho workspaces of its own, a trusted one and an untrusted one. A finished turn is written as two messages, the owner's (or other speaker's) from their peer and the agent's final reply from the agent's peer; tool calls, tool results and intermediate reasoning are not written. A turn is clean when the session is still clean at the turn's end, because the reply is made from the whole context: clean turns go to the trusted workspace, the rest to the untrusted one, which `recall` and `ask_memory` read as `memory-tainted`. The gate is `brokerd`'s session state, asked over a read-only socket query when `memoryd` learns the turn ended; a late answer can only file a clean turn as untrusted, never the reverse. `loopd`'s log labels are a second check. M5c's check "a turn from a tainted session never reaches Honcho" becomes "never reaches the trusted workspace". | Owner's direction and approval, 2026-09-25 (M5b design, now M5c): Honcho holds untrusted memories too, labelled by workspace since conclusions carry no per-entry provenance. Reading `brokerd`'s state file instead was rejected: a wrong path reads as clean (fails open), its modes block other users (M7), and it would make a private file an interface. To be applied to the brief with the M5b spec. |
|
||||||
|
|||||||
+3
-2
@@ -14,8 +14,9 @@ One session per milestone. The design brief is `docs/design.md`.
|
|||||||
| M4a | `gatewayd` + Mattermost conversations | Bot connection over TLS, user-ID allowlist, threads as sessions, bursts as one turn, typing while working, catching up after downtime, the secret store, no listening port | A direct message answered on the real server; a non-allowlisted user gets no response |
|
| M4a | `gatewayd` + Mattermost conversations | Bot connection over TLS, user-ID allowlist, threads as sessions, bursts as one turn, typing while working, catching up after downtime, the secret store, no listening port | A direct message answered on the real server; a non-allowlisted user gets no response |
|
||||||
| M4b | Approvals over Mattermost | `gateway.sock`, approval posts, answers by `!approve`/`!deny` in the thread, approvers list, long approvals in parts | An `ask` call approved and refused from Mattermost; the audit log names the post |
|
| M4b | Approvals over Mattermost | `gateway.sock`, approval posts, answers by `!approve`/`!deny` in the thread, approvers list, long approvals in parts | An `ask` call approved and refused from Mattermost; the audit log names the post |
|
||||||
| M5a | Local memory | `memoryd` without a network: the three memory files served to `loopd` once per epoch, the `memory` tool (`note`, and add, replace, remove, `consolidate` for identity) without questions and its check, `memory/notes.md`, the journal and `bxctl memory log`/`undo`, FTS5 `recall` over session logs and notes with source tags, `recall` hit counts, `bxctl reindex` | A fact from one session is recalled in another; an entry moved by `consolidate` is found by `recall`; a write from a session that read untrusted content becomes an untrusted note, never identity; a memory edit changes the prompt only in the next session (next epoch once M5c adds epochs); the baseline with the owner's files stays under 3,000 tokens |
|
| M5a | Local memory | `memoryd` without a network: the three memory files served to `loopd` once per epoch, the `memory` tool (`note`, and add, replace, remove, `consolidate` for identity) without questions and its check, `memory/notes.md`, the journal and `bxctl memory log`/`undo`, FTS5 `recall` over session logs and notes with source tags, `recall` hit counts, `bxctl reindex` | A fact from one session is recalled in another; an entry moved by `consolidate` is found by `recall`; a write from a session that read untrusted content becomes an untrusted note, never identity; a memory edit changes the prompt only in the next session (next epoch once M5c adds epochs); the baseline with the owner's files stays under 3,000 tokens |
|
||||||
| M5b | Honcho and hardening | A sanitizer module for memory writes, from the prompt-injection research of 2026-09-24; `memoryd` syncs finished turns to its own Honcho workspace through `roncho`, `recall` and `ask_memory` over Honcho, other workspaces read with the owner's trust labels, moved entries and trusted notes written as conclusions | A turn from a tainted session never reaches Honcho; a result from an untrusted workspace taints the session; Honcho's contents are rebuilt from the logs |
|
| M5b | Hardening | The sanitizer for memory writes, from the prompt-injection research of 2026-09-24: refuse only bytes that are never legitimate (invisible and format characters, bidirectional overrides, tag characters, private use, noncharacters, controls other than newline and tab) and known-prefix secrets; flag attack-shaped text (an identity write becomes a note, the reason journalled); chat-template tags neutralised to a visible look-alike wherever text enters the model's context or memory, the list checked against the tokenizer by the self-test; image links escaped in what `gatewayd` posts; a reason in invalid-arguments refusals; the secret store (systemd credential, environment, owner-only file) out of `gatewayd`, so every role can load its secrets at startup, failing closed | A tag in a fetched page reaches the model escaped; a write holding an invisible character or a key is refused; an identity write shaped like an attack becomes a note; a memory about code (a hash, a path, a fence, a command) is written unchanged; an image link in a reply is posted as text; a role whose secret is missing or readable by others does not start, and says which |
|
||||||
| M5c | Scheduler and compaction | Heartbeat and cron on their own slot in isolated sessions; compaction at idle, starting a new epoch from the baseline and a summary; summaries of tool output for the tools that opt in (a web fetch, say), indexed with the output's label; the tiering job, which decides what stays at which tier | A scheduled run leaves the main slot's cache intact; a fact from epoch 1 is recalled in epoch 2, and a memory edit reaches the next epoch; the tiering job promotes only trusted notes into identity, and its writes are journalled like any other |
|
| M5c | Honcho | `memoryd` syncs finished turns through `roncho` to two workspaces of its own (P23): the owner's message and the agent's final reply, to the trusted workspace while the session is clean at the turn's end (asked of `brokerd` over a socket), otherwise to the untrusted one; moved entries and trusted notes as conclusions; `recall` over the local index and every readable workspace at once; `ask_memory` over named workspaces in parallel; other agents' workspaces read with the owner's trust labels; keys from the secret store | A turn from a tainted session never reaches the trusted workspace; a result from an untrusted workspace taints the session; Honcho's contents are rebuilt from the logs; `recall` still answers from the local index when Honcho is down |
|
||||||
|
| M5d | Scheduler and compaction | Heartbeat and cron on their own slot in isolated sessions; compaction at idle, starting a new epoch from the baseline and a summary; summaries of tool output for the tools that opt in (a web fetch, say), indexed with the output's label; the tiering job, which decides what stays at which tier | A scheduled run leaves the main slot's cache intact; a fact from epoch 1 is recalled in epoch 2, and a memory edit reaches the next epoch; the tiering job promotes only trusted notes into identity, and its writes are journalled like any other |
|
||||||
| M6 | Subagents + cloud consult | Subagents on their slot returning summaries; consult tool gated by data-class grants with full payload log | A tainted session is refused; payload log matches what was sent |
|
| M6 | Subagents + cloud consult | Subagents on their slot returning summaries; consult tool gated by data-class grants with full payload log | A tainted session is refused; payload log matches what was sent |
|
||||||
| M7 | Split deployment | Each role in its own rootless container; `loopd` with no network; socket volume permissions; egress proxy for tools; host ACL policy in `deploy/` | From inside the `loopd` container, requests to the internet, the tailnet and the host all fail; a tool container without a host grant cannot reach the tailnet |
|
| M7 | Split deployment | Each role in its own rootless container; `loopd` with no network; socket volume permissions; egress proxy for tools; host ACL policy in `deploy/` | From inside the `loopd` container, requests to the internet, the tailnet and the host all fail; a tool container without a host grant cannot reach the tailnet |
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user