From 1034c52656095923474b8a235c227b975a1ce70b Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:26:26 -0400 Subject: [PATCH 01/40] Seed AgentTerm README with Matrix-first ChatOps architecture --- README.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 49aebbd..d04808c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,91 @@ -# agent-term -AgentTerm: terminal-native ChatOps console for multi-agent operator workflows across SourceOS, AgentPlane, GitHub, CI, MCP, and LLM agents. +# AgentTerm + +AgentTerm is a terminal-native ChatOps console for coordinating human operators, LLM agents, GitHub bots, CI systems, MCP tools, Matrix rooms, and local SourceOS services from one channel/thread workspace. + +The design target is not another single-agent CLI. AgentTerm is the Slack-term class interface for agent operations: rooms, channels, threads, slash commands, approvals, event logs, adapters, and terminal-first operator flow. For SourceOS, Matrix is the canonical network ChatOps substrate. Slack and Discord should be treated as bridge targets, not the source of truth. + +## What this repo seeds + +- A Python CLI package named `agent-term`. +- A local SQLite event log for durable operator history. +- A minimal interactive shell for immediate use. +- A Textual TUI entry point for richer terminal UX. +- First-class Matrix adapter boundaries for rooms, events, redactions, membership, E2EE posture, and bridges. +- Adapter contracts for Hermes, Codex, Claude Code, OpenCLAW, GitHub, CI, MCP, and local process agents. +- Configuration examples and operating-model docs for building AgentTerm into the SourceOS operator console. + +## Core concept + +```text +┌──────────────────────────┬─────────────────────────────────────────────┐ +│ Matrix Rooms / Channels │ Thread / Conversation │ +│ !sourceos-build │ @codex: opened branch fix-ci-gate │ +│ !agentplane │ @claude-code: proposes patch plan │ +│ !policyfabric │ @github: PR #42 checks failing │ +│ !ci-failures │ @operator: /approve retry │ +├──────────────────────────┴─────────────────────────────────────────────┤ +│ /ask claude-code ... /assign codex ... /run ci /approve /summarize │ +└────────────────────────────────────────────────────────────────────────┘ +``` + +AgentTerm treats every meaningful action as an event: + +- human chat messages +- slash commands +- agent replies +- GitHub issue and PR updates +- CI status transitions +- MCP tool calls +- approval decisions +- handoffs between agents +- Matrix room events and bridge events + +The event log is the control plane. The terminal UI is only the operator surface. + +## Why Matrix first + +Matrix gives us a federated, open ChatOps substrate instead of binding the system to a vendor workspace. AgentTerm should be able to operate inside Matrix rooms, bridge to Slack/Discord where required, and preserve enough event metadata to audit agent actions. + +Initial Matrix requirements: + +- map AgentTerm channels to Matrix room IDs or aliases +- preserve Matrix event IDs for auditability +- support threaded replies where homeserver/client support exists +- model redactions as first-class governance events +- expose membership changes as security-relevant events +- support encrypted-room posture checks before agents receive sensitive context +- keep bridge metadata when Matrix rooms bridge to Slack, Discord, GitHub, or CI systems + +## MVP commands + +After cloning locally: + +```bash +python -m venv .venv +source .venv/bin/activate +pip install -e '.[dev]' +agent-term init +agent-term post '!sourceos-build' '@operator' 'AgentTerm is online.' +agent-term tail '!sourceos-build' +agent-term shell +``` + +The first implementation stores events in SQLite and executes process-backed adapters locally. Matrix network I/O is intentionally isolated behind an adapter boundary so the terminal, policy, event log, and agent registry can be hardened independently. + +## Adapter targets + +| Target | Role | +| --- | --- | +| Matrix | Canonical ChatOps transport and room substrate | +| Hermes | Personal/multi-channel agent gateway participant | +| Codex | Code-writing and repo mutation participant | +| Claude Code | Codebase reasoning and patch participant | +| OpenCLAW | Local/open agent runtime participant | +| GitHub | Issues, PRs, reviews, checks, branch events | +| CI | Workflow status, logs, retry/approve gates | +| MCP | Tool plane for files, docs, search, memory, calendar, etc. | +| Local process | Escape hatch for any CLI-driven agent or bot | + +## Repository status + +This is the seed implementation. The next step is to land a Matrix-room MVP, then bind Codex, Claude Code, Hermes, and OpenCLAW as participants under explicit operator permissions. From 8001b7714eca73a5250d0bc6369923159f0a60ad Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:27:43 -0400 Subject: [PATCH 02/40] Add Python package metadata for AgentTerm --- pyproject.toml | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9a54d47 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,63 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "agent-term" +version = "0.1.0" +description = "Terminal-native Matrix-first ChatOps console for SourceOS multi-agent operations." +readme = "README.md" +requires-python = ">=3.11" +license = { text = "MIT" } +authors = [ + { name = "SourceOS-Linux" } +] +keywords = [ + "sourceos", + "matrix", + "chatops", + "tui", + "agents", + "mcp", + "agentplane", + "policy-fabric", + "sherlock" +] +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Communications :: Chat", + "Topic :: Software Development :: User Interfaces" +] +dependencies = [] + +[project.optional-dependencies] +dev = [ + "pytest>=8.0", + "ruff>=0.4" +] +textual = [ + "textual>=0.58" +] +matrix = [ + "matrix-nio>=0.24" +] + +[project.scripts] +agent-term = "agent_term.cli:main" + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.ruff] +line-length = 100 +src = ["src", "tests"] + +[tool.pytest.ini_options] +testpaths = ["tests"] +pythonpath = ["src"] From 26fbf319694c402dc42165a6f3ea1c7d1ee7f74d Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:27:54 -0400 Subject: [PATCH 03/40] Add AgentTerm package init --- src/agent_term/__init__.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/agent_term/__init__.py diff --git a/src/agent_term/__init__.py b/src/agent_term/__init__.py new file mode 100644 index 0000000..e7ddf3b --- /dev/null +++ b/src/agent_term/__init__.py @@ -0,0 +1,3 @@ +"""AgentTerm package.""" + +__version__ = "0.1.0" From f4d1f0ef667ed290b0fa5d62a7a81b2a0e93b5b5 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:28:09 -0400 Subject: [PATCH 04/40] Add canonical AgentTerm event model --- src/agent_term/events.py | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/agent_term/events.py diff --git a/src/agent_term/events.py b/src/agent_term/events.py new file mode 100644 index 0000000..78ef2a1 --- /dev/null +++ b/src/agent_term/events.py @@ -0,0 +1,77 @@ +"""Canonical AgentTerm event model. + +AgentTerm treats terminal chat, Matrix room events, agent replies, policy decisions, +cloud-fog shell sessions, AgentPlane bundle runs, Sherlock search packets, and GitHub/CI +updates as append-only events. Keeping this model small makes the terminal shell usable now +while leaving enough structure for PolicyFabric and AgentPlane receipts later. +""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from datetime import UTC, datetime +from typing import Any +from uuid import uuid4 + + +@dataclass(frozen=True) +class AgentTermEvent: + """A single normalized ChatOps event. + + Attributes: + event_id: AgentTerm-local stable ID. + channel: Logical channel or Matrix room alias/ID. + sender: Human, agent, bot, or system principal. + kind: Event class such as message, command, decision, run, search, shell_session. + body: Human-readable event body. + thread_id: Optional thread/work-order identifier. + source: Source plane or adapter: matrix, local, agentplane, policy-fabric, sherlock, + cloudshell-fog, github, ci, mcp, hermes, codex, claude-code, openclaw. + metadata: Adapter-specific structured fields. + created_at: UTC timestamp. + """ + + channel: str + sender: str + kind: str + body: str + thread_id: str | None = None + source: str = "local" + metadata: dict[str, Any] = field(default_factory=dict) + event_id: str = field(default_factory=lambda: f"evt_{uuid4().hex}") + created_at: datetime = field(default_factory=lambda: datetime.now(UTC)) + + def to_record(self) -> dict[str, Any]: + return { + "event_id": self.event_id, + "channel": self.channel, + "sender": self.sender, + "kind": self.kind, + "body": self.body, + "thread_id": self.thread_id, + "source": self.source, + "metadata": self.metadata, + "created_at": self.created_at.isoformat(), + } + + @classmethod + def from_record(cls, record: dict[str, Any]) -> "AgentTermEvent": + created_at = record.get("created_at") + if isinstance(created_at, str): + parsed_created_at = datetime.fromisoformat(created_at) + elif isinstance(created_at, datetime): + parsed_created_at = created_at + else: + parsed_created_at = datetime.now(UTC) + + return cls( + event_id=record["event_id"], + channel=record["channel"], + sender=record["sender"], + kind=record["kind"], + body=record["body"], + thread_id=record.get("thread_id"), + source=record.get("source", "local"), + metadata=record.get("metadata") or {}, + created_at=parsed_created_at, + ) From 8800b58a4bf82bd34d6e438abb8d9037c85d502a Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:28:27 -0400 Subject: [PATCH 05/40] Add SQLite event store --- src/agent_term/store.py | 109 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/agent_term/store.py diff --git a/src/agent_term/store.py b/src/agent_term/store.py new file mode 100644 index 0000000..ffecd9d --- /dev/null +++ b/src/agent_term/store.py @@ -0,0 +1,109 @@ +"""SQLite-backed local event log for AgentTerm.""" + +from __future__ import annotations + +import json +import sqlite3 +from pathlib import Path +from typing import Iterable + +from agent_term.events import AgentTermEvent + + +DEFAULT_DB_PATH = Path(".agent-term/events.sqlite3") + + +class EventStore: + """Durable append-only store for AgentTerm events.""" + + def __init__(self, path: Path | str = DEFAULT_DB_PATH) -> None: + self.path = Path(path) + self.path.parent.mkdir(parents=True, exist_ok=True) + self._conn = sqlite3.connect(self.path) + self._conn.row_factory = sqlite3.Row + self.init_schema() + + def init_schema(self) -> None: + self._conn.execute( + """ + CREATE TABLE IF NOT EXISTS events ( + event_id TEXT PRIMARY KEY, + channel TEXT NOT NULL, + sender TEXT NOT NULL, + kind TEXT NOT NULL, + body TEXT NOT NULL, + thread_id TEXT, + source TEXT NOT NULL, + metadata_json TEXT NOT NULL, + created_at TEXT NOT NULL + ) + """ + ) + self._conn.execute("CREATE INDEX IF NOT EXISTS idx_events_channel ON events(channel)") + self._conn.execute("CREATE INDEX IF NOT EXISTS idx_events_thread ON events(thread_id)") + self._conn.execute("CREATE INDEX IF NOT EXISTS idx_events_source ON events(source)") + self._conn.commit() + + def append(self, event: AgentTermEvent) -> AgentTermEvent: + self._conn.execute( + """ + INSERT INTO events ( + event_id, channel, sender, kind, body, thread_id, source, metadata_json, created_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + """, + ( + event.event_id, + event.channel, + event.sender, + event.kind, + event.body, + event.thread_id, + event.source, + json.dumps(event.metadata, sort_keys=True), + event.created_at.isoformat(), + ), + ) + self._conn.commit() + return event + + def tail(self, channel: str | None = None, limit: int = 25) -> list[AgentTermEvent]: + if channel: + rows: Iterable[sqlite3.Row] = self._conn.execute( + """ + SELECT * FROM events + WHERE channel = ? + ORDER BY created_at DESC + LIMIT ? + """, + (channel, limit), + ) + else: + rows = self._conn.execute( + """ + SELECT * FROM events + ORDER BY created_at DESC + LIMIT ? + """, + (limit,), + ) + + events = [self._row_to_event(row) for row in rows] + return list(reversed(events)) + + def _row_to_event(self, row: sqlite3.Row) -> AgentTermEvent: + return AgentTermEvent.from_record( + { + "event_id": row["event_id"], + "channel": row["channel"], + "sender": row["sender"], + "kind": row["kind"], + "body": row["body"], + "thread_id": row["thread_id"], + "source": row["source"], + "metadata": json.loads(row["metadata_json"]), + "created_at": row["created_at"], + } + ) + + def close(self) -> None: + self._conn.close() From ce8775f08404036925d0bc4fef81cb711ea0173c Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:29:20 -0400 Subject: [PATCH 06/40] Add SourceOS plane registry --- src/agent_term/planes.py | 140 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/agent_term/planes.py diff --git a/src/agent_term/planes.py b/src/agent_term/planes.py new file mode 100644 index 0000000..62d193f --- /dev/null +++ b/src/agent_term/planes.py @@ -0,0 +1,140 @@ +"""SourceOS plane registry for AgentTerm. + +These records make SourceOS integration explicit at the CLI/event layer before any +network adapter is enabled. AgentTerm is the operator console; these planes own the +actual execution, policy, search, shell, and orchestration semantics. +""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Iterable + + +@dataclass(frozen=True) +class PlaneCapability: + """An operator-visible capability exposed by a SourceOS plane.""" + + name: str + description: str + requires_approval: bool = True + event_kinds: tuple[str, ...] = () + + +@dataclass(frozen=True) +class SourceOSPlane: + """A first-class SourceOS integration plane.""" + + key: str + display_name: str + repository: str + role: str + source: str + capabilities: tuple[PlaneCapability, ...] = field(default_factory=tuple) + notes: tuple[str, ...] = field(default_factory=tuple) + + +SOURCEOS_PLANES: tuple[SourceOSPlane, ...] = ( + SourceOSPlane( + key="matrix", + display_name="Matrix", + repository="external/matrix", + role="Canonical federated ChatOps transport for rooms, events, membership, redactions, bridge metadata, and E2EE posture.", + source="matrix", + capabilities=( + PlaneCapability("room_event_ingest", "Normalize Matrix room events into the AgentTerm event log.", False, ("message", "command")), + PlaneCapability("room_event_emit", "Emit approved agent/operator events back into Matrix rooms.", True, ("message", "decision")), + PlaneCapability("e2ee_posture_check", "Block sensitive context injection when encrypted-room posture is unknown or unsafe.", False, ("policy_check",)), + ), + ), + SourceOSPlane( + key="cloudshell-fog", + display_name="CloudShell Fog", + repository="SocioProphet/cloudshell-fog", + role="Fog-first secure shell/session substrate for browser and terminal-accessible operator runtimes.", + source="cloudshell-fog", + capabilities=( + PlaneCapability("request_shell_session", "Request a governed fog/cloud shell session.", True, ("shell_session", "command")), + PlaneCapability("attach_pty", "Attach to an approved PTY/WebSocket session.", True, ("shell_attach",)), + PlaneCapability("record_shell_audit", "Record session placement, identity, TTL, and audit metadata.", False, ("audit",)), + ), + notes=( + "AgentTerm should not bypass cloudshell-fog policy, placement, OIDC, TTL, or audit semantics.", + "Terminal UX must treat shell attach as a governed event, not an implicit local subprocess.", + ), + ), + SourceOSPlane( + key="agentplane", + display_name="AgentPlane", + repository="SocioProphet/agentplane", + role="Execution control plane for validated bundles, executor placement, runs, replay, and evidence artifacts.", + source="agentplane", + capabilities=( + PlaneCapability("validate_bundle", "Validate a bundle before execution.", False, ("validation",)), + PlaneCapability("select_executor", "Choose an executor and emit a placement decision.", True, ("placement",)), + PlaneCapability("run_bundle", "Run a governed bundle and emit run/replay artifacts.", True, ("run", "evidence")), + PlaneCapability("replay_run", "Replay a governed run from recorded artifacts.", True, ("replay",)), + ), + notes=( + "AgentTerm is the operator surface; AgentPlane remains the execution authority.", + "RunArtifact, ReplayArtifact, ValidationArtifact, and PlacementDecision metadata should be preserved in AgentTerm events.", + ), + ), + SourceOSPlane( + key="policy-fabric", + display_name="Policy Fabric", + repository="SocioProphet/policy-fabric", + role="Policy-as-code control repository for validating, packaging, reviewing, and releasing governed data-protection decisions.", + source="policy-fabric", + capabilities=( + PlaneCapability("evaluate_command", "Evaluate slash commands before dispatch.", False, ("policy_check",)), + PlaneCapability("approve_action", "Bind explicit approval decisions to operator identity and policy context.", True, ("decision",)), + PlaneCapability("emit_policy_evidence", "Persist validation and replay evidence for governed actions.", False, ("evidence",)), + ), + notes=( + "Every side-effecting adapter command should have a Policy Fabric decision point.", + "Policy failures should be visible as first-class ChatOps events, not hidden exceptions.", + ), + ), + SourceOSPlane( + key="sherlock-search", + display_name="Sherlock Search", + repository="SocioProphet/sherlock-search", + role="Canonical Sherlock retrieval/search-packet surface for professional intelligence, workroom-scoped context, and demo-grade discovery.", + source="sherlock-search", + capabilities=( + PlaneCapability("create_search_packet", "Create a scoped search packet for a workroom/thread.", True, ("search_packet",)), + PlaneCapability("validate_search_packet", "Validate Sherlock search-packet schema and examples.", False, ("validation",)), + PlaneCapability("hydrate_context_pack", "Hydrate Matrix/AgentPlane/PolicyFabric context for retrieval-aware agent work.", True, ("context_pack",)), + ), + notes=( + "This is the preferred Sherlock integration path for AgentTerm.", + "Search packets should carry provenance, scope, policy state, and workroom/thread binding.", + ), + ), + SourceOSPlane( + key="legacy-sherlock", + display_name="Legacy Sherlock OSINT", + repository="SocioProphet/sherlock", + role="Legacy username/social-network OSINT tool. Available only as a high-friction, policy-gated adapter.", + source="legacy-sherlock", + capabilities=( + PlaneCapability("username_lookup", "Run bounded username discovery with explicit authorization and audit metadata.", True, ("osint_lookup",)), + ), + notes=( + "Do not expose legacy Sherlock as a default agent tool.", + "Use Policy Fabric approvals, scope limits, terms-of-use warnings, and audit receipts before invocation.", + ), + ), +) + + +def iter_planes() -> Iterable[SourceOSPlane]: + return iter(SOURCEOS_PLANES) + + +def get_plane(key: str) -> SourceOSPlane: + for plane in SOURCEOS_PLANES: + if plane.key == key: + return plane + raise KeyError(f"unknown SourceOS plane: {key}") From c1d15a79b553e194fec8f03ab52d69fcb87e10ae Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:30:10 -0400 Subject: [PATCH 07/40] Add runnable AgentTerm CLI commands --- src/agent_term/cli.py | 322 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 src/agent_term/cli.py diff --git a/src/agent_term/cli.py b/src/agent_term/cli.py new file mode 100644 index 0000000..e72f247 --- /dev/null +++ b/src/agent_term/cli.py @@ -0,0 +1,322 @@ +"""Command-line entry point for AgentTerm.""" + +from __future__ import annotations + +import argparse +import json +import shlex +import sys +from pathlib import Path +from typing import Any + +from agent_term.events import AgentTermEvent +from agent_term.planes import get_plane, iter_planes +from agent_term.store import DEFAULT_DB_PATH, EventStore + + +DEFAULT_CHANNEL = "!sourceos-ops" + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + prog="agent-term", + description="Matrix-first terminal ChatOps console for SourceOS multi-agent operations.", + ) + parser.add_argument( + "--db", + default=str(DEFAULT_DB_PATH), + help="Path to the local AgentTerm SQLite event log.", + ) + + subparsers = parser.add_subparsers(dest="command", required=True) + + subparsers.add_parser("init", help="Initialize the local AgentTerm event log.") + + post = subparsers.add_parser("post", help="Append a message/event to the local event log.") + post.add_argument("channel") + post.add_argument("sender") + post.add_argument("body") + post.add_argument("--kind", default="message") + post.add_argument("--source", default="local") + post.add_argument("--thread-id") + post.add_argument("--metadata-json", default="{}") + + tail = subparsers.add_parser("tail", help="Show recent events.") + tail.add_argument("channel", nargs="?") + tail.add_argument("--limit", type=int, default=25) + + planes = subparsers.add_parser("planes", help="List or inspect first-class SourceOS planes.") + planes_sub = planes.add_subparsers(dest="planes_command", required=True) + planes_sub.add_parser("list", help="List registered SourceOS planes.") + show_plane = planes_sub.add_parser("show", help="Show one registered SourceOS plane.") + show_plane.add_argument("plane") + + request_shell = subparsers.add_parser( + "request-shell", + help="Record a governed cloudshell-fog shell-session request event.", + ) + request_shell.add_argument("channel") + request_shell.add_argument("profile", nargs="?", default="default") + request_shell.add_argument("--sender", default="@operator") + request_shell.add_argument("--ttl-seconds", type=int, default=3600) + request_shell.add_argument("--placement-hint", default="fog-first") + request_shell.add_argument("--thread-id") + + sherlock_packet = subparsers.add_parser( + "sherlock-packet", + help="Record a governed Sherlock search-packet request event.", + ) + sherlock_packet.add_argument("channel") + sherlock_packet.add_argument("query") + sherlock_packet.add_argument("--sender", default="@operator") + sherlock_packet.add_argument("--workroom", default="default") + sherlock_packet.add_argument("--scope", default="workroom") + sherlock_packet.add_argument("--thread-id") + + subparsers.add_parser("shell", help="Open the minimal AgentTerm interactive shell.") + + return parser + + +def parse_metadata(metadata_json: str) -> dict[str, Any]: + try: + value = json.loads(metadata_json) + except json.JSONDecodeError as exc: + raise SystemExit(f"metadata must be valid JSON: {exc}") from exc + if not isinstance(value, dict): + raise SystemExit("metadata must decode to a JSON object") + return value + + +def format_event(event: AgentTermEvent) -> str: + thread = f" thread={event.thread_id}" if event.thread_id else "" + return ( + f"{event.created_at.isoformat()} [{event.channel}] " + f"{event.sender} kind={event.kind} source={event.source}{thread}: {event.body}" + ) + + +def cmd_init(store: EventStore) -> int: + event = AgentTermEvent( + channel=DEFAULT_CHANNEL, + sender="@agent-term", + kind="system", + source="local", + body="AgentTerm local event log initialized.", + ) + store.append(event) + print(f"initialized: {store.path}") + return 0 + + +def cmd_post(store: EventStore, args: argparse.Namespace) -> int: + event = AgentTermEvent( + channel=args.channel, + sender=args.sender, + kind=args.kind, + source=args.source, + body=args.body, + thread_id=args.thread_id, + metadata=parse_metadata(args.metadata_json), + ) + store.append(event) + print(format_event(event)) + return 0 + + +def cmd_tail(store: EventStore, args: argparse.Namespace) -> int: + for event in store.tail(channel=args.channel, limit=args.limit): + print(format_event(event)) + return 0 + + +def cmd_planes(args: argparse.Namespace) -> int: + if args.planes_command == "list": + for plane in iter_planes(): + print(f"{plane.key}\t{plane.display_name}\t{plane.repository}") + return 0 + + if args.planes_command == "show": + plane = get_plane(args.plane) + print(f"{plane.display_name} ({plane.key})") + print(f"repo: {plane.repository}") + print(f"source: {plane.source}") + print(f"role: {plane.role}") + print("capabilities:") + for capability in plane.capabilities: + approval = "approval-required" if capability.requires_approval else "no-approval" + kinds = ",".join(capability.event_kinds) or "none" + print(f" - {capability.name} [{approval}; events={kinds}]") + print(f" {capability.description}") + if plane.notes: + print("notes:") + for note in plane.notes: + print(f" - {note}") + return 0 + + raise SystemExit(f"unknown planes command: {args.planes_command}") + + +def cmd_request_shell(store: EventStore, args: argparse.Namespace) -> int: + metadata = { + "plane": "cloudshell-fog", + "profile": args.profile, + "ttl_seconds": args.ttl_seconds, + "placement_hint": args.placement_hint, + "approval_required": True, + "next_authority": "policy-fabric", + } + event = AgentTermEvent( + channel=args.channel, + sender=args.sender, + kind="shell_session", + source="cloudshell-fog", + body=f"Request cloudshell-fog session profile={args.profile} placement={args.placement_hint}", + thread_id=args.thread_id, + metadata=metadata, + ) + store.append(event) + print(format_event(event)) + print("status: pending Policy Fabric approval before shell attach") + return 0 + + +def cmd_sherlock_packet(store: EventStore, args: argparse.Namespace) -> int: + metadata = { + "plane": "sherlock-search", + "query": args.query, + "workroom": args.workroom, + "scope": args.scope, + "approval_required": True, + "next_authority": "policy-fabric", + "preferred_repo": "SocioProphet/sherlock-search", + } + event = AgentTermEvent( + channel=args.channel, + sender=args.sender, + kind="search_packet", + source="sherlock-search", + body=f"Request Sherlock search packet workroom={args.workroom} scope={args.scope}: {args.query}", + thread_id=args.thread_id, + metadata=metadata, + ) + store.append(event) + print(format_event(event)) + print("status: pending Policy Fabric approval before context hydration or legacy OSINT tools") + return 0 + + +def cmd_shell(store: EventStore) -> int: + print("AgentTerm shell. Type /help for commands, /quit to exit.") + channel = DEFAULT_CHANNEL + sender = "@operator" + while True: + try: + line = input(f"{channel} {sender}> ").strip() + except (EOFError, KeyboardInterrupt): + print() + return 0 + if not line: + continue + if line in {"/quit", "/exit"}: + return 0 + if line == "/help": + print("/channel ") + print("/sender ") + print("/tail [limit]") + print("/planes") + print("/request-shell [profile]") + print("/sherlock ") + print("/quit") + print("Anything else is posted as a message event.") + continue + if line.startswith("/channel "): + channel = line.split(maxsplit=1)[1] + continue + if line.startswith("/sender "): + sender = line.split(maxsplit=1)[1] + continue + if line.startswith("/tail"): + parts = shlex.split(line) + limit = int(parts[1]) if len(parts) > 1 else 10 + for event in store.tail(channel=channel, limit=limit): + print(format_event(event)) + continue + if line == "/planes": + for plane in iter_planes(): + print(f"{plane.key}\t{plane.display_name}\t{plane.repository}") + continue + if line.startswith("/request-shell"): + parts = shlex.split(line) + profile = parts[1] if len(parts) > 1 else "default" + event = AgentTermEvent( + channel=channel, + sender=sender, + kind="shell_session", + source="cloudshell-fog", + body=f"Request cloudshell-fog session profile={profile}", + metadata={ + "plane": "cloudshell-fog", + "profile": profile, + "approval_required": True, + "next_authority": "policy-fabric", + }, + ) + store.append(event) + print(format_event(event)) + continue + if line.startswith("/sherlock "): + query = line.split(maxsplit=1)[1] + event = AgentTermEvent( + channel=channel, + sender=sender, + kind="search_packet", + source="sherlock-search", + body=f"Request Sherlock search packet: {query}", + metadata={ + "plane": "sherlock-search", + "query": query, + "approval_required": True, + "next_authority": "policy-fabric", + }, + ) + store.append(event) + print(format_event(event)) + continue + + event = AgentTermEvent(channel=channel, sender=sender, kind="message", source="local", body=line) + store.append(event) + print(format_event(event)) + + +def main(argv: list[str] | None = None) -> int: + parser = build_parser() + args = parser.parse_args(argv) + db_path = Path(args.db) + + if args.command == "planes": + return cmd_planes(args) + + store = EventStore(db_path) + try: + if args.command == "init": + return cmd_init(store) + if args.command == "post": + return cmd_post(store, args) + if args.command == "tail": + return cmd_tail(store, args) + if args.command == "request-shell": + return cmd_request_shell(store, args) + if args.command == "sherlock-packet": + return cmd_sherlock_packet(store, args) + if args.command == "shell": + return cmd_shell(store) + finally: + store.close() + + parser.error(f"unknown command: {args.command}") + return 2 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv[1:])) From 53750d0c1146b46ee08ae0b793d65bf6439feb95 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:30:43 -0400 Subject: [PATCH 08/40] Add AgentTerm adapter contract --- src/agent_term/adapters.py | 106 +++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/agent_term/adapters.py diff --git a/src/agent_term/adapters.py b/src/agent_term/adapters.py new file mode 100644 index 0000000..cb90164 --- /dev/null +++ b/src/agent_term/adapters.py @@ -0,0 +1,106 @@ +"""Adapter contracts for AgentTerm participants. + +Adapters translate between AgentTerm events and concrete systems: Matrix rooms, Hermes, +Codex, Claude Code, OpenCLAW, AgentPlane, Policy Fabric, Sherlock Search, cloudshell-fog, +GitHub, CI, MCP, and local process agents. + +This file intentionally avoids vendor SDK dependencies. Real network adapters should live behind +this small contract so the terminal UI, local event log, and policy boundary remain stable. +""" + +from __future__ import annotations + +import subprocess +from dataclasses import dataclass, field +from typing import Protocol + +from agent_term.events import AgentTermEvent + + +@dataclass(frozen=True) +class AdapterResult: + """Normalized adapter result emitted back into the AgentTerm event log.""" + + ok: bool + body: str + source: str + kind: str = "adapter_result" + metadata: dict[str, object] = field(default_factory=dict) + + def to_event(self, request: AgentTermEvent, sender: str = "@agent-term") -> AgentTermEvent: + return AgentTermEvent( + channel=request.channel, + sender=sender, + kind=self.kind, + source=self.source, + body=self.body, + thread_id=request.thread_id, + metadata={"request_event_id": request.event_id, **self.metadata}, + ) + + +class AgentTermAdapter(Protocol): + """Protocol implemented by AgentTerm integration adapters.""" + + key: str + + def supports(self, event: AgentTermEvent) -> bool: + """Return true when this adapter can handle the event.""" + + def handle(self, event: AgentTermEvent) -> AdapterResult: + """Handle an event and return a normalized result.""" + + +@dataclass(frozen=True) +class ProcessAdapter: + """Simple command-backed adapter for local agents and CLIs. + + The command is passed to the shell only when explicitly configured by the operator. This is + deliberately not wired to the interactive shell yet; Policy Fabric approval and SourceOS + execution envelopes should be inserted before side-effecting commands are enabled. + """ + + key: str + command: tuple[str, ...] + accepted_kinds: tuple[str, ...] = ("command",) + timeout_seconds: int = 300 + + def supports(self, event: AgentTermEvent) -> bool: + return event.kind in self.accepted_kinds or event.source == self.key + + def handle(self, event: AgentTermEvent) -> AdapterResult: + completed = subprocess.run( + [*self.command, event.body], + check=False, + text=True, + capture_output=True, + timeout=self.timeout_seconds, + ) + output = completed.stdout.strip() or completed.stderr.strip() + return AdapterResult( + ok=completed.returncode == 0, + body=output or f"{self.key} exited with code {completed.returncode}", + source=self.key, + metadata={ + "returncode": completed.returncode, + "command": list(self.command), + "stderr_present": bool(completed.stderr.strip()), + }, + ) + + +ADAPTER_TARGETS = { + "matrix": "Canonical room/event transport adapter; must preserve room IDs, event IDs, redactions, membership, bridge metadata, and E2EE posture.", + "hermes": "Personal/multi-channel agent gateway participant; may bridge external chat surfaces into Matrix-backed AgentTerm rooms.", + "codex": "Code-writing participant; must operate through repo branches, diffs, PRs, and approval-gated shell/test commands.", + "claude-code": "Codebase reasoning and patch participant; must emit plan, diff, command, and evidence events.", + "openclaw": "Local/open agent runtime participant; must run inside SourceOS capability and policy envelopes.", + "cloudshell-fog": "Fog-first shell/session substrate; AgentTerm requests sessions but does not bypass OIDC, placement, TTL, or audit.", + "agentplane": "Execution authority for bundle validation, placement, runs, replay, and evidence artifacts.", + "policy-fabric": "Policy decision and evidence authority for side-effecting commands and sensitive context release.", + "sherlock-search": "Preferred Sherlock integration for scoped search packets and context hydration.", + "legacy-sherlock": "High-friction policy-gated OSINT wrapper only; never a default ambient tool.", + "github": "Issue, PR, review, check, and branch event integration.", + "ci": "Workflow status/log/retry integration with explicit retry approval gates.", + "mcp": "Tool-plane adapter for files, docs, search, memory, calendar, and other governed capabilities.", +} From c1eb9d8d452f466953776cadfe33591f7f109309 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:31:19 -0400 Subject: [PATCH 09/40] Add SourceOS control-surface architecture doc --- docs/architecture/sourceos-control-surface.md | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 docs/architecture/sourceos-control-surface.md diff --git a/docs/architecture/sourceos-control-surface.md b/docs/architecture/sourceos-control-surface.md new file mode 100644 index 0000000..4911b5e --- /dev/null +++ b/docs/architecture/sourceos-control-surface.md @@ -0,0 +1,152 @@ +# AgentTerm as the SourceOS control surface + +AgentTerm is the terminal-native operator surface for the SourceOS multi-agent stack. It does not replace Matrix, cloudshell-fog, AgentPlane, Policy Fabric, Sherlock, GitHub, CI, MCP, Hermes, Codex, Claude Code, or OpenCLAW. It normalizes those systems into an auditable ChatOps event plane with terminal UX. + +## Boundary statement + +AgentTerm owns: + +- terminal-native room/thread UX +- normalized local event log +- slash-command parsing +- operator approval capture +- adapter dispatch boundaries +- integration visibility across SourceOS planes + +AgentTerm does not own: + +- Matrix homeserver semantics +- cloudshell-fog placement, OIDC, TTL, or PTY enforcement +- AgentPlane bundle execution or replay authority +- Policy Fabric policy authoring, validation, packaging, or release authority +- Sherlock search-packet schema authority +- legacy Sherlock OSINT behavior +- GitHub repository state +- CI workflow execution + +This keeps AgentTerm as an operator console rather than a new monolith. + +## First-class SourceOS planes + +| Plane | Canonical repo/surface | AgentTerm role | +| --- | --- | --- | +| Matrix | Matrix homeserver and bridge topology | canonical ChatOps transport for rooms, events, membership, redactions, bridge metadata, and E2EE posture | +| cloudshell-fog | `SocioProphet/cloudshell-fog` | fog-first secure shell/session substrate for governed terminal and browser shells | +| AgentPlane | `SocioProphet/agentplane` | execution authority for validate/place/run/evidence/replay flows | +| Policy Fabric | `SocioProphet/policy-fabric` | policy decision point for command dispatch, sensitive context release, and evidence capture | +| Sherlock Search | `SocioProphet/sherlock-search` | preferred Sherlock integration for search packets and workroom-scoped retrieval context | +| Legacy Sherlock | `SocioProphet/sherlock` | high-friction, policy-gated OSINT adapter only | +| GitHub | GitHub app/CLI/API | issue, PR, branch, review, and check state | +| CI | GitHub Actions and other runners | workflow status, logs, artifacts, retry gates | +| MCP | MCP servers/tools | governed capability plane for external tools and context sources | +| Hermes | Hermes-compatible agent gateway | multi-channel/personal agent participant | +| Codex | Codex CLI/cloud agent | code-writing participant under branch/PR/evidence gates | +| Claude Code | Claude Code CLI | codebase reasoning and patch participant under branch/PR/evidence gates | +| OpenCLAW | OpenCLAW/local open runtime | local/open agent runtime inside SourceOS policy envelopes | + +## Control loop + +```text +Matrix room event or local terminal command + -> AgentTerm normalized event + -> Policy Fabric decision point + -> Adapter dispatch + -> cloudshell-fog / AgentPlane / Sherlock / GitHub / CI / MCP / agent runtime + -> evidence event + -> Matrix room and local event log +``` + +Side-effecting operations must pass through a decision event before execution. Examples include shell attach, repo mutation, CI retry, search-packet hydration with sensitive context, legacy Sherlock OSINT lookup, and AgentPlane bundle execution. + +## Cloud-fog shell integration + +AgentTerm should request cloudshell-fog sessions instead of directly spawning privileged shells for SourceOS operator work. The minimum session request event needs: + +- operator identity +- Matrix room/channel +- thread/work-order ID +- requested profile +- TTL +- placement hint +- policy decision reference +- resulting session ID and attach URL reference when approved +- audit event correlation ID + +AgentTerm may still provide local development shell commands, but those are not a substitute for SourceOS-governed cloud-fog shell sessions. + +## AgentPlane integration + +AgentTerm should call AgentPlane for execution, not reimplement execution. The minimum event mapping is: + +| AgentPlane concept | AgentTerm event kind | +| --- | --- | +| `ValidationArtifact` | `validation` | +| `PlacementDecision` | `placement` | +| `PlacementReceipt` | `placement` / `evidence` | +| `RunArtifact` | `run` / `evidence` | +| `ReplayArtifact` | `replay` / `evidence` | +| `SessionArtifact` | `session` / `evidence` | + +AgentTerm threads should preserve artifact paths, content hashes, executor identity, bundle ID, policy IDs, and replay inputs. + +## Policy Fabric integration + +Policy Fabric is the decision authority for AgentTerm operations. AgentTerm should emit policy-check events before adapter dispatch and decision/evidence events after validation. + +Minimum policy hooks: + +- command admission +- capability admission +- context-release admission +- shell-session admission +- legacy OSINT admission +- GitHub mutation admission +- CI retry admission +- AgentPlane run admission + +Policy denials must be displayed in-channel with enough metadata for review. + +## Sherlock integration + +AgentTerm should prefer `sherlock-search` search packets over direct legacy Sherlock invocation. + +Preferred path: + +```text +/operator asks for investigation or retrieval + -> AgentTerm creates `search_packet` event + -> Policy Fabric evaluates scope + -> sherlock-search validates packet schema + -> retrieval/context hydration happens under workroom/thread scope + -> AgentTerm records provenance and packet ID +``` + +Legacy Sherlock username/social-network lookup is not a default ambient tool. It should require explicit scope, authorization, terms-of-use posture, and audit metadata. + +## Matrix integration + +Matrix room metadata is security-relevant. AgentTerm should preserve: + +- room ID and alias +- event ID +- sender MXID +- thread/root event when available +- membership changes +- redactions +- bridge metadata +- encryption state and verification posture + +Agents should not receive sensitive room history from an encrypted room unless AgentTerm can establish an acceptable E2EE posture. + +## Implementation order + +1. Local event log and CLI shell. +2. SourceOS plane registry. +3. Matrix read/write adapter with E2EE posture surfaced. +4. Policy Fabric command-admission stub. +5. cloudshell-fog session request and attach flow. +6. Sherlock Search packet validation and hydration flow. +7. AgentPlane validate/place/run/evidence flow. +8. GitHub/CI bridge events. +9. Hermes, Codex, Claude Code, and OpenCLAW participant adapters. +10. Textual TUI with rooms, threads, events, approvals, and evidence panes. From 5c28f555b1b756986d754665881522c46d72043d Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:31:45 -0400 Subject: [PATCH 10/40] Add SourceOS plane registry tests --- tests/test_planes.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/test_planes.py diff --git a/tests/test_planes.py b/tests/test_planes.py new file mode 100644 index 0000000..d2e078a --- /dev/null +++ b/tests/test_planes.py @@ -0,0 +1,44 @@ +from agent_term.planes import get_plane, iter_planes + + +def test_sourceos_planes_include_required_integrations(): + keys = {plane.key for plane in iter_planes()} + + assert "matrix" in keys + assert "cloudshell-fog" in keys + assert "agentplane" in keys + assert "policy-fabric" in keys + assert "sherlock-search" in keys + assert "legacy-sherlock" in keys + + +def test_sherlock_search_is_preferred_surface(): + sherlock = get_plane("sherlock-search") + legacy = get_plane("legacy-sherlock") + + assert sherlock.repository == "SocioProphet/sherlock-search" + assert "preferred" in " ".join(sherlock.notes).lower() + assert legacy.repository == "SocioProphet/sherlock" + assert any("policy-gated" in note for note in legacy.notes) + + +def test_side_effecting_capabilities_require_approval(): + side_effecting = [] + for plane in iter_planes(): + for capability in plane.capabilities: + if capability.name in { + "room_event_emit", + "request_shell_session", + "attach_pty", + "select_executor", + "run_bundle", + "replay_run", + "approve_action", + "create_search_packet", + "hydrate_context_pack", + "username_lookup", + }: + side_effecting.append((plane.key, capability.name, capability.requires_approval)) + + assert side_effecting + assert all(required for _, _, required in side_effecting) From 6d4731e5b817ef4161f55329a7fb0101b11a43b7 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:32:05 -0400 Subject: [PATCH 11/40] Add event store round-trip test --- tests/test_events_store.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/test_events_store.py diff --git a/tests/test_events_store.py b/tests/test_events_store.py new file mode 100644 index 0000000..4c68890 --- /dev/null +++ b/tests/test_events_store.py @@ -0,0 +1,26 @@ +from agent_term.events import AgentTermEvent +from agent_term.store import EventStore + + +def test_event_store_round_trips_events(tmp_path): + store = EventStore(tmp_path / "events.sqlite3") + try: + event = AgentTermEvent( + channel="!sourceos-build", + sender="@operator", + kind="search_packet", + source="sherlock-search", + body="Request scoped Sherlock packet", + thread_id="thread-1", + metadata={"workroom": "demo", "approval_required": True}, + ) + store.append(event) + + events = store.tail("!sourceos-build", limit=5) + finally: + store.close() + + assert len(events) == 1 + assert events[0].event_id == event.event_id + assert events[0].metadata["approval_required"] is True + assert events[0].source == "sherlock-search" From a054c68e51b95db733f46bceb337425d69fcb12e Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:32:32 -0400 Subject: [PATCH 12/40] Add Python and AgentTerm gitignore --- .gitignore | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a2808b --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Python +__pycache__/ +*.py[cod] +.pytest_cache/ +.ruff_cache/ +.venv/ +venv/ +build/ +dist/ +*.egg-info/ + +# AgentTerm local state +.agent-term/ +*.sqlite3 +*.sqlite3-shm +*.sqlite3-wal + +# OS/editor +.DS_Store +.idea/ +.vscode/ From 08e8c92e716b0964d3fc4e77508e16623a5bc657 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:32:42 -0400 Subject: [PATCH 13/40] Add CI workflow for AgentTerm --- .github/workflows/ci.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..dcf840e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install package + run: | + python -m pip install --upgrade pip + python -m pip install -e '.[dev]' + + - name: Lint + run: ruff check . + + - name: Test + run: pytest From b0134247838f2a0742826a9477e67a9ae3e715b4 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:33:11 -0400 Subject: [PATCH 14/40] Add agent instructions for SourceOS AgentTerm boundaries --- AGENTS.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d4b51e2 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,56 @@ +# Agent instructions for AgentTerm + +AgentTerm is the terminal-native Matrix-first ChatOps console for SourceOS. It is not a single-agent chat wrapper. + +## Mandatory architecture boundaries + +- Matrix is the canonical ChatOps transport. Slack and Discord are bridge targets, not the source of truth. +- AgentTerm is the operator surface and normalized event log. It does not own shell placement, bundle execution, policy release, search-packet schemas, or CI execution. +- cloudshell-fog owns governed shell/session placement, OIDC, TTL, PTY attach, and audit semantics. +- AgentPlane owns bundle validation, executor placement, runs, evidence artifacts, and replay. +- Policy Fabric owns policy decision/evidence surfaces for side-effecting operations and sensitive context release. +- Sherlock Search is the preferred Sherlock integration path. Legacy Sherlock username/social-network lookup is high-friction and policy-gated only. + +## Required invariants + +1. Side-effecting commands require an approval path. +2. Sensitive context release requires Policy Fabric admission. +3. Matrix room IDs, event IDs, membership changes, redactions, bridge metadata, and E2EE posture must be preserved when available. +4. AgentPlane evidence artifacts must remain visible in AgentTerm events. +5. cloudshell-fog shell attach must not bypass OIDC, placement, TTL, or audit semantics. +6. Legacy Sherlock OSINT must never become an ambient default tool. +7. Adapter code must be behind narrow contracts; do not hardwire vendor SDKs into the terminal shell. +8. Local event-log data must not be committed. + +## Development commands + +```bash +python -m venv .venv +source .venv/bin/activate +python -m pip install -e '.[dev]' +ruff check . +pytest +``` + +## Useful smoke commands + +```bash +agent-term init +agent-term planes list +agent-term planes show cloudshell-fog +agent-term request-shell '!sourceos-build' default --thread-id demo-shell +agent-term sherlock-packet '!sourceos-intel' 'find workroom context for AgentTerm Sherlock integration' --workroom agent-term +agent-term tail +``` + +## Preferred implementation order + +1. Keep the local event model and SourceOS plane registry stable. +2. Add Matrix adapter read/write with E2EE posture surfaced. +3. Add Policy Fabric command admission stub before side-effecting adapter execution. +4. Add cloudshell-fog session request/attach flow. +5. Add Sherlock Search packet validation/hydration flow. +6. Add AgentPlane validate/place/run/evidence flow. +7. Add GitHub and CI bridge events. +8. Add Hermes, Codex, Claude Code, and OpenCLAW participant adapters. +9. Add richer Textual TUI views for rooms, threads, approvals, and evidence. From e4c0f871dd338a4257db49f4f498a83690f82822 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:33:48 -0400 Subject: [PATCH 15/40] Update README with SourceOS control-surface commands --- README.md | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d04808c..ce73377 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AgentTerm -AgentTerm is a terminal-native ChatOps console for coordinating human operators, LLM agents, GitHub bots, CI systems, MCP tools, Matrix rooms, and local SourceOS services from one channel/thread workspace. +AgentTerm is a terminal-native ChatOps console for coordinating human operators, Matrix rooms, LLM agents, GitHub bots, CI systems, MCP tools, cloudshell-fog sessions, AgentPlane runs, Policy Fabric decisions, Sherlock search packets, and local SourceOS services from one channel/thread workspace. The design target is not another single-agent CLI. AgentTerm is the Slack-term class interface for agent operations: rooms, channels, threads, slash commands, approvals, event logs, adapters, and terminal-first operator flow. For SourceOS, Matrix is the canonical network ChatOps substrate. Slack and Discord should be treated as bridge targets, not the source of truth. @@ -9,10 +9,10 @@ The design target is not another single-agent CLI. AgentTerm is the Slack-term c - A Python CLI package named `agent-term`. - A local SQLite event log for durable operator history. - A minimal interactive shell for immediate use. -- A Textual TUI entry point for richer terminal UX. -- First-class Matrix adapter boundaries for rooms, events, redactions, membership, E2EE posture, and bridges. -- Adapter contracts for Hermes, Codex, Claude Code, OpenCLAW, GitHub, CI, MCP, and local process agents. -- Configuration examples and operating-model docs for building AgentTerm into the SourceOS operator console. +- First-class SourceOS plane registry for Matrix, cloudshell-fog, AgentPlane, Policy Fabric, Sherlock Search, legacy Sherlock, GitHub, CI, MCP, Hermes, Codex, Claude Code, and OpenCLAW. +- Adapter contracts for Matrix and process-backed participants. +- Governance-preserving command shapes for shell-session and Sherlock search-packet requests. +- Configuration examples, tests, CI, and operating-model docs for building AgentTerm into the SourceOS operator console. ## Core concept @@ -22,6 +22,7 @@ The design target is not another single-agent CLI. AgentTerm is the Slack-term c │ !sourceos-build │ @codex: opened branch fix-ci-gate │ │ !agentplane │ @claude-code: proposes patch plan │ │ !policyfabric │ @github: PR #42 checks failing │ +│ !sherlock-search │ @operator: /sherlock scoped context packet │ │ !ci-failures │ @operator: /approve retry │ ├──────────────────────────┴─────────────────────────────────────────────┤ │ /ask claude-code ... /assign codex ... /run ci /approve /summarize │ @@ -33,12 +34,15 @@ AgentTerm treats every meaningful action as an event: - human chat messages - slash commands - agent replies +- Matrix room events, redactions, membership changes, and bridge events - GitHub issue and PR updates - CI status transitions - MCP tool calls -- approval decisions +- Policy Fabric decisions +- AgentPlane validation, placement, run, replay, and evidence artifacts +- cloudshell-fog session and shell-attach events +- Sherlock search-packet and context-hydration events - handoffs between agents -- Matrix room events and bridge events The event log is the control plane. The terminal UI is only the operator surface. @@ -65,27 +69,42 @@ python -m venv .venv source .venv/bin/activate pip install -e '.[dev]' agent-term init +agent-term planes list +agent-term planes show cloudshell-fog agent-term post '!sourceos-build' '@operator' 'AgentTerm is online.' -agent-term tail '!sourceos-build' +agent-term request-shell '!sourceos-build' default --thread-id demo-shell +agent-term sherlock-packet '!sherlock-search' 'hydrate AgentTerm workroom context' --workroom agent-term --thread-id demo-search +agent-term tail agent-term shell ``` -The first implementation stores events in SQLite and executes process-backed adapters locally. Matrix network I/O is intentionally isolated behind an adapter boundary so the terminal, policy, event log, and agent registry can be hardened independently. +The first implementation stores events in SQLite and records governance-preserving events locally. Matrix network I/O, cloudshell-fog session attach, AgentPlane bundle execution, Policy Fabric admission, and Sherlock Search hydration are intentionally isolated behind adapter boundaries so the terminal, policy, event log, and agent registry can be hardened independently. -## Adapter targets +## First-class SourceOS planes | Target | Role | | --- | --- | | Matrix | Canonical ChatOps transport and room substrate | +| cloudshell-fog | Fog-first shell/session substrate; AgentTerm requests sessions but does not bypass OIDC, placement, TTL, or audit | +| AgentPlane | Execution authority for bundle validation, placement, runs, replay, and evidence artifacts | +| Policy Fabric | Policy decision and evidence authority for side-effecting commands and sensitive context release | +| Sherlock Search | Preferred Sherlock integration for scoped search packets and context hydration | +| Legacy Sherlock | High-friction policy-gated OSINT wrapper only; never a default ambient tool | | Hermes | Personal/multi-channel agent gateway participant | -| Codex | Code-writing and repo mutation participant | -| Claude Code | Codebase reasoning and patch participant | -| OpenCLAW | Local/open agent runtime participant | +| Codex | Code-writing participant under branch/PR/evidence gates | +| Claude Code | Codebase reasoning and patch participant under branch/PR/evidence gates | +| OpenCLAW | Local/open agent runtime inside SourceOS policy envelopes | | GitHub | Issues, PRs, reviews, checks, branch events | | CI | Workflow status, logs, retry/approve gates | | MCP | Tool plane for files, docs, search, memory, calendar, etc. | | Local process | Escape hatch for any CLI-driven agent or bot | +## Docs + +- [SourceOS control surface architecture](docs/architecture/sourceos-control-surface.md) +- [Agent instructions](AGENTS.md) +- [Example configuration](configs/agent-term.example.json) + ## Repository status -This is the seed implementation. The next step is to land a Matrix-room MVP, then bind Codex, Claude Code, Hermes, and OpenCLAW as participants under explicit operator permissions. +This is the seed implementation. It is intentionally small but runnable. The next step is to land the Matrix-room MVP, then bind Policy Fabric admission, cloudshell-fog session lifecycle, Sherlock Search packets, AgentPlane evidence flow, and Hermes/Codex/Claude Code/OpenCLAW participants under explicit operator permissions. From 5d4229a781306511d4c3b34a857ae0b14ed48233 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:34:19 -0400 Subject: [PATCH 16/40] Add AgentTerm example configuration --- configs/agent-term.example.json | 89 +++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 configs/agent-term.example.json diff --git a/configs/agent-term.example.json b/configs/agent-term.example.json new file mode 100644 index 0000000..b88b5b3 --- /dev/null +++ b/configs/agent-term.example.json @@ -0,0 +1,89 @@ +{ + "workspace": "sourceos", + "defaultChannel": "!sourceos-ops", + "eventStore": { + "driver": "sqlite", + "path": ".agent-term/events.sqlite3" + }, + "matrix": { + "enabled": false, + "homeserverUrl": "https://matrix.example.org", + "userId": "@agent-term:example.org", + "deviceName": "agent-term-operator-console", + "rooms": { + "sourceosOps": "!sourceos-ops:example.org", + "sourceosBuild": "!sourceos-build:example.org", + "agentplane": "!agentplane:example.org", + "policyFabric": "!policyfabric:example.org", + "sherlockSearch": "!sherlock-search:example.org", + "ciFailures": "!ci-failures:example.org" + }, + "requireEncryptedRoomPostureForSensitiveContext": true, + "preserveBridgeMetadata": true, + "preserveRedactions": true, + "preserveMembershipEvents": true + }, + "planes": { + "cloudshellFog": { + "enabled": true, + "repository": "SocioProphet/cloudshell-fog", + "baseUrl": "http://localhost:8080", + "defaultProfile": "default", + "defaultTtlSeconds": 3600, + "requirePolicyApproval": true + }, + "agentplane": { + "enabled": true, + "repository": "SocioProphet/agentplane", + "artifactKinds": [ + "ValidationArtifact", + "PlacementDecision", + "PlacementReceipt", + "RunArtifact", + "ReplayArtifact", + "SessionArtifact" + ], + "requirePolicyApprovalForRun": true + }, + "policyFabric": { + "enabled": true, + "repository": "SocioProphet/policy-fabric", + "decisionMode": "admit-before-side-effect", + "recordDenialsAsEvents": true + }, + "sherlockSearch": { + "enabled": true, + "repository": "SocioProphet/sherlock-search", + "preferred": true, + "requirePolicyApprovalForHydration": true + }, + "legacySherlock": { + "enabled": false, + "repository": "SocioProphet/sherlock", + "ambientToolAccess": false, + "requireExplicitAuthorization": true, + "requirePolicyApproval": true + } + }, + "participants": { + "hermes": { + "enabled": false, + "mode": "gateway" + }, + "codex": { + "enabled": false, + "mode": "repo-branch-pr", + "requirePolicyApprovalForMutation": true + }, + "claudeCode": { + "enabled": false, + "mode": "repo-branch-pr", + "requirePolicyApprovalForMutation": true + }, + "openclaw": { + "enabled": false, + "mode": "local-runtime", + "requirePolicyApprovalForSideEffects": true + } + } +} From ef9480eb7865d9b2f3725571586d267d03b4e796 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:34:48 -0400 Subject: [PATCH 17/40] Add python module entrypoint --- src/agent_term/__main__.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/agent_term/__main__.py diff --git a/src/agent_term/__main__.py b/src/agent_term/__main__.py new file mode 100644 index 0000000..d951c7a --- /dev/null +++ b/src/agent_term/__main__.py @@ -0,0 +1,6 @@ +"""Allow `python -m agent_term` execution.""" + +from agent_term.cli import main + + +raise SystemExit(main()) From d5939c31b0a90825e56f46a907f489704d0c309e Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:38:13 -0400 Subject: [PATCH 18/40] Expand SourceOS plane registry for workspace, topics, memory, graph, and semantic runtimes --- src/agent_term/planes.py | 180 ++++++++++++++++++++++++++++++++------- 1 file changed, 149 insertions(+), 31 deletions(-) diff --git a/src/agent_term/planes.py b/src/agent_term/planes.py index 62d193f..94c7dc6 100644 --- a/src/agent_term/planes.py +++ b/src/agent_term/planes.py @@ -2,7 +2,8 @@ These records make SourceOS integration explicit at the CLI/event layer before any network adapter is enabled. AgentTerm is the operator console; these planes own the -actual execution, policy, search, shell, and orchestration semantics. +actual workspace, semantic, memory, execution, policy, search, shell, and orchestration +semantics. """ from __future__ import annotations @@ -47,6 +48,153 @@ class SourceOSPlane: PlaneCapability("e2ee_posture_check", "Block sensitive context injection when encrypted-room posture is unknown or unsafe.", False, ("policy_check",)), ), ), + SourceOSPlane( + key="sociosphere", + display_name="Sociosphere", + repository="SocioProphet/sociosphere", + role="Platform meta-workspace controller for canonical workspace manifests, dependency topology, governance registry, validation lanes, and release-readiness orchestration.", + source="sociosphere", + capabilities=( + PlaneCapability("resolve_workspace_manifest", "Resolve canonical workspace repositories, roles, pins, and local overrides.", False, ("workspace_manifest",)), + PlaneCapability("validate_topology", "Validate cross-repo directionality, dependency rules, and governance registry state.", False, ("validation",)), + PlaneCapability("materialize_workspace", "Materialize a governed multi-repo workspace from the canonical manifest.", True, ("workspace_materialization",)), + ), + notes=( + "Sociosphere is the meta-workspace controller; AgentTerm should display and request workspace operations, not own them.", + "AgentTerm events should preserve manifest, lock, topology, and validation evidence references.", + ), + ), + SourceOSPlane( + key="prophet-workspace", + display_name="Prophet Workspace", + repository="SocioProphet/prophet-workspace", + role="Open workspace product suite and Professional Workrooms contract surface for mail, calendar, drive, docs, chat, meetings, policy-aware UX, admin, audit, and search.", + source="prophet-workspace", + capabilities=( + PlaneCapability("open_workroom", "Bind an AgentTerm thread to a Professional Workroom.", False, ("workroom",)), + PlaneCapability("validate_workroom", "Validate Professional Workroom contracts and examples.", False, ("validation",)), + PlaneCapability("hydrate_workspace_context", "Release policy-approved workspace context into an agent thread.", True, ("context_pack", "workroom")), + PlaneCapability("record_workspace_receipt", "Record workspace audit, receipt, and provenance references.", False, ("evidence",)), + ), + notes=( + "Prophet Workspace owns product/workroom semantics; Sociosphere owns meta-workspace manifest and topology.", + "AgentTerm should map Matrix rooms and local threads to Professional Workrooms when available.", + ), + ), + SourceOSPlane( + key="slash-topics", + display_name="Slash Topics", + repository="SocioProphet/slash-topics", + role="Governed, signed, replayable topic scopes for search and knowledge surfaces with policy membranes and deterministic receipts.", + source="slash-topics", + capabilities=( + PlaneCapability("select_topic_scope", "Bind a slash-topic scope to a room, thread, workroom, or query.", False, ("topic_scope",)), + PlaneCapability("validate_topic_pack", "Validate signed topic packs, schemas, and policy membranes.", False, ("validation",)), + PlaneCapability("apply_topic_membrane", "Apply topic-policy gates before search, memory, or context release.", True, ("policy_check", "topic_scope")), + ), + notes=( + "Slash Topics should route and constrain search, memory, Holmes/Sherlock investigation, and New Hope semantic threads.", + "AgentTerm slash commands should preserve topic-pack IDs, signature state, membrane decisions, and replay receipts.", + ), + ), + SourceOSPlane( + key="memory-mesh", + display_name="Memory Mesh", + repository="SocioProphet/memory-mesh", + role="Canonical memory runtime for recall, writeback, config watch, resource application, context packs, LiteLLM callbacks, and OpenCLAW memory tools.", + source="memory-mesh", + capabilities=( + PlaneCapability("recall_context", "Recall scoped memory/context before an agent or investigation run.", True, ("memory_recall", "context_pack")), + PlaneCapability("write_memory", "Write governed memory after an agent action or workroom event.", True, ("memory_write",)), + PlaneCapability("validate_context_pack", "Validate Professional Intelligence context-pack contracts and examples.", False, ("validation",)), + PlaneCapability("record_memory_evidence", "Record memory entries, source references, and evidence records.", False, ("evidence",)), + ), + notes=( + "Memory Mesh should be used for governed recall/writeback, not ad hoc prompt stuffing.", + "Context release should carry workroom, topic, policy, search-packet, and evidence references.", + ), + ), + SourceOSPlane( + key="new-hope", + display_name="New Hope", + repository="SocioProphet/new-hope", + role="Higher-order semantic runtime for agentic commons over messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events.", + source="new-hope", + capabilities=( + PlaneCapability("normalize_thread", "Normalize Matrix/workspace/chat threads into New Hope semantic objects.", False, ("semantic_thread",)), + PlaneCapability("extract_claims", "Extract governed claims, citations, entities, and lenses from a thread.", True, ("claim", "citation")), + PlaneCapability("apply_semantic_membrane", "Apply New Hope receptor/membrane decisions before routing or ranking.", True, ("policy_check", "semantic_membrane")), + PlaneCapability("record_moderation_event", "Record moderation/ranking/provenance decisions as replayable semantic events.", False, ("moderation_event", "evidence")), + ), + notes=( + "New Hope is not covered by Holmes or Sherlock; it is the semantic runtime underneath message/thread/claim/citation operations.", + "AgentTerm should use New Hope to normalize operator and agent conversations before routing them into Holmes/Sherlock/Memory Mesh where appropriate.", + ), + ), + SourceOSPlane( + key="holmes", + display_name="Holmes", + repository="SocioProphet/holmes", + role="Governed language intelligence fabric for NLP, semantic search, retrieval, knowledge graphs, guardrails, evals, casefiles, and investigative agentic discovery.", + source="holmes", + capabilities=( + PlaneCapability("open_casefile", "Bind a workroom/thread to a Holmes investigation or casefile.", True, ("casefile",)), + PlaneCapability("investigate", "Run governed language-intelligence workflows over evidence, retrieval, and semantic graphs.", True, ("investigation",)), + PlaneCapability("synthesize_findings", "Synthesize findings with claim, citation, provenance, and contradiction metadata.", True, ("synthesis", "evidence")), + PlaneCapability("run_evals", "Run language/retrieval/guardrail/evidence evals for a case or agent flow.", True, ("eval",)), + ), + notes=( + "Holmes is the language-intelligence fabric above search, evidence, retrieval, casefiles, semantic graphs, tools, models, evals, and agents.", + "Holmes should coordinate with Sherlock Search for retrieval and New Hope for semantic message/thread/claim objects.", + ), + ), + SourceOSPlane( + key="sherlock-search", + display_name="Sherlock Search", + repository="SocioProphet/sherlock-search", + role="Canonical Sherlock retrieval/search-packet surface for professional intelligence, workroom-scoped context, and demo-grade discovery.", + source="sherlock-search", + capabilities=( + PlaneCapability("create_search_packet", "Create a scoped search packet for a workroom/thread.", True, ("search_packet",)), + PlaneCapability("validate_search_packet", "Validate Sherlock search-packet schema and examples.", False, ("validation",)), + PlaneCapability("hydrate_context_pack", "Hydrate Matrix/AgentPlane/PolicyFabric context for retrieval-aware agent work.", True, ("context_pack",)), + ), + notes=( + "This is the preferred Sherlock integration path for AgentTerm.", + "Search packets should carry provenance, scope, policy state, topic scope, memory references, and workroom/thread binding.", + ), + ), + SourceOSPlane( + key="legacy-sherlock", + display_name="Legacy Sherlock OSINT", + repository="SocioProphet/sherlock", + role="Legacy username/social-network OSINT tool. Available only as a high-friction, policy-gated adapter.", + source="legacy-sherlock", + capabilities=( + PlaneCapability("username_lookup", "Run bounded username discovery with explicit authorization and audit metadata.", True, ("osint_lookup",)), + ), + notes=( + "Do not expose legacy Sherlock as a default agent tool.", + "Use Policy Fabric approvals, scope limits, terms-of-use warnings, and audit receipts before invocation.", + ), + ), + SourceOSPlane( + key="meshrush", + display_name="MeshRush", + repository="SocioProphet/meshrush", + role="Graph-native autonomous-agent protocol and reference runtime for operating over graph views derived from typed hypergraph world models.", + source="meshrush", + capabilities=( + PlaneCapability("enter_graph_view", "Bind an agent or workroom thread to a typed graph view.", True, ("graph_view",)), + PlaneCapability("diffuse_graph", "Run governed graph diffusion/exploration while preserving provenance.", True, ("graph_diffusion",)), + PlaneCapability("crystallize_artifact", "Persist stable local graph structure and derived artifacts.", True, ("graph_artifact", "evidence")), + PlaneCapability("record_graph_trace", "Record traces and learning/evaluation surfaces for adjacent systems.", False, ("trace", "evidence")), + ), + notes=( + "MeshRush is the graph-operating runtime; it does not replace Sociosphere, AgentPlane, Prophet Workspace, or Holmes.", + "AgentTerm should expose graph operations as visible, policy-aware events with provenance and reversibility metadata.", + ), + ), SourceOSPlane( key="cloudshell-fog", display_name="CloudShell Fog", @@ -96,36 +244,6 @@ class SourceOSPlane: "Policy failures should be visible as first-class ChatOps events, not hidden exceptions.", ), ), - SourceOSPlane( - key="sherlock-search", - display_name="Sherlock Search", - repository="SocioProphet/sherlock-search", - role="Canonical Sherlock retrieval/search-packet surface for professional intelligence, workroom-scoped context, and demo-grade discovery.", - source="sherlock-search", - capabilities=( - PlaneCapability("create_search_packet", "Create a scoped search packet for a workroom/thread.", True, ("search_packet",)), - PlaneCapability("validate_search_packet", "Validate Sherlock search-packet schema and examples.", False, ("validation",)), - PlaneCapability("hydrate_context_pack", "Hydrate Matrix/AgentPlane/PolicyFabric context for retrieval-aware agent work.", True, ("context_pack",)), - ), - notes=( - "This is the preferred Sherlock integration path for AgentTerm.", - "Search packets should carry provenance, scope, policy state, and workroom/thread binding.", - ), - ), - SourceOSPlane( - key="legacy-sherlock", - display_name="Legacy Sherlock OSINT", - repository="SocioProphet/sherlock", - role="Legacy username/social-network OSINT tool. Available only as a high-friction, policy-gated adapter.", - source="legacy-sherlock", - capabilities=( - PlaneCapability("username_lookup", "Run bounded username discovery with explicit authorization and audit metadata.", True, ("osint_lookup",)), - ), - notes=( - "Do not expose legacy Sherlock as a default agent tool.", - "Use Policy Fabric approvals, scope limits, terms-of-use warnings, and audit receipts before invocation.", - ), - ), ) From a67ee8274ad48dc9e0dba9b37757b1caf8eff9a3 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:38:56 -0400 Subject: [PATCH 19/40] Expand plane tests for full SourceOS control surface --- tests/test_planes.py | 45 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/tests/test_planes.py b/tests/test_planes.py index d2e078a..4bb170d 100644 --- a/tests/test_planes.py +++ b/tests/test_planes.py @@ -5,11 +5,32 @@ def test_sourceos_planes_include_required_integrations(): keys = {plane.key for plane in iter_planes()} assert "matrix" in keys + assert "sociosphere" in keys + assert "prophet-workspace" in keys + assert "slash-topics" in keys + assert "memory-mesh" in keys + assert "new-hope" in keys + assert "holmes" in keys + assert "sherlock-search" in keys + assert "legacy-sherlock" in keys + assert "meshrush" in keys assert "cloudshell-fog" in keys assert "agentplane" in keys assert "policy-fabric" in keys - assert "sherlock-search" in keys - assert "legacy-sherlock" in keys + + +def test_authority_boundaries_are_explicit(): + sociosphere = get_plane("sociosphere") + workspace = get_plane("prophet-workspace") + new_hope = get_plane("new-hope") + holmes = get_plane("holmes") + sherlock = get_plane("sherlock-search") + + assert "meta-workspace controller" in sociosphere.role + assert "workroom" in workspace.role.lower() + assert "semantic runtime" in new_hope.role.lower() + assert "language intelligence fabric" in holmes.role.lower() + assert "retrieval/search-packet" in sherlock.role def test_sherlock_search_is_preferred_surface(): @@ -28,15 +49,29 @@ def test_side_effecting_capabilities_require_approval(): for capability in plane.capabilities: if capability.name in { "room_event_emit", + "materialize_workspace", + "hydrate_workspace_context", + "apply_topic_membrane", + "recall_context", + "write_memory", + "extract_claims", + "apply_semantic_membrane", + "open_casefile", + "investigate", + "synthesize_findings", + "run_evals", + "create_search_packet", + "hydrate_context_pack", + "username_lookup", + "enter_graph_view", + "diffuse_graph", + "crystallize_artifact", "request_shell_session", "attach_pty", "select_executor", "run_bundle", "replay_run", "approve_action", - "create_search_packet", - "hydrate_context_pack", - "username_lookup", }: side_effecting.append((plane.key, capability.name, capability.requires_approval)) From 1a58ec3838bd661c65c0cd10fa9d1fa13ce350ab Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:39:47 -0400 Subject: [PATCH 20/40] Expand adapter targets across SourceOS planes --- src/agent_term/adapters.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/agent_term/adapters.py b/src/agent_term/adapters.py index cb90164..a0356c1 100644 --- a/src/agent_term/adapters.py +++ b/src/agent_term/adapters.py @@ -1,8 +1,9 @@ """Adapter contracts for AgentTerm participants. -Adapters translate between AgentTerm events and concrete systems: Matrix rooms, Hermes, -Codex, Claude Code, OpenCLAW, AgentPlane, Policy Fabric, Sherlock Search, cloudshell-fog, -GitHub, CI, MCP, and local process agents. +Adapters translate between AgentTerm events and concrete systems: Matrix rooms, +Sociosphere, Prophet Workspace, Slash Topics, Memory Mesh, New Hope, Holmes, +Sherlock Search, MeshRush, cloudshell-fog, AgentPlane, Policy Fabric, Hermes, +Codex, Claude Code, OpenCLAW, GitHub, CI, MCP, and local process agents. This file intentionally avoids vendor SDK dependencies. Real network adapters should live behind this small contract so the terminal UI, local event log, and policy boundary remain stable. @@ -90,16 +91,23 @@ def handle(self, event: AgentTermEvent) -> AdapterResult: ADAPTER_TARGETS = { - "matrix": "Canonical room/event transport adapter; must preserve room IDs, event IDs, redactions, membership, bridge metadata, and E2EE posture.", + "matrix": "Canonical room/event transport adapter; preserve room IDs, event IDs, redactions, membership, bridge metadata, and E2EE posture.", + "sociosphere": "Meta-workspace controller adapter for manifest, lock, topology, governance registry, and validation-lane events.", + "prophet-workspace": "Professional Workrooms and workspace product adapter for workroom binding, policy-aware UX, admin, audit, and search surfaces.", + "slash-topics": "Governed topic-scope adapter for signed topic packs, policy membranes, and deterministic receipts.", + "memory-mesh": "Governed memory/context adapter for recall, writeback, context packs, LiteLLM hooks, and OpenCLAW memory tools.", + "new-hope": "Semantic runtime adapter for messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events.", + "holmes": "Language-intelligence fabric adapter for casefiles, retrieval, semantic graphs, synthesis, guardrails, and evals.", + "sherlock-search": "Preferred Sherlock integration for scoped search packets and context hydration.", + "legacy-sherlock": "High-friction policy-gated OSINT wrapper only; never a default ambient tool.", + "meshrush": "Graph-operating runtime adapter for graph views, diffusion, crystallization, traces, and graph evidence.", + "cloudshell-fog": "Fog-first shell/session substrate; AgentTerm requests sessions but does not bypass OIDC, placement, TTL, or audit.", + "agentplane": "Execution authority for bundle validation, placement, runs, replay, and evidence artifacts.", + "policy-fabric": "Policy decision and evidence authority for side-effecting commands and sensitive context release.", "hermes": "Personal/multi-channel agent gateway participant; may bridge external chat surfaces into Matrix-backed AgentTerm rooms.", "codex": "Code-writing participant; must operate through repo branches, diffs, PRs, and approval-gated shell/test commands.", "claude-code": "Codebase reasoning and patch participant; must emit plan, diff, command, and evidence events.", "openclaw": "Local/open agent runtime participant; must run inside SourceOS capability and policy envelopes.", - "cloudshell-fog": "Fog-first shell/session substrate; AgentTerm requests sessions but does not bypass OIDC, placement, TTL, or audit.", - "agentplane": "Execution authority for bundle validation, placement, runs, replay, and evidence artifacts.", - "policy-fabric": "Policy decision and evidence authority for side-effecting commands and sensitive context release.", - "sherlock-search": "Preferred Sherlock integration for scoped search packets and context hydration.", - "legacy-sherlock": "High-friction policy-gated OSINT wrapper only; never a default ambient tool.", "github": "Issue, PR, review, check, and branch event integration.", "ci": "Workflow status/log/retry integration with explicit retry approval gates.", "mcp": "Tool-plane adapter for files, docs, search, memory, calendar, and other governed capabilities.", From 16d7265bc0c9b6359700fd0b2559238e90cbd328 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:41:24 -0400 Subject: [PATCH 21/40] Add generic SourceOS plane event command and shell shortcuts --- src/agent_term/cli.py | 233 ++++++++++++++++++++++++++++++++---------- 1 file changed, 181 insertions(+), 52 deletions(-) diff --git a/src/agent_term/cli.py b/src/agent_term/cli.py index e72f247..71d9894 100644 --- a/src/agent_term/cli.py +++ b/src/agent_term/cli.py @@ -15,6 +15,7 @@ DEFAULT_CHANNEL = "!sourceos-ops" +APPROVAL_NEXT_AUTHORITY = "policy-fabric" def build_parser() -> argparse.ArgumentParser: @@ -41,6 +42,19 @@ def build_parser() -> argparse.ArgumentParser: post.add_argument("--thread-id") post.add_argument("--metadata-json", default="{}") + record = subparsers.add_parser( + "record", + help="Record a typed SourceOS plane event without invoking a network adapter.", + ) + record.add_argument("plane", help="Registered plane key, e.g. memory-mesh or new-hope.") + record.add_argument("kind", help="Event kind, e.g. workroom, topic_scope, memory_recall.") + record.add_argument("channel") + record.add_argument("body") + record.add_argument("--sender", default="@operator") + record.add_argument("--thread-id") + record.add_argument("--requires-approval", action="store_true") + record.add_argument("--metadata-json", default="{}") + tail = subparsers.add_parser("tail", help="Show recent events.") tail.add_argument("channel", nargs="?") tail.add_argument("--limit", type=int, default=25) @@ -71,6 +85,7 @@ def build_parser() -> argparse.ArgumentParser: sherlock_packet.add_argument("--sender", default="@operator") sherlock_packet.add_argument("--workroom", default="default") sherlock_packet.add_argument("--scope", default="workroom") + sherlock_packet.add_argument("--topic") sherlock_packet.add_argument("--thread-id") subparsers.add_parser("shell", help="Open the minimal AgentTerm interactive shell.") @@ -96,6 +111,45 @@ def format_event(event: AgentTermEvent) -> str: ) +def append_and_print(store: EventStore, event: AgentTermEvent) -> int: + store.append(event) + print(format_event(event)) + if event.metadata.get("approval_required"): + print("status: pending Policy Fabric approval before side effects or sensitive context release") + return 0 + + +def make_plane_event( + *, + plane: str, + kind: str, + channel: str, + sender: str, + body: str, + thread_id: str | None = None, + metadata: dict[str, Any] | None = None, + approval_required: bool = False, +) -> AgentTermEvent: + get_plane(plane) + merged_metadata: dict[str, Any] = { + "plane": plane, + "approval_required": approval_required, + } + if approval_required: + merged_metadata["next_authority"] = APPROVAL_NEXT_AUTHORITY + if metadata: + merged_metadata.update(metadata) + return AgentTermEvent( + channel=channel, + sender=sender, + kind=kind, + source=plane, + body=body, + thread_id=thread_id, + metadata=merged_metadata, + ) + + def cmd_init(store: EventStore) -> int: event = AgentTermEvent( channel=DEFAULT_CHANNEL, @@ -119,9 +173,21 @@ def cmd_post(store: EventStore, args: argparse.Namespace) -> int: thread_id=args.thread_id, metadata=parse_metadata(args.metadata_json), ) - store.append(event) - print(format_event(event)) - return 0 + return append_and_print(store, event) + + +def cmd_record(store: EventStore, args: argparse.Namespace) -> int: + event = make_plane_event( + plane=args.plane, + kind=args.kind, + channel=args.channel, + sender=args.sender, + body=args.body, + thread_id=args.thread_id, + metadata=parse_metadata(args.metadata_json), + approval_required=args.requires_approval, + ) + return append_and_print(store, event) def cmd_tail(store: EventStore, args: argparse.Namespace) -> int: @@ -159,51 +225,42 @@ def cmd_planes(args: argparse.Namespace) -> int: def cmd_request_shell(store: EventStore, args: argparse.Namespace) -> int: metadata = { - "plane": "cloudshell-fog", "profile": args.profile, "ttl_seconds": args.ttl_seconds, "placement_hint": args.placement_hint, - "approval_required": True, - "next_authority": "policy-fabric", } - event = AgentTermEvent( + event = make_plane_event( + plane="cloudshell-fog", + kind="shell_session", channel=args.channel, sender=args.sender, - kind="shell_session", - source="cloudshell-fog", body=f"Request cloudshell-fog session profile={args.profile} placement={args.placement_hint}", thread_id=args.thread_id, metadata=metadata, + approval_required=True, ) - store.append(event) - print(format_event(event)) - print("status: pending Policy Fabric approval before shell attach") - return 0 + return append_and_print(store, event) def cmd_sherlock_packet(store: EventStore, args: argparse.Namespace) -> int: metadata = { - "plane": "sherlock-search", "query": args.query, "workroom": args.workroom, "scope": args.scope, - "approval_required": True, - "next_authority": "policy-fabric", + "topic": args.topic, "preferred_repo": "SocioProphet/sherlock-search", } - event = AgentTermEvent( + event = make_plane_event( + plane="sherlock-search", + kind="search_packet", channel=args.channel, sender=args.sender, - kind="search_packet", - source="sherlock-search", body=f"Request Sherlock search packet workroom={args.workroom} scope={args.scope}: {args.query}", thread_id=args.thread_id, metadata=metadata, + approval_required=True, ) - store.append(event) - print(format_event(event)) - print("status: pending Policy Fabric approval before context hydration or legacy OSINT tools") - return 0 + return append_and_print(store, event) def cmd_shell(store: EventStore) -> int: @@ -225,8 +282,14 @@ def cmd_shell(store: EventStore) -> int: print("/sender ") print("/tail [limit]") print("/planes") - print("/request-shell [profile]") + print("/workroom ") + print("/topic ") + print("/memory ") + print("/newhope ") + print("/holmes ") print("/sherlock ") + print("/meshrush ") + print("/request-shell [profile]") print("/quit") print("Anything else is posted as a message event.") continue @@ -246,47 +309,111 @@ def cmd_shell(store: EventStore) -> int: for plane in iter_planes(): print(f"{plane.key}\t{plane.display_name}\t{plane.repository}") continue - if line.startswith("/request-shell"): - parts = shlex.split(line) - profile = parts[1] if len(parts) > 1 else "default" - event = AgentTermEvent( + if line.startswith("/workroom "): + ref = line.split(maxsplit=1)[1] + event = make_plane_event( + plane="prophet-workspace", + kind="workroom", channel=channel, sender=sender, - kind="shell_session", - source="cloudshell-fog", - body=f"Request cloudshell-fog session profile={profile}", - metadata={ - "plane": "cloudshell-fog", - "profile": profile, - "approval_required": True, - "next_authority": "policy-fabric", - }, + body=f"Bind AgentTerm thread to Professional Workroom: {ref}", + metadata={"workroom": ref}, ) - store.append(event) - print(format_event(event)) + append_and_print(store, event) continue - if line.startswith("/sherlock "): + if line.startswith("/topic "): + scope = line.split(maxsplit=1)[1] + event = make_plane_event( + plane="slash-topics", + kind="topic_scope", + channel=channel, + sender=sender, + body=f"Select slash-topic scope: {scope}", + metadata={"topic_scope": scope}, + ) + append_and_print(store, event) + continue + if line.startswith("/memory "): query = line.split(maxsplit=1)[1] - event = AgentTermEvent( + event = make_plane_event( + plane="memory-mesh", + kind="memory_recall", channel=channel, sender=sender, + body=f"Request governed Memory Mesh recall: {query}", + metadata={"query": query}, + approval_required=True, + ) + append_and_print(store, event) + continue + if line.startswith("/newhope "): + ref = line.split(maxsplit=1)[1] + event = make_plane_event( + plane="new-hope", + kind="semantic_thread", + channel=channel, + sender=sender, + body=f"Normalize semantic thread/message object: {ref}", + metadata={"semantic_ref": ref}, + ) + append_and_print(store, event) + continue + if line.startswith("/holmes "): + request = line.split(maxsplit=1)[1] + event = make_plane_event( + plane="holmes", + kind="investigation", + channel=channel, + sender=sender, + body=f"Request Holmes investigation: {request}", + metadata={"request": request}, + approval_required=True, + ) + append_and_print(store, event) + continue + if line.startswith("/sherlock "): + query = line.split(maxsplit=1)[1] + event = make_plane_event( + plane="sherlock-search", kind="search_packet", - source="sherlock-search", + channel=channel, + sender=sender, body=f"Request Sherlock search packet: {query}", - metadata={ - "plane": "sherlock-search", - "query": query, - "approval_required": True, - "next_authority": "policy-fabric", - }, + metadata={"query": query}, + approval_required=True, + ) + append_and_print(store, event) + continue + if line.startswith("/meshrush "): + request = line.split(maxsplit=1)[1] + event = make_plane_event( + plane="meshrush", + kind="graph_view", + channel=channel, + sender=sender, + body=f"Request MeshRush graph view: {request}", + metadata={"request": request}, + approval_required=True, + ) + append_and_print(store, event) + continue + if line.startswith("/request-shell"): + parts = shlex.split(line) + profile = parts[1] if len(parts) > 1 else "default" + event = make_plane_event( + plane="cloudshell-fog", + kind="shell_session", + channel=channel, + sender=sender, + body=f"Request cloudshell-fog session profile={profile}", + metadata={"profile": profile}, + approval_required=True, ) - store.append(event) - print(format_event(event)) + append_and_print(store, event) continue event = AgentTermEvent(channel=channel, sender=sender, kind="message", source="local", body=line) - store.append(event) - print(format_event(event)) + append_and_print(store, event) def main(argv: list[str] | None = None) -> int: @@ -303,6 +430,8 @@ def main(argv: list[str] | None = None) -> int: return cmd_init(store) if args.command == "post": return cmd_post(store, args) + if args.command == "record": + return cmd_record(store, args) if args.command == "tail": return cmd_tail(store, args) if args.command == "request-shell": From 354505e2be675ebf53c658060762f570bb4bffd5 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:43:44 -0400 Subject: [PATCH 22/40] Expand example config for full SourceOS plane topology --- configs/agent-term.example.json | 80 +++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/configs/agent-term.example.json b/configs/agent-term.example.json index b88b5b3..77d57b8 100644 --- a/configs/agent-term.example.json +++ b/configs/agent-term.example.json @@ -13,9 +13,17 @@ "rooms": { "sourceosOps": "!sourceos-ops:example.org", "sourceosBuild": "!sourceos-build:example.org", + "sociosphere": "!sociosphere:example.org", + "prophetWorkspace": "!prophet-workspace:example.org", + "slashTopics": "!slash-topics:example.org", + "memoryMesh": "!memory-mesh:example.org", + "newHope": "!new-hope:example.org", + "holmes": "!holmes:example.org", + "sherlockSearch": "!sherlock-search:example.org", + "meshrush": "!meshrush:example.org", "agentplane": "!agentplane:example.org", "policyFabric": "!policyfabric:example.org", - "sherlockSearch": "!sherlock-search:example.org", + "cloudshellFog": "!cloudshell-fog:example.org", "ciFailures": "!ci-failures:example.org" }, "requireEncryptedRoomPostureForSensitiveContext": true, @@ -24,6 +32,63 @@ "preserveMembershipEvents": true }, "planes": { + "sociosphere": { + "enabled": true, + "repository": "SocioProphet/sociosphere", + "role": "meta-workspace-controller", + "requirePolicyApprovalForMaterialization": true + }, + "prophetWorkspace": { + "enabled": true, + "repository": "SocioProphet/prophet-workspace", + "role": "professional-workrooms-and-workspace-product-surface", + "requirePolicyApprovalForContextHydration": true + }, + "slashTopics": { + "enabled": true, + "repository": "SocioProphet/slash-topics", + "role": "governed-topic-scopes-and-policy-membranes", + "requirePolicyApprovalForMembraneApplication": true + }, + "memoryMesh": { + "enabled": true, + "repository": "SocioProphet/memory-mesh", + "role": "governed-recall-writeback-and-context-packs", + "requirePolicyApprovalForRecall": true, + "requirePolicyApprovalForWriteback": true + }, + "newHope": { + "enabled": true, + "repository": "SocioProphet/new-hope", + "role": "semantic-runtime-for-message-thread-claim-citation-membrane-objects", + "requirePolicyApprovalForSemanticMembranes": true + }, + "holmes": { + "enabled": true, + "repository": "SocioProphet/holmes", + "role": "language-intelligence-fabric-for-investigation-casefiles-retrieval-evals-and-guardrails", + "requirePolicyApprovalForInvestigation": true + }, + "sherlockSearch": { + "enabled": true, + "repository": "SocioProphet/sherlock-search", + "preferred": true, + "role": "retrieval-search-packets-and-evidence-search", + "requirePolicyApprovalForHydration": true + }, + "legacySherlock": { + "enabled": false, + "repository": "SocioProphet/sherlock", + "ambientToolAccess": false, + "requireExplicitAuthorization": true, + "requirePolicyApproval": true + }, + "meshrush": { + "enabled": true, + "repository": "SocioProphet/meshrush", + "role": "graph-native-agent-runtime-for-graph-views-diffusion-and-crystallization", + "requirePolicyApprovalForGraphOperations": true + }, "cloudshellFog": { "enabled": true, "repository": "SocioProphet/cloudshell-fog", @@ -50,19 +115,6 @@ "repository": "SocioProphet/policy-fabric", "decisionMode": "admit-before-side-effect", "recordDenialsAsEvents": true - }, - "sherlockSearch": { - "enabled": true, - "repository": "SocioProphet/sherlock-search", - "preferred": true, - "requirePolicyApprovalForHydration": true - }, - "legacySherlock": { - "enabled": false, - "repository": "SocioProphet/sherlock", - "ambientToolAccess": false, - "requireExplicitAuthorization": true, - "requirePolicyApproval": true } }, "participants": { From c41cd633b48f03e0a6214ca42d0f3ae35bc8de15 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:44:27 -0400 Subject: [PATCH 23/40] Update README for full SourceOS control surface --- README.md | 86 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index ce73377..c68f52c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AgentTerm -AgentTerm is a terminal-native ChatOps console for coordinating human operators, Matrix rooms, LLM agents, GitHub bots, CI systems, MCP tools, cloudshell-fog sessions, AgentPlane runs, Policy Fabric decisions, Sherlock search packets, and local SourceOS services from one channel/thread workspace. +AgentTerm is a terminal-native ChatOps console for coordinating human operators, Matrix rooms, LLM agents, GitHub bots, CI systems, MCP tools, Sociosphere workspace materialization, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh context, New Hope semantic threads, Holmes investigations, Sherlock search packets, MeshRush graph operations, cloudshell-fog sessions, AgentPlane runs, Policy Fabric decisions, and local SourceOS services from one channel/thread workspace. The design target is not another single-agent CLI. AgentTerm is the Slack-term class interface for agent operations: rooms, channels, threads, slash commands, approvals, event logs, adapters, and terminal-first operator flow. For SourceOS, Matrix is the canonical network ChatOps substrate. Slack and Discord should be treated as bridge targets, not the source of truth. @@ -9,9 +9,9 @@ The design target is not another single-agent CLI. AgentTerm is the Slack-term c - A Python CLI package named `agent-term`. - A local SQLite event log for durable operator history. - A minimal interactive shell for immediate use. -- First-class SourceOS plane registry for Matrix, cloudshell-fog, AgentPlane, Policy Fabric, Sherlock Search, legacy Sherlock, GitHub, CI, MCP, Hermes, Codex, Claude Code, and OpenCLAW. -- Adapter contracts for Matrix and process-backed participants. -- Governance-preserving command shapes for shell-session and Sherlock search-packet requests. +- A first-class SourceOS plane registry for Matrix, Sociosphere, Prophet Workspace, Slash Topics, Memory Mesh, New Hope, Holmes, Sherlock Search, legacy Sherlock, MeshRush, cloudshell-fog, AgentPlane, Policy Fabric, GitHub, CI, MCP, Hermes, Codex, Claude Code, and OpenCLAW. +- Adapter contracts for Matrix, SourceOS planes, and process-backed participants. +- Governance-preserving command shapes for workroom, topic, memory, semantic-thread, investigation, search-packet, graph-view, and shell-session requests. - Configuration examples, tests, CI, and operating-model docs for building AgentTerm into the SourceOS operator console. ## Core concept @@ -19,13 +19,18 @@ The design target is not another single-agent CLI. AgentTerm is the Slack-term c ```text ┌──────────────────────────┬─────────────────────────────────────────────┐ │ Matrix Rooms / Channels │ Thread / Conversation │ -│ !sourceos-build │ @codex: opened branch fix-ci-gate │ +│ !prophet-workspace │ @operator: /workroom pi-demo │ +│ !slash-topics │ @operator: /topic professional-intelligence │ +│ !memory-mesh │ @operator: /memory recall workroom context │ +│ !new-hope │ @agent-term: semantic thread normalized │ +│ !holmes │ @operator: /holmes investigate evidence gap │ +│ !sherlock-search │ @operator: /sherlock scoped search packet │ +│ !meshrush │ @operator: /meshrush enter graph view │ │ !agentplane │ @claude-code: proposes patch plan │ │ !policyfabric │ @github: PR #42 checks failing │ -│ !sherlock-search │ @operator: /sherlock scoped context packet │ -│ !ci-failures │ @operator: /approve retry │ +│ !cloudshell-fog │ @operator: /request-shell default │ ├──────────────────────────┴─────────────────────────────────────────────┤ -│ /ask claude-code ... /assign codex ... /run ci /approve /summarize │ +│ /workroom /topic /memory /newhope /holmes /sherlock /meshrush │ └────────────────────────────────────────────────────────────────────────┘ ``` @@ -35,13 +40,20 @@ AgentTerm treats every meaningful action as an event: - slash commands - agent replies - Matrix room events, redactions, membership changes, and bridge events +- Sociosphere workspace manifest, lock, topology, and validation events +- Prophet Workspace workroom, audit, policy-aware UX, and receipt events +- Slash Topics topic-scope, policy-membrane, and receipt events +- Memory Mesh recall, writeback, and context-pack events +- New Hope message, thread, claim, citation, receptor, membrane, and moderation events +- Holmes casefile, investigation, synthesis, guardrail, and eval events +- Sherlock Search search-packet and context-hydration events +- MeshRush graph-view, diffusion, crystallization, trace, and graph-evidence events - GitHub issue and PR updates - CI status transitions - MCP tool calls - Policy Fabric decisions - AgentPlane validation, placement, run, replay, and evidence artifacts - cloudshell-fog session and shell-attach events -- Sherlock search-packet and context-hydration events - handoffs between agents The event log is the control plane. The terminal UI is only the operator surface. @@ -60,6 +72,27 @@ Initial Matrix requirements: - support encrypted-room posture checks before agents receive sensitive context - keep bridge metadata when Matrix rooms bridge to Slack, Discord, GitHub, or CI systems +## Authority split + +AgentTerm should not collapse the SourceOS stack into one generic search agent. + +| Plane | Authority | +| --- | --- | +| Sociosphere | Meta-workspace controller, canonical workspace manifest, lock, topology, governance registry, validation lanes | +| Prophet Workspace | Workspace product semantics, Professional Workrooms, mail/calendar/drive/docs/chat/meeting surfaces, policy-aware UX | +| Slash Topics | Governed signed topic scopes, policy membranes, search/knowledge scoping, replayable receipts | +| Memory Mesh | Governed recall, writeback, context packs, memoryd runtime, LiteLLM/OpenCLAW memory integrations | +| New Hope | Semantic runtime for messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events | +| Holmes | Language intelligence fabric for casefiles, retrieval, semantic graphs, investigation, synthesis, guardrails, and evals | +| Sherlock Search | Discovery/search-packet surface and retrieval evidence engine | +| Legacy Sherlock | Explicitly authorized, policy-gated username/social-network OSINT only | +| MeshRush | Graph-native autonomous-agent runtime over typed hypergraph world-model views | +| cloudshell-fog | Governed fog/cloud shell session placement, OIDC, TTL, PTY attach, and audit | +| AgentPlane | Validated bundle execution, executor placement, run/replay artifacts, and evidence | +| Policy Fabric | Policy decision/evidence authority for side effects and sensitive context release | + +New Hope is not “handled by” Sherlock or Holmes. Holmes investigates, Sherlock retrieves, and New Hope normalizes the semantic commons objects they operate over. + ## MVP commands After cloning locally: @@ -70,34 +103,21 @@ source .venv/bin/activate pip install -e '.[dev]' agent-term init agent-term planes list -agent-term planes show cloudshell-fog +agent-term planes show new-hope agent-term post '!sourceos-build' '@operator' 'AgentTerm is online.' -agent-term request-shell '!sourceos-build' default --thread-id demo-shell -agent-term sherlock-packet '!sherlock-search' 'hydrate AgentTerm workroom context' --workroom agent-term --thread-id demo-search +agent-term record prophet-workspace workroom '!prophet-workspace' 'Bind PI demo workroom' --metadata-json '{"workroom":"pi-demo"}' +agent-term record slash-topics topic_scope '!slash-topics' 'Select /professional-intelligence topic scope' +agent-term record memory-mesh memory_recall '!memory-mesh' 'Recall workroom context' --requires-approval +agent-term record new-hope semantic_thread '!new-hope' 'Normalize Matrix thread into New Hope objects' +agent-term record holmes investigation '!holmes' 'Investigate evidence gap' --requires-approval +agent-term sherlock-packet '!sherlock-search' 'hydrate AgentTerm workroom context' --workroom agent-term --topic professional-intelligence --thread-id demo-search +agent-term record meshrush graph_view '!meshrush' 'Enter professional intelligence graph view' --requires-approval +agent-term request-shell '!cloudshell-fog' default --thread-id demo-shell agent-term tail agent-term shell ``` -The first implementation stores events in SQLite and records governance-preserving events locally. Matrix network I/O, cloudshell-fog session attach, AgentPlane bundle execution, Policy Fabric admission, and Sherlock Search hydration are intentionally isolated behind adapter boundaries so the terminal, policy, event log, and agent registry can be hardened independently. - -## First-class SourceOS planes - -| Target | Role | -| --- | --- | -| Matrix | Canonical ChatOps transport and room substrate | -| cloudshell-fog | Fog-first shell/session substrate; AgentTerm requests sessions but does not bypass OIDC, placement, TTL, or audit | -| AgentPlane | Execution authority for bundle validation, placement, runs, replay, and evidence artifacts | -| Policy Fabric | Policy decision and evidence authority for side-effecting commands and sensitive context release | -| Sherlock Search | Preferred Sherlock integration for scoped search packets and context hydration | -| Legacy Sherlock | High-friction policy-gated OSINT wrapper only; never a default ambient tool | -| Hermes | Personal/multi-channel agent gateway participant | -| Codex | Code-writing participant under branch/PR/evidence gates | -| Claude Code | Codebase reasoning and patch participant under branch/PR/evidence gates | -| OpenCLAW | Local/open agent runtime inside SourceOS policy envelopes | -| GitHub | Issues, PRs, reviews, checks, branch events | -| CI | Workflow status, logs, retry/approve gates | -| MCP | Tool plane for files, docs, search, memory, calendar, etc. | -| Local process | Escape hatch for any CLI-driven agent or bot | +The first implementation stores events in SQLite and records governance-preserving events locally. Matrix network I/O, Sociosphere materialization, Prophet Workspace workroom APIs, Slash Topics membranes, Memory Mesh recall/writeback, New Hope semantic normalization, Holmes investigation, Sherlock Search hydration, MeshRush graph execution, cloudshell-fog session attach, AgentPlane bundle execution, and Policy Fabric admission are intentionally isolated behind adapter boundaries so the terminal, policy, event log, and registry can be hardened independently. ## Docs @@ -107,4 +127,4 @@ The first implementation stores events in SQLite and records governance-preservi ## Repository status -This is the seed implementation. It is intentionally small but runnable. The next step is to land the Matrix-room MVP, then bind Policy Fabric admission, cloudshell-fog session lifecycle, Sherlock Search packets, AgentPlane evidence flow, and Hermes/Codex/Claude Code/OpenCLAW participants under explicit operator permissions. +This is the seed implementation. It is intentionally small but runnable. The next step is to land the Matrix-room MVP, then bind Policy Fabric admission, Sociosphere workspace state, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh recall/writeback, New Hope semantic events, Holmes investigations, Sherlock Search packets, MeshRush graph events, cloudshell-fog session lifecycle, AgentPlane evidence flow, and Hermes/Codex/Claude Code/OpenCLAW participants under explicit operator permissions. From edfd26d9e99d8ef2960a4a4d882429874056547f Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:46:36 -0400 Subject: [PATCH 24/40] Expand architecture doc for workspace, semantic, memory, and graph planes --- docs/architecture/sourceos-control-surface.md | 171 +++++++++++++++--- 1 file changed, 141 insertions(+), 30 deletions(-) diff --git a/docs/architecture/sourceos-control-surface.md b/docs/architecture/sourceos-control-surface.md index 4911b5e..d61a858 100644 --- a/docs/architecture/sourceos-control-surface.md +++ b/docs/architecture/sourceos-control-surface.md @@ -1,6 +1,6 @@ # AgentTerm as the SourceOS control surface -AgentTerm is the terminal-native operator surface for the SourceOS multi-agent stack. It does not replace Matrix, cloudshell-fog, AgentPlane, Policy Fabric, Sherlock, GitHub, CI, MCP, Hermes, Codex, Claude Code, or OpenCLAW. It normalizes those systems into an auditable ChatOps event plane with terminal UX. +AgentTerm is the terminal-native operator surface for the SourceOS multi-agent stack. It does not replace Matrix, Sociosphere, Prophet Workspace, Slash Topics, Memory Mesh, New Hope, Holmes, Sherlock Search, MeshRush, cloudshell-fog, AgentPlane, Policy Fabric, GitHub, CI, MCP, Hermes, Codex, Claude Code, or OpenCLAW. It normalizes those systems into an auditable ChatOps event plane with terminal UX. ## Boundary statement @@ -16,10 +16,17 @@ AgentTerm owns: AgentTerm does not own: - Matrix homeserver semantics +- Sociosphere workspace manifest, lock, topology, or governance registry authority +- Prophet Workspace product/workroom semantics +- Slash Topics topic-pack or membrane schema authority +- Memory Mesh recall/writeback runtime authority +- New Hope semantic runtime authority +- Holmes language intelligence, casefile, retrieval, eval, or guardrail authority +- Sherlock Search search-packet schema authority +- MeshRush graph runtime authority - cloudshell-fog placement, OIDC, TTL, or PTY enforcement - AgentPlane bundle execution or replay authority - Policy Fabric policy authoring, validation, packaging, or release authority -- Sherlock search-packet schema authority - legacy Sherlock OSINT behavior - GitHub repository state - CI workflow execution @@ -31,11 +38,18 @@ This keeps AgentTerm as an operator console rather than a new monolith. | Plane | Canonical repo/surface | AgentTerm role | | --- | --- | --- | | Matrix | Matrix homeserver and bridge topology | canonical ChatOps transport for rooms, events, membership, redactions, bridge metadata, and E2EE posture | +| Sociosphere | `SocioProphet/sociosphere` | meta-workspace controller for manifests, locks, topology, governance registry, validation lanes, and release-readiness orchestration | +| Prophet Workspace | `SocioProphet/prophet-workspace` | Professional Workrooms and workspace product surface for policy-aware workrooms, audit, receipts, and user-facing collaboration surfaces | +| Slash Topics | `SocioProphet/slash-topics` | governed, signed, replayable topic scopes and policy membranes for search/knowledge operations | +| Memory Mesh | `SocioProphet/memory-mesh` | governed recall, writeback, context packs, memoryd runtime, and memory adapters | +| New Hope | `SocioProphet/new-hope` | higher-order semantic runtime for messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events | +| Holmes | `SocioProphet/holmes` | language intelligence fabric for casefiles, retrieval, semantic graphs, synthesis, guardrails, evals, and investigative discovery | +| Sherlock Search | `SocioProphet/sherlock-search` | preferred Sherlock integration for search packets and workroom-scoped retrieval context | +| Legacy Sherlock | `SocioProphet/sherlock` | high-friction, policy-gated OSINT adapter only | +| MeshRush | `SocioProphet/meshrush` | graph-native agent runtime for graph views, diffusion, crystallization, traces, and graph evidence | | cloudshell-fog | `SocioProphet/cloudshell-fog` | fog-first secure shell/session substrate for governed terminal and browser shells | | AgentPlane | `SocioProphet/agentplane` | execution authority for validate/place/run/evidence/replay flows | | Policy Fabric | `SocioProphet/policy-fabric` | policy decision point for command dispatch, sensitive context release, and evidence capture | -| Sherlock Search | `SocioProphet/sherlock-search` | preferred Sherlock integration for search packets and workroom-scoped retrieval context | -| Legacy Sherlock | `SocioProphet/sherlock` | high-friction, policy-gated OSINT adapter only | | GitHub | GitHub app/CLI/API | issue, PR, branch, review, and check state | | CI | GitHub Actions and other runners | workflow status, logs, artifacts, retry gates | | MCP | MCP servers/tools | governed capability plane for external tools and context sources | @@ -49,14 +63,114 @@ This keeps AgentTerm as an operator console rather than a new monolith. ```text Matrix room event or local terminal command -> AgentTerm normalized event + -> Slash Topics scope and New Hope semantic normalization, when applicable -> Policy Fabric decision point -> Adapter dispatch - -> cloudshell-fog / AgentPlane / Sherlock / GitHub / CI / MCP / agent runtime + -> Sociosphere / Prophet Workspace / Memory Mesh / Holmes / Sherlock Search / MeshRush + / cloudshell-fog / AgentPlane / GitHub / CI / MCP / agent runtime -> evidence event -> Matrix room and local event log ``` -Side-effecting operations must pass through a decision event before execution. Examples include shell attach, repo mutation, CI retry, search-packet hydration with sensitive context, legacy Sherlock OSINT lookup, and AgentPlane bundle execution. +Side-effecting operations must pass through a decision event before execution. Examples include workspace materialization, sensitive workroom context hydration, memory recall/writeback, semantic membrane application, Holmes investigation, search-packet hydration, graph diffusion/crystallization, shell attach, repo mutation, CI retry, legacy Sherlock OSINT lookup, and AgentPlane bundle execution. + +## Workspace and workroom integration + +Sociosphere and Prophet Workspace are separate authorities: + +- Sociosphere owns canonical multi-repo workspace state: manifest, lock, topology, governance registry, validation lanes, and release readiness. +- Prophet Workspace owns product semantics: Professional Workrooms, workspace capabilities, policy-aware UX, audit, receipts, and collaboration surfaces. + +AgentTerm should bind Matrix rooms and local terminal threads to Professional Workrooms when available, but use Sociosphere when the operator needs workspace materialization, topology, repo roles, or governance status. + +Minimum workroom event metadata: + +- workroom ID or alias +- Matrix room ID and thread/root event +- operator identity +- Slash Topics scope, when selected +- Policy Fabric decision reference for context release +- Memory Mesh context-pack reference, when hydrated +- Sherlock Search packet reference, when retrieval is requested +- Holmes casefile reference, when investigation begins +- AgentPlane bundle/evidence reference, when execution occurs + +## Slash Topics integration + +Slash Topics supplies governed scopes for knowledge and search surfaces. AgentTerm slash commands should preserve: + +- topic-pack ID +- signature or validation state +- policy membrane decision +- room/thread/workroom binding +- deterministic receipt reference +- downstream search, memory, Holmes, Sherlock, or New Hope correlation IDs + +Topic scopes should constrain Memory Mesh recall, Sherlock Search packets, Holmes investigations, New Hope semantic routing, and MeshRush graph view selection. + +## Memory Mesh integration + +Memory Mesh should supply governed recall and writeback. AgentTerm should not treat memory as generic hidden prompt history. + +Minimum memory event metadata: + +- recall or writeback operation +- workroom/thread binding +- topic scope +- policy decision reference +- memory entry IDs or context-pack ID +- source/evidence/provenance references +- downstream agent or investigation recipient + +## New Hope integration + +New Hope is not covered by Sherlock or Holmes. It is the semantic runtime underneath message/thread/claim/citation operations. + +AgentTerm should use New Hope to normalize operator and agent conversations into semantic commons objects before routing to investigation, retrieval, ranking, moderation, or graph operations. + +Minimum New Hope event metadata: + +- source Matrix event/thread/workroom reference +- Message/Thread/Claim/Citation/Entity/Lens/ModerationEvent IDs, when available +- receptor/membrane decision reference +- provenance and replay references +- ranking/moderation output, when applicable + +## Holmes and Sherlock integration + +Holmes and Sherlock Search are complementary: + +- Holmes is the language-intelligence fabric for casefiles, retrieval, semantic graphs, synthesis, guardrails, evals, and investigative discovery. +- Sherlock Search is the discovery/search-packet surface and retrieval-evidence engine. +- Legacy Sherlock is an explicitly authorized, policy-gated OSINT adapter only. + +Preferred investigation path: + +```text +/operator asks for investigation or retrieval + -> AgentTerm binds workroom/topic/thread + -> New Hope normalizes semantic thread objects + -> Policy Fabric evaluates context release and action scope + -> Sherlock Search creates/validates search packet + -> Memory Mesh hydrates approved context pack + -> Holmes opens casefile or investigation workflow + -> AgentTerm records findings, claims, citations, provenance, and evidence +``` + +## MeshRush integration + +MeshRush is the graph-operating runtime. It does not replace the workspace controller, execution control plane, or learning/evaluation plane. + +AgentTerm should expose graph operations as visible events: + +- graph view selection +- diffusion/exploration request +- stop/crystallization decision +- graph artifact persistence +- trace/evidence emission +- downstream AgentPlane or Holmes handoff + +Graph operations should carry provenance, reversibility, policy decision, and workroom/topic/memory bindings. ## Cloud-fog shell integration @@ -98,6 +212,13 @@ Minimum policy hooks: - command admission - capability admission - context-release admission +- workroom context admission +- topic membrane admission +- memory recall/writeback admission +- semantic membrane admission +- investigation admission +- search-packet hydration admission +- graph-operation admission - shell-session admission - legacy OSINT admission - GitHub mutation admission @@ -106,23 +227,6 @@ Minimum policy hooks: Policy denials must be displayed in-channel with enough metadata for review. -## Sherlock integration - -AgentTerm should prefer `sherlock-search` search packets over direct legacy Sherlock invocation. - -Preferred path: - -```text -/operator asks for investigation or retrieval - -> AgentTerm creates `search_packet` event - -> Policy Fabric evaluates scope - -> sherlock-search validates packet schema - -> retrieval/context hydration happens under workroom/thread scope - -> AgentTerm records provenance and packet ID -``` - -Legacy Sherlock username/social-network lookup is not a default ambient tool. It should require explicit scope, authorization, terms-of-use posture, and audit metadata. - ## Matrix integration Matrix room metadata is security-relevant. AgentTerm should preserve: @@ -141,12 +245,19 @@ Agents should not receive sensitive room history from an encrypted room unless A ## Implementation order 1. Local event log and CLI shell. -2. SourceOS plane registry. +2. Full SourceOS plane registry and CLI shortcuts. 3. Matrix read/write adapter with E2EE posture surfaced. 4. Policy Fabric command-admission stub. -5. cloudshell-fog session request and attach flow. -6. Sherlock Search packet validation and hydration flow. -7. AgentPlane validate/place/run/evidence flow. -8. GitHub/CI bridge events. -9. Hermes, Codex, Claude Code, and OpenCLAW participant adapters. -10. Textual TUI with rooms, threads, events, approvals, and evidence panes. +5. Sociosphere workspace state and topology adapter. +6. Prophet Workspace workroom binding and receipt adapter. +7. Slash Topics scope/membrane adapter. +8. Memory Mesh recall/writeback/context-pack adapter. +9. New Hope semantic-thread/message/claim/citation adapter. +10. Sherlock Search packet validation and hydration flow. +11. Holmes casefile/investigation/synthesis/eval flow. +12. MeshRush graph-view/diffusion/crystallization flow. +13. cloudshell-fog session request and attach flow. +14. AgentPlane validate/place/run/evidence flow. +15. GitHub/CI bridge events. +16. Hermes, Codex, Claude Code, and OpenCLAW participant adapters. +17. Textual TUI with rooms, threads, events, approvals, workrooms, context, graph, and evidence panes. From 3c2e31ce5766591283d3e3a676d1a00b0a80073f Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:47:07 -0400 Subject: [PATCH 25/40] Expand agent instructions for full SourceOS plane boundaries --- AGENTS.md | 55 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d4b51e2..480a906 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,22 +5,34 @@ AgentTerm is the terminal-native Matrix-first ChatOps console for SourceOS. It i ## Mandatory architecture boundaries - Matrix is the canonical ChatOps transport. Slack and Discord are bridge targets, not the source of truth. -- AgentTerm is the operator surface and normalized event log. It does not own shell placement, bundle execution, policy release, search-packet schemas, or CI execution. +- AgentTerm is the operator surface and normalized event log. It does not own workspace topology, workroom semantics, topic scopes, memory runtime, semantic runtime, investigation runtime, search-packet schemas, graph runtime, shell placement, bundle execution, policy release, or CI execution. +- Sociosphere owns canonical workspace manifests, locks, topology, registry metadata, validation lanes, and release-readiness orchestration. +- Prophet Workspace owns workspace product semantics, Professional Workrooms, workspace app surfaces, policy-aware UX, audit, and receipts. +- Slash Topics owns governed, signed, replayable topic scopes and policy membranes for search/knowledge operations. +- Memory Mesh owns governed recall, writeback, context packs, memoryd runtime, LiteLLM hooks, and OpenCLAW memory tools. +- New Hope owns semantic runtime semantics for messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events. +- Holmes owns language intelligence: casefiles, retrieval, semantic graphs, synthesis, guardrails, evals, and investigative discovery. +- Sherlock Search owns discovery/search-packet and retrieval-evidence surfaces. Legacy Sherlock username/social-network lookup is high-friction and policy-gated only. +- MeshRush owns graph-native autonomous-agent runtime semantics over graph views, diffusion, crystallization, traces, and graph evidence. - cloudshell-fog owns governed shell/session placement, OIDC, TTL, PTY attach, and audit semantics. - AgentPlane owns bundle validation, executor placement, runs, evidence artifacts, and replay. - Policy Fabric owns policy decision/evidence surfaces for side-effecting operations and sensitive context release. -- Sherlock Search is the preferred Sherlock integration path. Legacy Sherlock username/social-network lookup is high-friction and policy-gated only. ## Required invariants 1. Side-effecting commands require an approval path. 2. Sensitive context release requires Policy Fabric admission. 3. Matrix room IDs, event IDs, membership changes, redactions, bridge metadata, and E2EE posture must be preserved when available. -4. AgentPlane evidence artifacts must remain visible in AgentTerm events. -5. cloudshell-fog shell attach must not bypass OIDC, placement, TTL, or audit semantics. -6. Legacy Sherlock OSINT must never become an ambient default tool. -7. Adapter code must be behind narrow contracts; do not hardwire vendor SDKs into the terminal shell. -8. Local event-log data must not be committed. +4. Workroom, topic, memory, semantic-thread, investigation, search-packet, graph, execution, and shell events must remain explicit and auditable. +5. Slash Topics scopes should constrain Memory Mesh recall, Sherlock Search packets, Holmes investigations, New Hope semantic routing, and MeshRush graph view selection. +6. Memory Mesh must not be treated as hidden prompt history; recall/writeback requires explicit event metadata and policy posture. +7. New Hope is not handled by Sherlock or Holmes; it is the semantic commons runtime underneath message/thread/claim/citation operations. +8. Holmes investigates; Sherlock retrieves; New Hope normalizes semantic objects; Memory Mesh supplies governed context; Slash Topics scopes the operation. +9. AgentPlane evidence artifacts must remain visible in AgentTerm events. +10. cloudshell-fog shell attach must not bypass OIDC, placement, TTL, or audit semantics. +11. Legacy Sherlock OSINT must never become an ambient default tool. +12. Adapter code must be behind narrow contracts; do not hardwire vendor SDKs into the terminal shell. +13. Local event-log data must not be committed. ## Development commands @@ -37,9 +49,15 @@ pytest ```bash agent-term init agent-term planes list -agent-term planes show cloudshell-fog +agent-term planes show new-hope +agent-term record prophet-workspace workroom '!prophet-workspace' 'Bind PI demo workroom' --metadata-json '{"workroom":"pi-demo"}' +agent-term record slash-topics topic_scope '!slash-topics' 'Select /professional-intelligence topic scope' +agent-term record memory-mesh memory_recall '!memory-mesh' 'Recall workroom context' --requires-approval +agent-term record new-hope semantic_thread '!new-hope' 'Normalize Matrix thread into semantic commons objects' +agent-term record holmes investigation '!holmes' 'Investigate evidence gap' --requires-approval +agent-term sherlock-packet '!sourceos-intel' 'find workroom context for AgentTerm Sherlock integration' --workroom agent-term --topic professional-intelligence +agent-term record meshrush graph_view '!meshrush' 'Enter professional intelligence graph view' --requires-approval agent-term request-shell '!sourceos-build' default --thread-id demo-shell -agent-term sherlock-packet '!sourceos-intel' 'find workroom context for AgentTerm Sherlock integration' --workroom agent-term agent-term tail ``` @@ -48,9 +66,16 @@ agent-term tail 1. Keep the local event model and SourceOS plane registry stable. 2. Add Matrix adapter read/write with E2EE posture surfaced. 3. Add Policy Fabric command admission stub before side-effecting adapter execution. -4. Add cloudshell-fog session request/attach flow. -5. Add Sherlock Search packet validation/hydration flow. -6. Add AgentPlane validate/place/run/evidence flow. -7. Add GitHub and CI bridge events. -8. Add Hermes, Codex, Claude Code, and OpenCLAW participant adapters. -9. Add richer Textual TUI views for rooms, threads, approvals, and evidence. +4. Add Sociosphere workspace manifest/topology adapter. +5. Add Prophet Workspace workroom binding and receipt adapter. +6. Add Slash Topics topic-pack and membrane adapter. +7. Add Memory Mesh recall/writeback/context-pack adapter. +8. Add New Hope semantic-thread/message/claim/citation adapter. +9. Add Sherlock Search packet validation/hydration flow. +10. Add Holmes casefile/investigation/synthesis/eval flow. +11. Add MeshRush graph-view/diffusion/crystallization flow. +12. Add cloudshell-fog session request/attach flow. +13. Add AgentPlane validate/place/run/evidence flow. +14. Add GitHub and CI bridge events. +15. Add Hermes, Codex, Claude Code, and OpenCLAW participant adapters. +16. Add richer Textual TUI views for rooms, threads, workrooms, topics, memory, semantic objects, investigations, graphs, approvals, and evidence. From b71b8f08abe5d118c92baee9d3a0a65b5774a61f Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:47:39 -0400 Subject: [PATCH 26/40] Add CLI smoke tests for SourceOS plane events --- tests/test_cli.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/test_cli.py diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..f14d474 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,34 @@ +from agent_term.cli import main + + +def test_record_memory_mesh_event(tmp_path, capsys): + db_path = tmp_path / "events.sqlite3" + + exit_code = main( + [ + "--db", + str(db_path), + "record", + "memory-mesh", + "memory_recall", + "!memory-mesh", + "Recall workroom context", + "--requires-approval", + "--metadata-json", + '{"workroom":"pi-demo"}', + ] + ) + + captured = capsys.readouterr() + assert exit_code == 0 + assert "source=memory-mesh" in captured.out + assert "pending Policy Fabric approval" in captured.out + + +def test_planes_show_new_hope(capsys): + exit_code = main(["planes", "show", "new-hope"]) + + captured = capsys.readouterr() + assert exit_code == 0 + assert "New Hope" in captured.out + assert "semantic runtime" in captured.out.lower() From a21618fd70a739bffa79353a4210034d52457efd Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:48:23 -0400 Subject: [PATCH 27/40] Add Holmes integration boundary guardrail --- docs/integration/holmes-boundary.md | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 docs/integration/holmes-boundary.md diff --git a/docs/integration/holmes-boundary.md b/docs/integration/holmes-boundary.md new file mode 100644 index 0000000..fe8527c --- /dev/null +++ b/docs/integration/holmes-boundary.md @@ -0,0 +1,44 @@ +# Holmes integration boundary + +AgentTerm must integrate with Holmes without redefining Holmes. + +Holmes is the SocioProphet language-intelligence fabric. AgentTerm is only the terminal-native ChatOps/operator surface that can display, request, correlate, and audit Holmes-related work. + +## AgentTerm may own + +- terminal commands that request a Holmes investigation or casefile operation +- local event records that reference Holmes work +- Matrix room/thread correlation metadata +- Policy Fabric admission records before sensitive context release or side-effecting investigation actions +- links to Holmes artifacts, casefiles, evals, guardrails, retrieval traces, or synthesis outputs +- operator-visible status and evidence summaries + +## AgentTerm must not own + +- Holmes product semantics +- Holmes service implementation +- Holmes casefile schema authority +- Holmes retrieval, NLP, guardrail, eval, or synthesis internals +- Holmes model-routing policy +- Holmes release/deployment topology +- any migration or refactor inside `SocioProphet/holmes` + +## Integration posture + +Holmes integration in AgentTerm should be conservative until the Holmes repo exposes stable contracts. The current AgentTerm registry entry is only an operator-visible integration placeholder based on the public Holmes product boundary. It should not be treated as a normative Holmes specification. + +## Expected flow + +```text +Matrix room / AgentTerm thread + -> optional Prophet Workspace workroom binding + -> optional Slash Topics scope + -> optional New Hope semantic normalization + -> Policy Fabric admission for sensitive context or side effects + -> Sherlock Search packet or Memory Mesh context pack, when needed + -> Holmes casefile/investigation request + -> Holmes-owned artifacts/status/evidence references + -> AgentTerm event log + Matrix-visible summary +``` + +AgentTerm should call or observe Holmes through adapters once Holmes contracts are stable. Until then, AgentTerm should record governed request events and preserve references rather than simulating Holmes behavior. From 8d60ba3c4c87105a9e56f560c9a7d39dfa06f000 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:48:57 -0400 Subject: [PATCH 28/40] Add Copilot instructions for AgentTerm architecture boundaries --- .github/copilot-instructions.md | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..562f21d --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,53 @@ +# Copilot instructions for SourceOS AgentTerm + +AgentTerm is the Matrix-first terminal ChatOps console for SourceOS. Do not implement it as a generic chatbot wrapper. + +Read these before making changes: + +- `AGENTS.md` +- `docs/architecture/sourceos-control-surface.md` +- `docs/integration/holmes-boundary.md` + +## Architecture guardrails + +- Matrix is the canonical transport. Slack and Discord integrations are bridges. +- AgentTerm owns terminal UX, normalized local events, slash-command parsing, and adapter boundaries. +- Sociosphere owns workspace manifest, lock, topology, registry, validation lanes, and release-readiness orchestration. +- Prophet Workspace owns Professional Workrooms and workspace product semantics. +- Slash Topics owns topic scopes and policy membranes. +- Memory Mesh owns governed recall/writeback and context packs. +- New Hope owns message/thread/claim/citation semantic runtime semantics. +- Holmes must not be redefined here. AgentTerm may only request, display, correlate, and audit Holmes-owned work. +- Sherlock Search owns search packets and retrieval-evidence surfaces. Legacy Sherlock OSINT remains disabled by default and policy-gated. +- MeshRush owns graph-view/diffusion/crystallization semantics. +- cloudshell-fog owns shell placement, OIDC, TTL, PTY attach, and audit. +- AgentPlane owns validation, placement, runs, replay, and evidence artifacts. +- Policy Fabric owns command admission and sensitive context-release decisions. +- Side-effecting operations require explicit approval paths. +- Avoid adding SDK-specific logic directly to `cli.py`. Keep adapters narrow and testable. + +## Validation commands + +```bash +python -m pip install -e '.[dev]' +ruff check . +pytest +``` + +## Current priority order + +1. Matrix adapter with room/event/E2EE posture preservation. +2. Policy Fabric admission stub for side-effecting commands and sensitive context release. +3. Sociosphere workspace state adapter. +4. Prophet Workspace workroom binding and receipt adapter. +5. Slash Topics scope/membrane adapter. +6. Memory Mesh recall/writeback/context-pack adapter. +7. New Hope semantic event adapter. +8. Sherlock Search packet validation/hydration adapter. +9. Holmes request/status/artifact correlation adapter, respecting `docs/integration/holmes-boundary.md`. +10. MeshRush graph operation adapter. +11. cloudshell-fog session lifecycle adapter. +12. AgentPlane validate/place/run/evidence adapter. +13. GitHub/CI bridge adapters. +14. Hermes, Codex, Claude Code, and OpenCLAW participant adapters. +15. Textual TUI for rooms, threads, workrooms, topics, memory, semantic objects, investigations, graphs, approvals, and evidence. From 94680b35fa1e1aef774bca3eb322771511e3cb0a Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:49:36 -0400 Subject: [PATCH 29/40] Reference Holmes boundary in README --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c68f52c..7946d84 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ AgentTerm treats every meaningful action as an event: - Slash Topics topic-scope, policy-membrane, and receipt events - Memory Mesh recall, writeback, and context-pack events - New Hope message, thread, claim, citation, receptor, membrane, and moderation events -- Holmes casefile, investigation, synthesis, guardrail, and eval events +- Holmes request/status/artifact correlation events, without redefining Holmes behavior - Sherlock Search search-packet and context-hydration events - MeshRush graph-view, diffusion, crystallization, trace, and graph-evidence events - GitHub issue and PR updates @@ -83,7 +83,7 @@ AgentTerm should not collapse the SourceOS stack into one generic search agent. | Slash Topics | Governed signed topic scopes, policy membranes, search/knowledge scoping, replayable receipts | | Memory Mesh | Governed recall, writeback, context packs, memoryd runtime, LiteLLM/OpenCLAW memory integrations | | New Hope | Semantic runtime for messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events | -| Holmes | Language intelligence fabric for casefiles, retrieval, semantic graphs, investigation, synthesis, guardrails, and evals | +| Holmes | External language-intelligence fabric; AgentTerm may request, display, correlate, and audit Holmes-owned work, but must not define it | | Sherlock Search | Discovery/search-packet surface and retrieval evidence engine | | Legacy Sherlock | Explicitly authorized, policy-gated username/social-network OSINT only | | MeshRush | Graph-native autonomous-agent runtime over typed hypergraph world-model views | @@ -117,14 +117,15 @@ agent-term tail agent-term shell ``` -The first implementation stores events in SQLite and records governance-preserving events locally. Matrix network I/O, Sociosphere materialization, Prophet Workspace workroom APIs, Slash Topics membranes, Memory Mesh recall/writeback, New Hope semantic normalization, Holmes investigation, Sherlock Search hydration, MeshRush graph execution, cloudshell-fog session attach, AgentPlane bundle execution, and Policy Fabric admission are intentionally isolated behind adapter boundaries so the terminal, policy, event log, and registry can be hardened independently. +The first implementation stores events in SQLite and records governance-preserving events locally. Matrix network I/O, Sociosphere materialization, Prophet Workspace workroom APIs, Slash Topics membranes, Memory Mesh recall/writeback, New Hope semantic normalization, Holmes request/status/artifact correlation, Sherlock Search hydration, MeshRush graph execution, cloudshell-fog session attach, AgentPlane bundle execution, and Policy Fabric admission are intentionally isolated behind adapter boundaries so the terminal, policy, event log, and registry can be hardened independently. ## Docs - [SourceOS control surface architecture](docs/architecture/sourceos-control-surface.md) +- [Holmes integration boundary](docs/integration/holmes-boundary.md) - [Agent instructions](AGENTS.md) - [Example configuration](configs/agent-term.example.json) ## Repository status -This is the seed implementation. It is intentionally small but runnable. The next step is to land the Matrix-room MVP, then bind Policy Fabric admission, Sociosphere workspace state, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh recall/writeback, New Hope semantic events, Holmes investigations, Sherlock Search packets, MeshRush graph events, cloudshell-fog session lifecycle, AgentPlane evidence flow, and Hermes/Codex/Claude Code/OpenCLAW participants under explicit operator permissions. +This is the seed implementation. It is intentionally small but runnable. The next step is to land the Matrix-room MVP, then bind Policy Fabric admission, Sociosphere workspace state, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh recall/writeback, New Hope semantic events, Holmes request/status/artifact correlation, Sherlock Search packets, MeshRush graph events, cloudshell-fog session lifecycle, AgentPlane evidence flow, and Hermes/Codex/Claude Code/OpenCLAW participants under explicit operator permissions. From ac46f225f1a991769d6b94ddaa945a3ec2721f1a Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:53:39 -0400 Subject: [PATCH 30/40] Add Agent Registry as agent identity authority plane --- src/agent_term/planes.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/agent_term/planes.py b/src/agent_term/planes.py index 94c7dc6..cb4e063 100644 --- a/src/agent_term/planes.py +++ b/src/agent_term/planes.py @@ -2,8 +2,8 @@ These records make SourceOS integration explicit at the CLI/event layer before any network adapter is enabled. AgentTerm is the operator console; these planes own the -actual workspace, semantic, memory, execution, policy, search, shell, and orchestration -semantics. +actual agent identity, workspace, semantic, memory, execution, policy, search, shell, +and orchestration semantics. """ from __future__ import annotations @@ -48,6 +48,24 @@ class SourceOSPlane: PlaneCapability("e2ee_posture_check", "Block sensitive context injection when encrypted-room posture is unknown or unsafe.", False, ("policy_check",)), ), ), + SourceOSPlane( + key="agent-registry", + display_name="Agent Registry", + repository="SocioProphet/agent-registry", + role="Governed registry for SocioProphet agent specs, identities, sessions, memories, tool grants, revocation, and runtime authority.", + source="agent-registry", + capabilities=( + PlaneCapability("resolve_agent_identity", "Resolve an agent participant identity, spec, runtime authority, and registration state.", False, ("agent_identity",)), + PlaneCapability("validate_agent_registration", "Validate that a requested AgentTerm participant is registered before enablement.", False, ("validation", "agent_identity")), + PlaneCapability("request_tool_grant", "Request a governed tool/capability grant for an agent participant.", True, ("tool_grant", "policy_check")), + PlaneCapability("revoke_agent_session", "Revoke or disable an agent session/capability grant.", True, ("revocation", "decision")), + ), + notes=( + "Every non-human AgentTerm participant must be registered in Agent Registry before it is enabled.", + "Hermes, Codex, Claude Code, OpenCLAW, GitHub bots, CI bots, MCP tools, Matrix bots, and local process agents should resolve identity and tool grants through Agent Registry.", + "AgentTerm local config may reference participants, but Agent Registry remains the runtime authority for agent identity and grants.", + ), + ), SourceOSPlane( key="sociosphere", display_name="Sociosphere", @@ -135,17 +153,17 @@ class SourceOSPlane: key="holmes", display_name="Holmes", repository="SocioProphet/holmes", - role="Governed language intelligence fabric for NLP, semantic search, retrieval, knowledge graphs, guardrails, evals, casefiles, and investigative agentic discovery.", + role="External language intelligence fabric for casefiles, retrieval, semantic graphs, synthesis, guardrails, evals, and investigative discovery.", source="holmes", capabilities=( - PlaneCapability("open_casefile", "Bind a workroom/thread to a Holmes investigation or casefile.", True, ("casefile",)), - PlaneCapability("investigate", "Run governed language-intelligence workflows over evidence, retrieval, and semantic graphs.", True, ("investigation",)), - PlaneCapability("synthesize_findings", "Synthesize findings with claim, citation, provenance, and contradiction metadata.", True, ("synthesis", "evidence")), - PlaneCapability("run_evals", "Run language/retrieval/guardrail/evidence evals for a case or agent flow.", True, ("eval",)), + PlaneCapability("open_casefile", "Request or correlate a Holmes-owned investigation or casefile.", True, ("casefile",)), + PlaneCapability("investigate", "Request a governed Holmes investigation without redefining Holmes behavior.", True, ("investigation",)), + PlaneCapability("correlate_holmes_artifact", "Record Holmes-owned artifact, status, eval, guardrail, synthesis, or evidence references.", False, ("evidence", "correlation")), ), notes=( - "Holmes is the language-intelligence fabric above search, evidence, retrieval, casefiles, semantic graphs, tools, models, evals, and agents.", - "Holmes should coordinate with Sherlock Search for retrieval and New Hope for semantic message/thread/claim objects.", + "AgentTerm must not define Holmes product semantics, schemas, service behavior, model routing, or deployment.", + "AgentTerm may request, display, correlate, and audit Holmes-owned work once Holmes exposes stable contracts.", + "Holmes integration must respect docs/integration/holmes-boundary.md.", ), ), SourceOSPlane( From 07adf193bcff9ff036f0bad72d5cbb6609cf5d67 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:54:11 -0400 Subject: [PATCH 31/40] Enforce Agent Registry as participant authority in plane tests --- tests/test_planes.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_planes.py b/tests/test_planes.py index 4bb170d..3550802 100644 --- a/tests/test_planes.py +++ b/tests/test_planes.py @@ -5,6 +5,7 @@ def test_sourceos_planes_include_required_integrations(): keys = {plane.key for plane in iter_planes()} assert "matrix" in keys + assert "agent-registry" in keys assert "sociosphere" in keys assert "prophet-workspace" in keys assert "slash-topics" in keys @@ -20,12 +21,14 @@ def test_sourceos_planes_include_required_integrations(): def test_authority_boundaries_are_explicit(): + agent_registry = get_plane("agent-registry") sociosphere = get_plane("sociosphere") workspace = get_plane("prophet-workspace") new_hope = get_plane("new-hope") holmes = get_plane("holmes") sherlock = get_plane("sherlock-search") + assert "agent specs" in agent_registry.role assert "meta-workspace controller" in sociosphere.role assert "workroom" in workspace.role.lower() assert "semantic runtime" in new_hope.role.lower() @@ -33,6 +36,19 @@ def test_authority_boundaries_are_explicit(): assert "retrieval/search-packet" in sherlock.role +def test_agent_registry_is_participant_authority(): + agent_registry = get_plane("agent-registry") + notes = " ".join(agent_registry.notes).lower() + capabilities = {capability.name for capability in agent_registry.capabilities} + + assert agent_registry.repository == "SocioProphet/agent-registry" + assert "every non-human agentterm participant must be registered" in notes + assert "resolve_agent_identity" in capabilities + assert "validate_agent_registration" in capabilities + assert "request_tool_grant" in capabilities + assert "revoke_agent_session" in capabilities + + def test_sherlock_search_is_preferred_surface(): sherlock = get_plane("sherlock-search") legacy = get_plane("legacy-sherlock") @@ -49,6 +65,8 @@ def test_side_effecting_capabilities_require_approval(): for capability in plane.capabilities: if capability.name in { "room_event_emit", + "request_tool_grant", + "revoke_agent_session", "materialize_workspace", "hydrate_workspace_context", "apply_topic_membrane", From 1f2741dc45f4a126e14076f14ae1439afb14300c Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:55:05 -0400 Subject: [PATCH 32/40] Require Agent Registry authority in adapter targets --- src/agent_term/adapters.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/agent_term/adapters.py b/src/agent_term/adapters.py index a0356c1..0ae22a9 100644 --- a/src/agent_term/adapters.py +++ b/src/agent_term/adapters.py @@ -1,8 +1,8 @@ """Adapter contracts for AgentTerm participants. Adapters translate between AgentTerm events and concrete systems: Matrix rooms, -Sociosphere, Prophet Workspace, Slash Topics, Memory Mesh, New Hope, Holmes, -Sherlock Search, MeshRush, cloudshell-fog, AgentPlane, Policy Fabric, Hermes, +Agent Registry, Sociosphere, Prophet Workspace, Slash Topics, Memory Mesh, New Hope, +Holmes, Sherlock Search, MeshRush, cloudshell-fog, AgentPlane, Policy Fabric, Hermes, Codex, Claude Code, OpenCLAW, GitHub, CI, MCP, and local process agents. This file intentionally avoids vendor SDK dependencies. Real network adapters should live behind @@ -57,8 +57,9 @@ class ProcessAdapter: """Simple command-backed adapter for local agents and CLIs. The command is passed to the shell only when explicitly configured by the operator. This is - deliberately not wired to the interactive shell yet; Policy Fabric approval and SourceOS - execution envelopes should be inserted before side-effecting commands are enabled. + deliberately not wired to the interactive shell yet; Agent Registry resolution, Policy Fabric + approval, and SourceOS execution envelopes should be inserted before side-effecting commands + are enabled. """ key: str @@ -92,23 +93,24 @@ def handle(self, event: AgentTermEvent) -> AdapterResult: ADAPTER_TARGETS = { "matrix": "Canonical room/event transport adapter; preserve room IDs, event IDs, redactions, membership, bridge metadata, and E2EE posture.", + "agent-registry": "Agent identity and runtime-authority adapter for specs, participants, sessions, tool grants, revocation, memories, and registration state.", "sociosphere": "Meta-workspace controller adapter for manifest, lock, topology, governance registry, and validation-lane events.", "prophet-workspace": "Professional Workrooms and workspace product adapter for workroom binding, policy-aware UX, admin, audit, and search surfaces.", "slash-topics": "Governed topic-scope adapter for signed topic packs, policy membranes, and deterministic receipts.", "memory-mesh": "Governed memory/context adapter for recall, writeback, context packs, LiteLLM hooks, and OpenCLAW memory tools.", "new-hope": "Semantic runtime adapter for messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events.", - "holmes": "Language-intelligence fabric adapter for casefiles, retrieval, semantic graphs, synthesis, guardrails, and evals.", + "holmes": "Boundary-respecting Holmes adapter for request/status/artifact correlation only; AgentTerm must not define Holmes behavior.", "sherlock-search": "Preferred Sherlock integration for scoped search packets and context hydration.", "legacy-sherlock": "High-friction policy-gated OSINT wrapper only; never a default ambient tool.", "meshrush": "Graph-operating runtime adapter for graph views, diffusion, crystallization, traces, and graph evidence.", "cloudshell-fog": "Fog-first shell/session substrate; AgentTerm requests sessions but does not bypass OIDC, placement, TTL, or audit.", "agentplane": "Execution authority for bundle validation, placement, runs, replay, and evidence artifacts.", "policy-fabric": "Policy decision and evidence authority for side-effecting commands and sensitive context release.", - "hermes": "Personal/multi-channel agent gateway participant; may bridge external chat surfaces into Matrix-backed AgentTerm rooms.", - "codex": "Code-writing participant; must operate through repo branches, diffs, PRs, and approval-gated shell/test commands.", - "claude-code": "Codebase reasoning and patch participant; must emit plan, diff, command, and evidence events.", - "openclaw": "Local/open agent runtime participant; must run inside SourceOS capability and policy envelopes.", - "github": "Issue, PR, review, check, and branch event integration.", - "ci": "Workflow status/log/retry integration with explicit retry approval gates.", - "mcp": "Tool-plane adapter for files, docs, search, memory, calendar, and other governed capabilities.", + "hermes": "Personal/multi-channel agent gateway participant; must resolve identity and grants through Agent Registry before enablement.", + "codex": "Code-writing participant; must be registered and operate through repo branches, diffs, PRs, and approval-gated shell/test commands.", + "claude-code": "Codebase reasoning participant; must be registered and emit plan, diff, command, and evidence events.", + "openclaw": "Local/open agent runtime participant; must be registered and run inside SourceOS capability and policy envelopes.", + "github": "Issue, PR, review, check, branch, and bot-event integration; GitHub bots must be represented in Agent Registry where acting as agents.", + "ci": "Workflow status/log/retry integration with explicit retry approval gates; CI bots must be represented in Agent Registry where acting as agents.", + "mcp": "Tool-plane adapter for files, docs, search, memory, calendar, and other governed capabilities; tool grants should resolve through Agent Registry.", } From e75ad14a586fa320903cf015b71c446e888a494a Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:55:44 -0400 Subject: [PATCH 33/40] Add Agent Registry integration boundary --- docs/integration/agent-registry-boundary.md | 71 +++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 docs/integration/agent-registry-boundary.md diff --git a/docs/integration/agent-registry-boundary.md b/docs/integration/agent-registry-boundary.md new file mode 100644 index 0000000..2271985 --- /dev/null +++ b/docs/integration/agent-registry-boundary.md @@ -0,0 +1,71 @@ +# Agent Registry integration boundary + +AgentTerm must not invent, hardcode, or locally bless non-human agent participants. Agent identity and runtime authority belong to `SocioProphet/agent-registry`. + +Agent Registry is the governed registry for SocioProphet agent specs, identities, sessions, memories, tool grants, revocation, and runtime authority. + +## AgentTerm may own + +- terminal UX for selecting, viewing, and addressing registered agents +- local event records that reference agent identities and sessions +- Matrix room/thread correlation metadata for agent messages +- request events for tool grants, capability use, and session activation +- display of Agent Registry status, grants, revocations, and denials +- adapter plumbing that resolves registered agents before dispatch + +## AgentTerm must not own + +- canonical agent specs +- agent identity authority +- runtime session authority +- tool grant authority +- revocation authority +- memory ownership authority +- capability-policy decisions +- a hidden allowlist that bypasses Agent Registry + +## Required invariant + +Every non-human AgentTerm participant must be registered and resolved through Agent Registry before enablement. This includes: + +- Hermes participants +- Codex participants +- Claude Code participants +- OpenCLAW participants +- Matrix bots +- GitHub bots acting as agents +- CI bots acting as agents +- MCP-backed tool participants +- local process agents +- future custom SourceOS agents + +Local config may reference agents, but config is not authority. Config only expresses desired local bindings. Agent Registry decides whether the participant exists, what it may do, which tools it may use, which sessions are live, and whether any grants have been revoked. + +## Expected flow + +```text +/operator addresses @agent + -> AgentTerm records agent_identity lookup event + -> Agent Registry resolves identity, spec, runtime authority, grants, and session state + -> Policy Fabric evaluates requested action/context release where required + -> AgentTerm dispatches through the appropriate adapter only if identity and grants are valid + -> adapter result is recorded with agent ID, grant ID, session ID, and policy/evidence references + -> Matrix room and local event log receive visible status +``` + +## Minimum metadata on agent events + +- `agent_id` +- `agent_registry_ref` +- `agent_spec_version` +- `session_id`, when active +- `tool_grant_ids`, when tools are requested +- `revocation_check_at` +- `policy_decision_ref`, when the action is side-effecting or context-sensitive +- `adapter_key` +- `runtime_authority` +- `workroom`, `topic_scope`, and `thread_id`, when applicable + +## Adapter posture + +Agent adapters should fail closed when Agent Registry is unavailable or returns unknown/revoked status. The only acceptable exception is a clearly marked local development mode that cannot operate on sensitive context or side-effecting commands. From b3318e424e1c11e6ff640d127345239938b35ddd Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:56:50 -0400 Subject: [PATCH 34/40] Add Agent Registry authority to example configuration --- configs/agent-term.example.json | 45 ++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/configs/agent-term.example.json b/configs/agent-term.example.json index 77d57b8..feaa9ae 100644 --- a/configs/agent-term.example.json +++ b/configs/agent-term.example.json @@ -13,6 +13,7 @@ "rooms": { "sourceosOps": "!sourceos-ops:example.org", "sourceosBuild": "!sourceos-build:example.org", + "agentRegistry": "!agent-registry:example.org", "sociosphere": "!sociosphere:example.org", "prophetWorkspace": "!prophet-workspace:example.org", "slashTopics": "!slash-topics:example.org", @@ -31,7 +32,30 @@ "preserveRedactions": true, "preserveMembershipEvents": true }, + "agentRegistration": { + "requireRegisteredParticipants": true, + "failClosedWhenRegistryUnavailable": true, + "repository": "SocioProphet/agent-registry", + "requiredFor": [ + "hermes", + "codex", + "claudeCode", + "openclaw", + "matrixBots", + "githubBots", + "ciBots", + "mcpTools", + "localProcessAgents" + ] + }, "planes": { + "agentRegistry": { + "enabled": true, + "repository": "SocioProphet/agent-registry", + "role": "agent-specs-identities-sessions-memories-tool-grants-revocation-and-runtime-authority", + "requireResolutionBeforeParticipantEnablement": true, + "requireToolGrantBeforeAdapterDispatch": true + }, "sociosphere": { "enabled": true, "repository": "SocioProphet/sociosphere", @@ -66,8 +90,9 @@ "holmes": { "enabled": true, "repository": "SocioProphet/holmes", - "role": "language-intelligence-fabric-for-investigation-casefiles-retrieval-evals-and-guardrails", - "requirePolicyApprovalForInvestigation": true + "role": "external-language-intelligence-fabric-request-status-artifact-correlation-only", + "requirePolicyApprovalForInvestigation": true, + "mustNotRedefineHolmesSemantics": true }, "sherlockSearch": { "enabled": true, @@ -120,22 +145,36 @@ "participants": { "hermes": { "enabled": false, - "mode": "gateway" + "mode": "gateway", + "requireAgentRegistryResolution": true, + "agentRegistryId": "agent.hermes" }, "codex": { "enabled": false, "mode": "repo-branch-pr", + "requireAgentRegistryResolution": true, + "agentRegistryId": "agent.codex", "requirePolicyApprovalForMutation": true }, "claudeCode": { "enabled": false, "mode": "repo-branch-pr", + "requireAgentRegistryResolution": true, + "agentRegistryId": "agent.claude-code", "requirePolicyApprovalForMutation": true }, "openclaw": { "enabled": false, "mode": "local-runtime", + "requireAgentRegistryResolution": true, + "agentRegistryId": "agent.openclaw", "requirePolicyApprovalForSideEffects": true + }, + "localProcessAgents": { + "enabled": false, + "mode": "developer-only", + "requireAgentRegistryResolution": true, + "disableForSensitiveContext": true } } } From cb02573f9bf8567d7ba4fbd2e3d33a297cfa7ad3 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:57:35 -0400 Subject: [PATCH 35/40] Document Agent Registry as participant authority in README --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7946d84..8f634d8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AgentTerm -AgentTerm is a terminal-native ChatOps console for coordinating human operators, Matrix rooms, LLM agents, GitHub bots, CI systems, MCP tools, Sociosphere workspace materialization, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh context, New Hope semantic threads, Holmes investigations, Sherlock search packets, MeshRush graph operations, cloudshell-fog sessions, AgentPlane runs, Policy Fabric decisions, and local SourceOS services from one channel/thread workspace. +AgentTerm is a terminal-native ChatOps console for coordinating human operators, Matrix rooms, registered agents, GitHub bots, CI systems, MCP tools, Agent Registry identities, Sociosphere workspace materialization, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh context, New Hope semantic threads, Holmes investigations, Sherlock search packets, MeshRush graph operations, cloudshell-fog sessions, AgentPlane runs, Policy Fabric decisions, and local SourceOS services from one channel/thread workspace. The design target is not another single-agent CLI. AgentTerm is the Slack-term class interface for agent operations: rooms, channels, threads, slash commands, approvals, event logs, adapters, and terminal-first operator flow. For SourceOS, Matrix is the canonical network ChatOps substrate. Slack and Discord should be treated as bridge targets, not the source of truth. @@ -9,9 +9,10 @@ The design target is not another single-agent CLI. AgentTerm is the Slack-term c - A Python CLI package named `agent-term`. - A local SQLite event log for durable operator history. - A minimal interactive shell for immediate use. -- A first-class SourceOS plane registry for Matrix, Sociosphere, Prophet Workspace, Slash Topics, Memory Mesh, New Hope, Holmes, Sherlock Search, legacy Sherlock, MeshRush, cloudshell-fog, AgentPlane, Policy Fabric, GitHub, CI, MCP, Hermes, Codex, Claude Code, and OpenCLAW. +- A first-class SourceOS plane registry for Matrix, Agent Registry, Sociosphere, Prophet Workspace, Slash Topics, Memory Mesh, New Hope, Holmes, Sherlock Search, legacy Sherlock, MeshRush, cloudshell-fog, AgentPlane, Policy Fabric, GitHub, CI, MCP, Hermes, Codex, Claude Code, and OpenCLAW. - Adapter contracts for Matrix, SourceOS planes, and process-backed participants. - Governance-preserving command shapes for workroom, topic, memory, semantic-thread, investigation, search-packet, graph-view, and shell-session requests. +- Agent identity posture: local config may reference agents, but Agent Registry is the authority for specs, identities, sessions, memories, tool grants, revocation, and runtime authority. - Configuration examples, tests, CI, and operating-model docs for building AgentTerm into the SourceOS operator console. ## Core concept @@ -19,6 +20,7 @@ The design target is not another single-agent CLI. AgentTerm is the Slack-term c ```text ┌──────────────────────────┬─────────────────────────────────────────────┐ │ Matrix Rooms / Channels │ Thread / Conversation │ +│ !agent-registry │ @agent-term: resolve @codex before dispatch │ │ !prophet-workspace │ @operator: /workroom pi-demo │ │ !slash-topics │ @operator: /topic professional-intelligence │ │ !memory-mesh │ @operator: /memory recall workroom context │ @@ -38,6 +40,7 @@ AgentTerm treats every meaningful action as an event: - human chat messages - slash commands +- registered-agent identity, grant, session, and revocation events - agent replies - Matrix room events, redactions, membership changes, and bridge events - Sociosphere workspace manifest, lock, topology, and validation events @@ -78,6 +81,7 @@ AgentTerm should not collapse the SourceOS stack into one generic search agent. | Plane | Authority | | --- | --- | +| Agent Registry | Agent specs, identities, sessions, memories, tool grants, revocation, and runtime authority for every non-human participant | | Sociosphere | Meta-workspace controller, canonical workspace manifest, lock, topology, governance registry, validation lanes | | Prophet Workspace | Workspace product semantics, Professional Workrooms, mail/calendar/drive/docs/chat/meeting surfaces, policy-aware UX | | Slash Topics | Governed signed topic scopes, policy membranes, search/knowledge scoping, replayable receipts | @@ -93,6 +97,8 @@ AgentTerm should not collapse the SourceOS stack into one generic search agent. New Hope is not “handled by” Sherlock or Holmes. Holmes investigates, Sherlock retrieves, and New Hope normalizes the semantic commons objects they operate over. +Every non-human AgentTerm participant must resolve through Agent Registry before enablement. This includes Hermes, Codex, Claude Code, OpenCLAW, Matrix bots, GitHub bots acting as agents, CI bots acting as agents, MCP-backed tools, local process agents, and future SourceOS agents. Local config is a desired binding, not authority. + ## MVP commands After cloning locally: @@ -103,8 +109,10 @@ source .venv/bin/activate pip install -e '.[dev]' agent-term init agent-term planes list +agent-term planes show agent-registry agent-term planes show new-hope agent-term post '!sourceos-build' '@operator' 'AgentTerm is online.' +agent-term record agent-registry agent_identity '!agent-registry' 'Resolve agent.codex before dispatch' agent-term record prophet-workspace workroom '!prophet-workspace' 'Bind PI demo workroom' --metadata-json '{"workroom":"pi-demo"}' agent-term record slash-topics topic_scope '!slash-topics' 'Select /professional-intelligence topic scope' agent-term record memory-mesh memory_recall '!memory-mesh' 'Recall workroom context' --requires-approval @@ -117,15 +125,16 @@ agent-term tail agent-term shell ``` -The first implementation stores events in SQLite and records governance-preserving events locally. Matrix network I/O, Sociosphere materialization, Prophet Workspace workroom APIs, Slash Topics membranes, Memory Mesh recall/writeback, New Hope semantic normalization, Holmes request/status/artifact correlation, Sherlock Search hydration, MeshRush graph execution, cloudshell-fog session attach, AgentPlane bundle execution, and Policy Fabric admission are intentionally isolated behind adapter boundaries so the terminal, policy, event log, and registry can be hardened independently. +The first implementation stores events in SQLite and records governance-preserving events locally. Matrix network I/O, Agent Registry resolution/grants/revocation, Sociosphere materialization, Prophet Workspace workroom APIs, Slash Topics membranes, Memory Mesh recall/writeback, New Hope semantic normalization, Holmes request/status/artifact correlation, Sherlock Search hydration, MeshRush graph execution, cloudshell-fog session attach, AgentPlane bundle execution, and Policy Fabric admission are intentionally isolated behind adapter boundaries so the terminal, policy, event log, and registry can be hardened independently. ## Docs - [SourceOS control surface architecture](docs/architecture/sourceos-control-surface.md) +- [Agent Registry integration boundary](docs/integration/agent-registry-boundary.md) - [Holmes integration boundary](docs/integration/holmes-boundary.md) - [Agent instructions](AGENTS.md) - [Example configuration](configs/agent-term.example.json) ## Repository status -This is the seed implementation. It is intentionally small but runnable. The next step is to land the Matrix-room MVP, then bind Policy Fabric admission, Sociosphere workspace state, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh recall/writeback, New Hope semantic events, Holmes request/status/artifact correlation, Sherlock Search packets, MeshRush graph events, cloudshell-fog session lifecycle, AgentPlane evidence flow, and Hermes/Codex/Claude Code/OpenCLAW participants under explicit operator permissions. +This is the seed implementation. It is intentionally small but runnable. The next step is to land the Matrix-room MVP, then bind Agent Registry resolution/grants/revocation, Policy Fabric admission, Sociosphere workspace state, Prophet Workspace workrooms, Slash Topics scopes, Memory Mesh recall/writeback, New Hope semantic events, Holmes request/status/artifact correlation, Sherlock Search packets, MeshRush graph events, cloudshell-fog session lifecycle, AgentPlane evidence flow, and Hermes/Codex/Claude Code/OpenCLAW participants under explicit operator permissions. From dc7177c0a9cbb80b5f268aa19e3c61b362248d52 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 11:58:58 -0400 Subject: [PATCH 36/40] Document Agent Registry invariant in AGENTS --- AGENTS.md | 64 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 480a906..e95ee35 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,13 +5,14 @@ AgentTerm is the terminal-native Matrix-first ChatOps console for SourceOS. It i ## Mandatory architecture boundaries - Matrix is the canonical ChatOps transport. Slack and Discord are bridge targets, not the source of truth. -- AgentTerm is the operator surface and normalized event log. It does not own workspace topology, workroom semantics, topic scopes, memory runtime, semantic runtime, investigation runtime, search-packet schemas, graph runtime, shell placement, bundle execution, policy release, or CI execution. +- AgentTerm is the operator surface and normalized event log. It does not own agent identity authority, workspace topology, workroom semantics, topic scopes, memory runtime, semantic runtime, investigation runtime, search-packet schemas, graph runtime, shell placement, bundle execution, policy release, or CI execution. +- Agent Registry owns agent specs, identities, sessions, memories, tool grants, revocation, and runtime authority. Every non-human AgentTerm participant must resolve through Agent Registry before enablement. - Sociosphere owns canonical workspace manifests, locks, topology, registry metadata, validation lanes, and release-readiness orchestration. - Prophet Workspace owns workspace product semantics, Professional Workrooms, workspace app surfaces, policy-aware UX, audit, and receipts. - Slash Topics owns governed, signed, replayable topic scopes and policy membranes for search/knowledge operations. - Memory Mesh owns governed recall, writeback, context packs, memoryd runtime, LiteLLM hooks, and OpenCLAW memory tools. - New Hope owns semantic runtime semantics for messages, threads, claims, citations, entities, lenses, receptors, membranes, and moderation events. -- Holmes owns language intelligence: casefiles, retrieval, semantic graphs, synthesis, guardrails, evals, and investigative discovery. +- Holmes owns language intelligence: casefiles, retrieval, semantic graphs, synthesis, guardrails, evals, and investigative discovery. AgentTerm may request/status/correlate Holmes work but must not redefine Holmes. - Sherlock Search owns discovery/search-packet and retrieval-evidence surfaces. Legacy Sherlock username/social-network lookup is high-friction and policy-gated only. - MeshRush owns graph-native autonomous-agent runtime semantics over graph views, diffusion, crystallization, traces, and graph evidence. - cloudshell-fog owns governed shell/session placement, OIDC, TTL, PTY attach, and audit semantics. @@ -20,19 +21,21 @@ AgentTerm is the terminal-native Matrix-first ChatOps console for SourceOS. It i ## Required invariants -1. Side-effecting commands require an approval path. -2. Sensitive context release requires Policy Fabric admission. -3. Matrix room IDs, event IDs, membership changes, redactions, bridge metadata, and E2EE posture must be preserved when available. -4. Workroom, topic, memory, semantic-thread, investigation, search-packet, graph, execution, and shell events must remain explicit and auditable. -5. Slash Topics scopes should constrain Memory Mesh recall, Sherlock Search packets, Holmes investigations, New Hope semantic routing, and MeshRush graph view selection. -6. Memory Mesh must not be treated as hidden prompt history; recall/writeback requires explicit event metadata and policy posture. -7. New Hope is not handled by Sherlock or Holmes; it is the semantic commons runtime underneath message/thread/claim/citation operations. -8. Holmes investigates; Sherlock retrieves; New Hope normalizes semantic objects; Memory Mesh supplies governed context; Slash Topics scopes the operation. -9. AgentPlane evidence artifacts must remain visible in AgentTerm events. -10. cloudshell-fog shell attach must not bypass OIDC, placement, TTL, or audit semantics. -11. Legacy Sherlock OSINT must never become an ambient default tool. -12. Adapter code must be behind narrow contracts; do not hardwire vendor SDKs into the terminal shell. -13. Local event-log data must not be committed. +1. Every non-human participant requires Agent Registry identity resolution before enablement. +2. Tool use, capability grants, runtime sessions, memory authority, and revocation checks must resolve through Agent Registry. +3. Side-effecting commands require an approval path. +4. Sensitive context release requires Policy Fabric admission. +5. Matrix room IDs, event IDs, membership changes, redactions, bridge metadata, and E2EE posture must be preserved when available. +6. Workroom, topic, memory, semantic-thread, investigation, search-packet, graph, execution, and shell events must remain explicit and auditable. +7. Slash Topics scopes should constrain Memory Mesh recall, Sherlock Search packets, Holmes investigations, New Hope semantic routing, and MeshRush graph view selection. +8. Memory Mesh must not be treated as hidden prompt history; recall/writeback requires explicit event metadata and policy posture. +9. New Hope is not handled by Sherlock or Holmes; it is the semantic commons runtime underneath message/thread/claim/citation operations. +10. Holmes investigates; Sherlock retrieves; New Hope normalizes semantic objects; Memory Mesh supplies governed context; Slash Topics scopes the operation. +11. AgentPlane evidence artifacts must remain visible in AgentTerm events. +12. cloudshell-fog shell attach must not bypass OIDC, placement, TTL, or audit semantics. +13. Legacy Sherlock OSINT must never become an ambient default tool. +14. Adapter code must be behind narrow contracts; do not hardwire vendor SDKs into the terminal shell. +15. Local event-log data must not be committed. ## Development commands @@ -49,7 +52,9 @@ pytest ```bash agent-term init agent-term planes list +agent-term planes show agent-registry agent-term planes show new-hope +agent-term record agent-registry agent_identity '!agent-registry' 'Resolve agent.codex before dispatch' agent-term record prophet-workspace workroom '!prophet-workspace' 'Bind PI demo workroom' --metadata-json '{"workroom":"pi-demo"}' agent-term record slash-topics topic_scope '!slash-topics' 'Select /professional-intelligence topic scope' agent-term record memory-mesh memory_recall '!memory-mesh' 'Recall workroom context' --requires-approval @@ -65,17 +70,18 @@ agent-term tail 1. Keep the local event model and SourceOS plane registry stable. 2. Add Matrix adapter read/write with E2EE posture surfaced. -3. Add Policy Fabric command admission stub before side-effecting adapter execution. -4. Add Sociosphere workspace manifest/topology adapter. -5. Add Prophet Workspace workroom binding and receipt adapter. -6. Add Slash Topics topic-pack and membrane adapter. -7. Add Memory Mesh recall/writeback/context-pack adapter. -8. Add New Hope semantic-thread/message/claim/citation adapter. -9. Add Sherlock Search packet validation/hydration flow. -10. Add Holmes casefile/investigation/synthesis/eval flow. -11. Add MeshRush graph-view/diffusion/crystallization flow. -12. Add cloudshell-fog session request/attach flow. -13. Add AgentPlane validate/place/run/evidence flow. -14. Add GitHub and CI bridge events. -15. Add Hermes, Codex, Claude Code, and OpenCLAW participant adapters. -16. Add richer Textual TUI views for rooms, threads, workrooms, topics, memory, semantic objects, investigations, graphs, approvals, and evidence. +3. Add Agent Registry participant identity, grant, session, and revocation adapter. +4. Add Policy Fabric command admission stub before side-effecting adapter execution. +5. Add Sociosphere workspace manifest/topology adapter. +6. Add Prophet Workspace workroom binding and receipt adapter. +7. Add Slash Topics topic-pack and membrane adapter. +8. Add Memory Mesh recall/writeback/context-pack adapter. +9. Add New Hope semantic-thread/message/claim/citation adapter. +10. Add Sherlock Search packet validation/hydration flow. +11. Add Holmes request/status/artifact correlation flow without redefining Holmes. +12. Add MeshRush graph-view/diffusion/crystallization flow. +13. Add cloudshell-fog session request/attach flow. +14. Add AgentPlane validate/place/run/evidence flow. +15. Add GitHub and CI bridge events. +16. Add Hermes, Codex, Claude Code, and OpenCLAW participant adapters gated by Agent Registry. +17. Add richer Textual TUI views for rooms, threads, agents, grants, workrooms, topics, memory, semantic objects, investigations, graphs, approvals, and evidence. From 2a6f673c39b24e45ef8d756692e3c3ce24db7241 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 12:00:06 -0400 Subject: [PATCH 37/40] Update Copilot instructions for Agent Registry authority --- .github/copilot-instructions.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 562f21d..87d9f66 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -6,12 +6,14 @@ Read these before making changes: - `AGENTS.md` - `docs/architecture/sourceos-control-surface.md` +- `docs/integration/agent-registry-boundary.md` - `docs/integration/holmes-boundary.md` ## Architecture guardrails - Matrix is the canonical transport. Slack and Discord integrations are bridges. - AgentTerm owns terminal UX, normalized local events, slash-command parsing, and adapter boundaries. +- Agent Registry owns agent specs, identities, sessions, memories, tool grants, revocation, and runtime authority. Every non-human participant must resolve through Agent Registry before enablement. - Sociosphere owns workspace manifest, lock, topology, registry, validation lanes, and release-readiness orchestration. - Prophet Workspace owns Professional Workrooms and workspace product semantics. - Slash Topics owns topic scopes and policy membranes. @@ -25,6 +27,7 @@ Read these before making changes: - Policy Fabric owns command admission and sensitive context-release decisions. - Side-effecting operations require explicit approval paths. - Avoid adding SDK-specific logic directly to `cli.py`. Keep adapters narrow and testable. +- Local config may reference participants, but it is not runtime authority. ## Validation commands @@ -37,17 +40,18 @@ pytest ## Current priority order 1. Matrix adapter with room/event/E2EE posture preservation. -2. Policy Fabric admission stub for side-effecting commands and sensitive context release. -3. Sociosphere workspace state adapter. -4. Prophet Workspace workroom binding and receipt adapter. -5. Slash Topics scope/membrane adapter. -6. Memory Mesh recall/writeback/context-pack adapter. -7. New Hope semantic event adapter. -8. Sherlock Search packet validation/hydration adapter. -9. Holmes request/status/artifact correlation adapter, respecting `docs/integration/holmes-boundary.md`. -10. MeshRush graph operation adapter. -11. cloudshell-fog session lifecycle adapter. -12. AgentPlane validate/place/run/evidence adapter. -13. GitHub/CI bridge adapters. -14. Hermes, Codex, Claude Code, and OpenCLAW participant adapters. -15. Textual TUI for rooms, threads, workrooms, topics, memory, semantic objects, investigations, graphs, approvals, and evidence. +2. Agent Registry adapter for participant identity, grants, sessions, and revocation. +3. Policy Fabric admission stub for side-effecting commands and sensitive context release. +4. Sociosphere workspace state adapter. +5. Prophet Workspace workroom binding and receipt adapter. +6. Slash Topics scope/membrane adapter. +7. Memory Mesh recall/writeback/context-pack adapter. +8. New Hope semantic event adapter. +9. Sherlock Search packet validation/hydration adapter. +10. Holmes request/status/artifact correlation adapter, respecting `docs/integration/holmes-boundary.md`. +11. MeshRush graph operation adapter. +12. cloudshell-fog session lifecycle adapter. +13. AgentPlane validate/place/run/evidence adapter. +14. GitHub/CI bridge adapters. +15. Hermes, Codex, Claude Code, and OpenCLAW participant adapters gated by Agent Registry. +16. Textual TUI for rooms, threads, agents, grants, workrooms, topics, memory, semantic objects, investigations, graphs, approvals, and evidence. From a434b5d38bde2442f4cc223d4fe2ee70991cae57 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 12:48:29 -0400 Subject: [PATCH 38/40] Add architecture note for Agent Registry participant authority --- .../agent-participant-authority.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 docs/architecture/agent-participant-authority.md diff --git a/docs/architecture/agent-participant-authority.md b/docs/architecture/agent-participant-authority.md new file mode 100644 index 0000000..8c56e1b --- /dev/null +++ b/docs/architecture/agent-participant-authority.md @@ -0,0 +1,64 @@ +# Agent participant authority + +AgentTerm is not the authority for non-human agent identity. It is the terminal operator console and event surface. + +`SocioProphet/agent-registry` is the authority for: + +- agent specs +- agent identities +- runtime sessions +- tool grants +- memory authority +- revocation +- runtime authority + +## Hard invariant + +Every non-human AgentTerm participant must resolve through Agent Registry before enablement. + +This includes: + +- Hermes +- Codex +- Claude Code +- OpenCLAW +- Matrix bots +- GitHub bots acting as agents +- CI bots acting as agents +- MCP-backed tool participants +- local process agents +- future SourceOS agents + +Local config may express desired bindings. It is not runtime authority. + +## Dispatch sequence + +```text +/operator addresses @agent + -> AgentTerm records agent_identity lookup event + -> Agent Registry resolves identity, spec, grants, session, and revocation state + -> Policy Fabric evaluates action/context admission when required + -> AgentTerm dispatches only if registry and policy posture are valid + -> adapter result records agent_id, grant_id, session_id, policy ref, and evidence ref +``` + +## Failure posture + +AgentTerm must fail closed when registry status is: + +- unknown +- missing +- revoked +- expired +- incompatible with requested tool/capability +- unavailable outside explicitly marked local development mode + +Local development mode must not operate on sensitive context or side-effecting commands unless Agent Registry and Policy Fabric checks pass. + +## Relationship to other planes + +Agent Registry does not replace Policy Fabric. Agent Registry answers: “Who is this agent, what session/grants does it hold, and is it still authorized as an agent participant?” + +Policy Fabric answers: “Is this action or context release allowed under current policy?” + +Both gates are required for side-effecting agent work. From a604f57c3cde051e0e26a9bc6193921796b1adcf Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 12:52:17 -0400 Subject: [PATCH 39/40] Fix legacy Sherlock boundary test --- tests/test_planes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_planes.py b/tests/test_planes.py index 3550802..d840836 100644 --- a/tests/test_planes.py +++ b/tests/test_planes.py @@ -52,11 +52,13 @@ def test_agent_registry_is_participant_authority(): def test_sherlock_search_is_preferred_surface(): sherlock = get_plane("sherlock-search") legacy = get_plane("legacy-sherlock") + legacy_contract = f"{legacy.role} {' '.join(legacy.notes)}".lower() assert sherlock.repository == "SocioProphet/sherlock-search" assert "preferred" in " ".join(sherlock.notes).lower() assert legacy.repository == "SocioProphet/sherlock" - assert any("policy-gated" in note for note in legacy.notes) + assert "policy-gated" in legacy_contract + assert "ambient default" in legacy_contract def test_side_effecting_capabilities_require_approval(): From 6f0d7dc72689adf4fbd7329c4cd511ae9171ee28 Mon Sep 17 00:00:00 2001 From: mdheller <21163552+mdheller@users.noreply.github.com> Date: Thu, 30 Apr 2026 12:54:48 -0400 Subject: [PATCH 40/40] Stabilize legacy Sherlock boundary assertion --- tests/test_planes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_planes.py b/tests/test_planes.py index d840836..ad97a4f 100644 --- a/tests/test_planes.py +++ b/tests/test_planes.py @@ -58,7 +58,7 @@ def test_sherlock_search_is_preferred_surface(): assert "preferred" in " ".join(sherlock.notes).lower() assert legacy.repository == "SocioProphet/sherlock" assert "policy-gated" in legacy_contract - assert "ambient default" in legacy_contract + assert "default agent tool" in legacy_contract def test_side_effecting_capabilities_require_approval():