docs GitHub

Architecture

Person relay entry points

Standing rules (owner):

  • Fix the class everywhere: one shared implementation in lib/person-relay.js, every entry point wired through it, and table-driven tests derived from lib/person-relay-entrypoints.js (not hand-maintained surface lists).
  • Agent-agnostic: slash, member relay, and isolation live tests must behave the same for every registered session adapter. Use core/sessions/testing/fake-agent-harness.js (FAKE_SESSION_PROVIDERS: claude, grok, codex); do not wire tests through Claude-only env vars.

Shared binding

  • personCallOpts(caller, meta) gives { as, token?, kernelFacts?, person? } for nested ctx.call
  • relayPersonTool(ctx, caller, meta, tool, input) handles composer slash relays
  • core/modules/index.js merges CALL_AS from currentCall() for any person-surface { as }

Generated entry-point table

The canonical list is built at runtime:

import { listAllPersonRelayEntryPoints } from "../../lib/person-relay-entrypoints.js";
import { personRelayReportMarkdown } from "../../lib/person-relay-report.js";
// personRelayReportMarkdown(registry) → markdown for docs/PRs

Live isolation tests (parametrized over claude, grok, codex):

Harness: harness/member-relay-harness.js. /find live cases boot recall via core/sessions/testing/recall-live.js (Node 22.16+ for FTS5 in node:sqlite).

Primary surfaces

Entry id (from code)Surface toolNested person-scoped tools
composer.slashthreads.slashplanner.add, recall.search, threads.remember, threads.shell, …
composer.sendthreads.sendmentions.search, mentions.resolve, vault.mention.resolve
composer.edit-queuedthreads.editsame as send
stream / MCP slash idsthreads.slashsame as composer slash (see generated table)
stream send idsstream.send when registeredingress targets from ingressRelayTargets()

Exact stream and MCP entry ids are derived in listPersonRelayEntryPoints(); run personRelayReportMarkdown(registry) on a live box rather than duplicating them here.

Auxiliary relays

idToolNotes
agents.askagents.ask→ threads.send, threads.release as asking person
mentions.searchmentions.searchproviders run as caller
mentions.resolvementions.resolve→ vault.mention.resolve
views.*capsule.* / views.*first-party module tools as person (lib/views/engine.js)
connectors.declareconnectors.declare→ vault.put
appmods.installappmods.install→ connectors.connection.create

Module RELAY_ALLOWED

Person hops via { relay: true } (see core/modules/index.js): spaces, memory, work, publish, previews, providers, vault, term, mcp, appmods, import, each to a fixed nested tool prefix list. Documented in lib/person-relay-report.js (RELAY_ALLOWED_SUMMARY).

Out of scope for the entry-point list

  • Mac/box link writes (link.macs.call, as: "person")
  • MCP thread/agent labels without a person turn
  • Registry callers gates (separate from relay opts)