OpenProgram lets local interfaces and channels such as Telegram and Discord share one agent and memory workspace. This page records the current method, reference frameworks, adopted and rejected designs, and implementation progress.
Runtime authority has only owner and paired. Unpaired is not a third authority tier: the message never enters the agent. Identity uses only stable platform-provided IDs, never message text.
Obtain the speaker ID and display name from Telegram/Discord platform metadata. Message text does not determine identity.
Look up the stable ID in the allowlist. Unpaired messages stop here; approval must originate from the local CLI or a loopback Web request.
speaker_*, instance owner principal and authority_tier are persisted and propagated as separate fields.
_gated_executeCheck the fixed tier→capability table. Missing or unknown tiers are denied; rules and bypass cannot skip this check.
Owner can fully manage memory; paired accounts can only reply and append. Paired content is trusted. Unpaired group sources remain pending and enter Topic synthesis only after explicit owner promotion.
memory_update to creation or byte append; only explicitly persisted owner turns may rewrite or delete existing content. Deferred work remains the hold queue for unauthorized requests and tier-filtered reads.
The following conclusions were checked against local source snapshots of refs-a/ and refs-b/: Codex f344a80a, OpenCode 0bff28de, OpenClaw c71c29ec, Hermes Agent 3bd844ed, pi-mono 936aff00, WeClaw 10711d0c. External documentation research also covers Claude Code, the MCP specification, LangGraph, OpenAI Agents SDK, AutoGen and Letta. This section treats only authority and memory mechanisms verifiable in local code as implementation evidence.
refs-b/openclaw/src/pairing/pairing-store.tsPairing codes are eight characters, exclude 0O1I, expire after one hour, and allow at most three pending requests per channel account.docs/channels/pairing.mdUnknown DMs are explicitly not processed. DM admission, command owner and group authorization are separate states.
refs-a/codex/codex-rs/memories/README.mdMemory extraction claims bounded rollout tasks with leases and failure backoff. Global consolidation permits one writer to modify the shared workspace and records success or failure. Progress uses thread-level watermarks and does not resolve branch provenance within one SessionDAG.
refs-b/hermes-agent/agent/memory_manager.pysync_allCalls all providers after a completed turn; MemoryProvider.on_session_switch provides session-switch notifications. Memory writing has no durable pending cursor; whether a provider handles switches depends on its implementation.
refs-a/opencode and refs-b/{pi-mono,weclaw}These three snapshots lack an equivalent long-term memory write flow. pi-mono SessionDAG uses append-only label/leaf records; OpenCode stores linear messages and manages the tail through revert; WeClaw retains only downstream session IDs or limited in-process history.
| Decision | Source | OpenProgram design |
|---|---|---|
| Adopted | OpenClaw pairing; Codex bounded tasks and single writer; Hermes unified provider entry | Stable-ID admission, a fixed owner/paired capability table, unified writer entry, persistent status and bounded backfill. |
| Adopted with modifications | OpenClaw session backfill and memory status | Backfill selects only trusted Sources not referenced by Topics. Status performs local read-only statistics without loading models or repairing the workspace. |
| Rejected | Codex separate task database; Hermes per-turn synchronization; OpenClaw external archives in backfill preview | Reuse node markers, Source references, workspace revisions and file locks. Invoke models only at thresholds or idle time. External archives do not enter trusted synthesis. |
Ingress uses stable-ID pairing; runtime retains only owner and paired; tool execution checks only a fixed constant table. Unpaired group sources are archived as pending without proactive synthesis. Detailed decisions:authority-handoff.md.
Requests carry only the owner/paired enum. Unknown accounts receive an eight-character pairing code; approval uses local owner channels only (terminal/local Web), never channel messages. No migration code: after rollout, all non-owner accounts pair on first contact. Mutable nicknames do not determine identity. Display names are sanitized. Rejections return structured reason codes.
trust_state marked pending. Retrieval distinguishes speakers and does not automatically recall these sources into context.openprogram memory backfillProcess trusted Sources not referenced by Topics and exclude pending sources. Failed batches are not installed; repeated execution skips referenced sources. Writer status from tools, CLI and Web includes last success, last failure classification, retryability and pending counts.memory.backend=none rejects all CLI memory verbs and /api/memory/* routes before workspace creation.
Unauthorized requests from paired members, such as “restart the service,” enter a queue for one-time owner approval. Memory reads are filtered by requester tier; write-side attribution metadata is already implemented.
memory.writer.model supports live overrides. Unknown exceptions default to non-retryable. Exact compatibility reads parsed all 154 frames in 23 old v1 source files from the real workspace. A real writer acceptance committed two pending messages as three Topic files and five blocks; a repeated scan processed zero sessions without changing the revision. Backfill, writer status, CLI/Web disabled boundaries, paired naming and integration tests are implemented; real-workspace backfill for 152 historical unreferenced Sources has not run. Write-failure reason codes form a closed enum. Restricted writer stages cannot see Source archives.