MCP 服务

SAGE|AI Agent 受治理的持久记忆与协作层

SAGE

为具备 MCP 能力的 AI 客户端提供本地运行、经签名入账与权限治理的持久记忆、任务和消息协作层。

获取与使用

需要部署

按官方资料自行安装或部署

使用难度待核验
国内可用性待核验

2026-11-09 更新 · 本站尚未实测

项目介绍

MCP 服务 · 2026-11-09 更新 · 本站尚未实测

SAGE(Sovereign Agent Governed Experience)是面向 AI Agent 的“受治理记忆与消息层”。按 README 描述,它让 Agent 记录的经验经过签名、可审查的准入流程、权限范围控制和可追溯审计,而不是把对话直接堆进向量库。记忆默认保存在本地,可通过本地节点让不同客户端共享同一份经验;开发者也可用 Python SDK 或带签名的 REST API 接入。

README 说明它可与 Claude Code、Codex、Cursor 以及其他支持 MCP 的客户端配合使用。需要注意的是,能否召回取决于实际记录了什么、配置方式以及 Agent 是否调用了相应工具。

核心能力

点击能力名称查看输入、输出和原文依据。

  • 受治理记忆:记忆由 Agent 签名写入,经准入生命周期后进入常规召回,并带有置信度、状态与衰减/弃用控制。
  • 访问控制:通过 Agent 注册、角色与配置、Access Group、域权限和分类检查决定谁能读写哪条记忆。
  • 持久任务与统一收件箱:支持指定到具体 Agent 的任务、请求领取、幂等回复,以及本地/联邦消息的收件箱与回复页。
  • 运行时交接:在同一签名 Agent 身份下,按会话与修订号进行受控工作交接。
  • 受控联邦:以显式信任和只读/复制策略连接不同 SAGE 链,不直接授予本地成员或写权限。
  • 本地控制面板 CEREBRUM:在浏览器中查看记忆脑图、链健康、Agent、联邦、召回设置、任务与更新。
  • 恢复与升级:支持原地链升级、恢复快照与重启后消息领取保留。

个人模式只运行一个 CometBFT 验证节点,不具备拜占庭容错冗余;多验证者部署才需要 BFT 法定人数。README 明确指出,这些机制治理的是“什么被提交”,并不证明每条记忆内容为真,也不会改变模型权重。

实际应用场景

适用场景

  • 需要跨会话保留设计决策、失败教训和项目经验的长期编码或研究型 Agent。
  • 多 Agent 之间需要可审计的任务分派、请求领取与回复,而非仅靠聊天上下文传递。
  • 希望记忆默认留在本地、并能人工检查与撤销的团队或个人。
  • 需要从小规模个人节点逐步演进到多验证者、联邦部署的组织。

若只想要一次性问答或简单 RAG 检索,SAGE 提供的额外治理与部署成本可能不必要。

安装与接入

README 给出的获取方式包括桌面安装包(macOS DMG、Windows EXE、Linux tar.gz)和容器镜像。桌面版下载后打开 SAGE,在 CEREBRUM 中完成设置,再按连接指南接入 AI 客户端。

源码构建方式(Go 1.26.10+)原文为:

git clone https://github.com/l33tdawg/sage.git && cd sage
go build -o sage-gui ./cmd/sage-gui/
./sage-gui setup    # Pick your AI, get MCP config
./sage-gui serve    # SAGE + Dashboard on :8080

Docker 方式原文为:

docker pull ghcr.io/l33tdawg/sage:latest
docker run -d --name sage \
  -p 8080:8080 \
  -v ~/.sage:/root/.sage \
  ghcr.io/l33tdawg/sage:latest

如需让本地 MCP 客户端通过 stdio 桥接,README 要求在同一个运行中的容器内另起进程,并传入 SAGE_PROVIDER、SAGE_PROJECT 与 SAGE_IDENTITY_PATH;具体命令与 Compose 变体请按原文执行。HTTP MCP 位于 /v1/mcp/sse 与 /v1/mcp/streamable,需要 bearer token 或 OAuth;裸 http://localhost:8080 是 REST 基址,并非免认证 MCP 端点。

启动前可检查节点:

curl http://127.0.0.1:8080/health

健康时返回 {"status":"healthy"}。连接 MCP 客户端后,README 建议调用 sage_inception 并遵循其返回的记忆模式。Python 侧需 Python 3.10+、运行中的节点和已注册的 Agent,SDK 安装命令原文为 python -m pip install sage-agent-sdk。

使用条件与限制

是否需要部署
需自行准备运行环境,具体要求见正文
是否需要注册
账号和认证要求见正文;未明确说明的项目仍待核验
是否需要 API Key
待核验
费用与额度
费用边界见正文,项目许可不代表模型或托管服务免费
所需权限
待核验
许可证与服务条款
待核验

权限费用与限制

  • 权限模型:记忆写入需 Agent 签名,读取受注册状态、域权限、Access Group 和分类约束;CEREBRUM 提供人工控制与凭证交接。README 强调 Agent 请求与结果都视为不可信数据,不能用来扩大用户指令权限。
  • 本地与外部数据:记忆默认本地;可选的联邦、连接器和远程模型提供方会把数据发送到所配置的目的地。启用 vault 可对静态记忆内容加密。
  • 共识边界:单验证者个人模式没有拜占庭冗余;多验证者与联邦需要单独配置。
  • 费用:README 未说明软件本身是否收费、是否存在商业模块或托管服务,也未给出价格,需向官方核验。
  • 模型与外部依赖:README 提到可接入 Claude Code、Codex、Cursor 等 MCP 客户端,并提及可选远程模型提供方和本地记忆评审模型;具体支持的模型清单、API Key 要求及国内可用性,资料未完整说明,待核验。
  • 平台:README 列出 macOS、Windows、Linux 安装包;国内网络下容器镜像与下载可达性待核验。

国内使用情况

网友核验 用户经验分享

与站长实测独立,不代表官方认证或本站已实测。

我要核验
0 位参与者0 份有效分项记录

最近核验:暂无有效核验。参与人数按当前项目有效身份去重;不同核验项分别统计,不合并成用户总结果。仅统计审核通过且未过期的记录。

分项统计、有效期与样本量
核验项目有效人数成功 / 部分 / 失败 / 无法判断成功率最近核验 / 有效期
官方网站访问00 / 0 / 0 / 0样本不足暂无 / 7 天
GitHub 仓库访问00 / 0 / 0 / 0样本不足暂无 / 7 天
安装与运行00 / 0 / 0 / 0样本不足暂无 / 30 天
官方服务国内连接 / MCP 连接00 / 0 / 0 / 0样本不足暂无 / 30 天
国内网络情况00 / 0 / 0 / 0样本不足暂无 / 7 天
国内模型兼容性00 / 0 / 0 / 0样本不足暂无 / 30 天
自定义 API00 / 0 / 0 / 0样本不足暂无 / 30 天
海外服务依赖
00 / 0 / 0 / 0样本不足暂无 / 30 天
海外账号要求
00 / 0 / 0 / 0样本不足暂无 / 30 天
中文界面
00 / 0 / 0 / 0样本不足暂无 / 30 天
客户端兼容性00 / 0 / 0 / 0样本不足暂无 / 30 天
账号及费用信息
00 / 0 / 0 / 0样本不足暂无 / 30 天

成功率 = 成功 ÷(成功 + 部分成功 + 失败);无法判断不计入分母。至少 5 份可判断结果才显示成功率。账号、费用、海外依赖与语言等事实项,成功表示核查结论与资料吻合,具体观察另行统计;不表示免费或没有海外依赖。不同网络、客户端和版本的结果不能直接等同。

最近有效核验

暂无审核通过且未过期的网友核验。欢迎提交真实使用记录。

查看全部有效核验 →

国内实测状态:国内可用性待核验。协议兼容和官方资料说明不等于国内网络可用。

官方网站访问
尚未实测 待核验
GitHub 仓库访问
尚未实测 待核验
官方服务国内连接
尚未实测 待核验
国内网络情况
尚未实测 待核验
国内模型兼容性
尚未实测 待核验
自定义 API
尚未实测 待核验
海外服务依赖
尚未实测 待核验
海外账号要求
尚未实测 待核验
中文界面
尚未实测 待核验
国内最后核验时间
尚未实测

许可与国内使用

仓库 LICENSE 文件为 Apache License 2.0,版权声明年份为 2026。该许可适用于仓库中标注的代码;README 未明确区分商业模块、托管服务或第三方模型的授权与费用,这些部分需分别向官方核验。公开仓库不等于全部功能或依赖免费。

关于中国大陆网络环境下的下载、镜像拉取、OAuth 与远程模型调用是否可用,现有资料没有说明,需实际核验。项目未显示已归档或停止维护。

项目资料与来源

官方网站 ↗

GitHub 仓库 ↗

官方文档 ↗

字段依据与待核验事项

access:来源确认 · docker pull ghcr.io/l33tdawg/sage:latest

project_type:来源确认 · Works with Claude Code, Codex, Cursor and other MCP-capable clients. Developers can integrate through the Python SDK or signed REST API.

原始 README(折叠技术参考)
# (S)AGE — Sovereign Agent Governed Experience

![SAGE: governed memory for AI agents, with a lavender neural brain](docs/brand/sage-twitter-cover.png)

**Memory your agents can be held to.**

SAGE is a governed memory and messaging layer for AI agents. Every memory is
signed by an agent, admitted through a reviewable process, scoped by permissions
you set, and kept with an audit trail you can inspect.

Connect your tools to the same local node so authorized agents can record
experience and recall relevant context in later sessions. Inspect what they keep
in CEREBRUM, SAGE's local dashboard.

Works with Claude Code, Codex, Cursor and other MCP-capable clients. Developers
can integrate through the Python SDK or signed REST API. Recall depends on what
is recorded, your configuration and the agent's use of its tools.

[Download SAGE](https://github.com/l33tdawg/sage/releases/latest) ·
[Get started](https://l33tdawg.github.io/sage/#get-started) ·
[Connect your AI](https://l33tdawg.github.io/sage/connect.html) ·
[Developer quickstart](https://l33tdawg.github.io/sage/#developers)

[Why SAGE](#why-sage) · [Quick Start](#quick-start) · [For Developers](#for-developers) · [Architecture](#architecture) ·
[Capabilities](#current-capabilities) · [Dashboard](#cerebrum-dashboard) ·
[Release history](#release-history) · [Documentation](#documentation)

<a href="https://glama.ai/mcp/servers/l33tdawg/s-age">
  <img width="380" height="200" src="https://glama.ai/mcp/servers/l33tdawg/s-age/badge" alt="(S)AGE MCP server" />
</a>

---

## Why SAGE

Use SAGE when your agents return to ongoing work: a design decision worth
keeping, an approach that failed, or a lesson the next session should use.
RAG retrieves source material; SAGE uses retrieval too, with a governed record
of agent experience around it.

- **Trace the origin.** Agent-signed writes attribute memories to their recorded author.
- **Review admission.** Memories pass through a validation lifecycle before they enter normal recall.
- **Control access.** Enrollment, domain permissions and classification determine which agents can use a memory.
- **Keep memory useful.** Inspect confidence and status, apply decay, or deprecate a memory while retaining its audit history.

A personal install runs one validator and casts its own signed admission vote.
A multi-validator network requires a BFT quorum. These checks govern what is
committed; they do not prove every remembered claim is true or change your
model's weights. See the [memory lifecycle](docs/reference/concepts/memory-lifecycle.md)
and [consensus reference](docs/reference/concepts/consensus-confidence-decay.md).

Memory is local by default. Optional federation, connectors and remote model
providers can send data to configured destinations. Enable the vault for
memory-content encryption at rest; see the [privacy details](https://l33tdawg.github.io/sage/privacy.html)
and [Security FAQ](SECURITY_FAQ.md).

## Quick Start

**Desktop:** [Download the latest release](https://github.com/l33tdawg/sage/releases/latest),
open SAGE and complete setup in CEREBRUM. Choose your memory engine, connect an
AI client and review agent access. Follow the
[connection guide](https://l33tdawg.github.io/sage/connect.html) for your tool or
the full [Getting Started](docs/GETTING_STARTED.md) walkthrough.

If SAGE is already running, check it before starting another server:

```bash
curl http://127.0.0.1:8080/health
```

A healthy node returns `{"status":"healthy"}`. After connecting an MCP client,
call `sage_inception` and follow its returned memory mode.

<details>
<summary>Build from source</summary>

**From source (Go 1.26.10+):**

```bash
git clone https://github.com/l33tdawg/sage.git && cd sage
go build -o sage-gui ./cmd/sage-gui/
./sage-gui setup    # Pick your AI, get MCP config
./sage-gui serve    # SAGE + Dashboard on :8080
```

</details>

Desktop packages: [macOS DMG](https://github.com/l33tdawg/sage/releases/latest) (signed & notarized) | [Windows EXE](https://github.com/l33tdawg/sage/releases/latest) | [Linux tar.gz](https://github.com/l33tdawg/sage/releases/latest)

<details>
<summary>Docker and containerized MCP setup</summary>

### Docker

```bash
docker pull ghcr.io/l33tdawg/sage:latest
docker run -d --name sage \
  -p 8080:8080 \
  -v ~/.sage:/root/.sage \
  ghcr.io/l33tdawg/sage:latest
```

Pin a specific version with `ghcr.io/l33tdawg/sage:11.25.4`.

The SAGE server stays in that container. To give a local MCP client a stdio
bridge, start a second process **inside the same running container**:

```bash
docker exec -i \
  -e SAGE_PROVIDER=claude-code \
  -e SAGE_PROJECT=my-project \
  -e SAGE_IDENTITY_PATH=/root/.sage/agents/claude-code-my-project/agent.key \
  sage /usr/local/bin/sage-gui mcp
```

For the shipped Compose stack, use the service name rather than a generated
container name:

```bash
docker compose -f docker-compose.sage-gui.yml exec -T \
  -e SAGE_PROVIDER=claude-code \
  -e SAGE_PROJECT=my-project \
  -e SAGE_IDENTITY_PATH=/root/.sage/agents/claude-code-my-project/agent.key \
  sage /usr/local/bin/sage-gui mcp
```

If an MCP client launches this through a wrapper, point its stdio configuration
at the wrapper's absolute path. Pass `SAGE_PROVIDER`, `SAGE_PROJECT`, and
`SAGE_IDENTITY_PATH` through `docker exec -e`/`docker compose exec -e`; setting
them only on the host-side Docker command does not place them in the container.
Keep the whole SAGE data root mounted at `/root/.sage`, including agent keys and
the ledger. Do not start a separate `docker run ... mcp` container: its
`localhost:8080` is isolated from the running SAGE server.

HTTP MCP is also available at `/v1/mcp/sse` and `/v1/mcp/streamable`, but both
require a bearer token or OAuth. Bare `http://localhost:8080` is the REST base,
not an unauthenticated MCP endpoint.

</details>

<details>
<summary>Upgrading an existing node</summary>

### Upgrading from an older version?

**Upgrading an existing node — including the v10.x → v11 jump — is
[docs/UPGRADING.md](docs/UPGRADING.md).** In the desktop app, accept the update:
SAGE verifies canonical upgrade compatibility, captures a full recovery
snapshot, installs, and restarts automatically. Headless and quorum operators
have separate technical procedures in the guide.
Your chain advances in place; a personal node climbs the consensus fork ladder by
itself. Read the guide before a multi-admin chain crosses app-v23 — that
activation re-derives administrator authority.

If you installed SAGE before v5.0 and your AI isn't doing turn-by-turn memory updates, re-run the installer in your project directory:

```bash
cd /path/to/your/project
sage-gui mcp install
```

This installs Claude Code hooks that prompt the memory lifecycle (boot, turn, reflect) — even if your `.mcp.json` is already configured. Restart your Claude Code session after running this.

</details>

---

## For Developers

Choose an integration for your workflow:

| Integration | Use it for | Start here |
| --- | --- | --- |
| MCP | Giving an existing AI client memory and coordination tools | [Connection guide](https://l33tdawg.github.io/sage/connect.html) · [MCP reference](docs/reference/mcp-tools.md) |
| Python SDK | Building a memory-aware agent or application with sync/async clients | [Developer quickstart](https://l33tdawg.github.io/sage/#developers) · [SDK reference](docs/reference/python-sdk.md) |
| Signed REST API | Integrating from another language over HTTP | [REST reference](docs/reference/rest-api.md) |

The [authoritative reference index](docs/reference/INDEX.md) covers exact API
behavior, authentication, access controls and lifecycle rules. Start there
when implementing an integration.

### Python: read existing memories

Requires Python 3.10+, a running node and an enrolled agent. Set
`SAGE_IDENTITY_PATH` to that agent's existing key file and `SAGE_DOMAIN` to a
domain it can read.

```bash
python -m pip install sage-agent-sdk
```

```python
import os
from sage_sdk import AgentIdentity, SageClient

identity = AgentIdentity.from_file(os.environ["SAGE_IDENTITY_PATH"])
domain = os.environ["SAGE_DOMAIN"]

with SageClient(
    base_url="http://127.0.0.1:8080",
    identity=identity,
    trust_env=False,
) as client:
    page = client.list_memories(
        domain=domain, status="committed", limit=3,
    )
    for memory in page.memories:
        print(memory.memory_id, memory.content)
```

Save as `quickstart.py` and run `python quickstart.py`. An empty list means no
committed memories are visible to this agent in that domain. Review enrollment
and domain permissions in CEREBRUM if access is denied.

To record experience, use `propose()` in a domain the agent can write to and set
classification explicitly. A submitted memory starts as `proposed`; normal
recall includes it after admission commits it. For semantic retrieval, use
`hybrid()` with query text and a matching embedding. See the
[SDK examples](docs/reference/python-sdk.md) and
[memory admission guide](docs/reference/concepts/voter-operations.md).

---

## Architecture

```mermaid
flowchart TB
    A["AI agents · MCP / SDK / REST"] --> P["SAGE node · authenticated admission + live policy"]
    H["CEREBRUM · local human control"] --> P
    P --> M["Memory + local policy transactions<br/>CometBFT / ABCI"]
    P --> W["Node-local coordination<br/>inbox / claims / replies"]
    M --> B["BadgerDB<br/>authoritative chain state"]
    B --> Q["Commit-time SQL projection<br/>content + vectors for authorized recall"]
    P -. "explicit peer trust and sharing" .-> F["Separate SAGE chain<br/>bounded Read / receiver-controlled Copy"]
    classDef entry fill:#eef2ff,stroke:#6366f1,color:#1e293b
    classDef memory fill:#ecfdf5,stroke:#059669,color:#064e3b
    classDef work fill:#fff7ed,stroke:#d97706,color:#7c2d12
    class A,H,P entry
    class M,B,Q memory
    class W,F work
```

**Agents are not validators.** Personal mode runs one real CometBFT validator
with a per-node memory auto-voter; it has no Byzantine redundancy. Registering
more agents does not add consensus voters. A multi-validator deployment runs
one shared chain; federation connects separate chains under explicit policy.

**Storage has two roles.** BadgerDB is authoritative for consensus state.
SQLite (personal) or PostgreSQL + pgvector (cluster) projects memory content
and vectors at Commit. Node-local message coordination is separate from the
memory consensus path. Block inclusion is not the same as memory acceptance.

For the detailed trust boundaries, lifecycles, and deployment topology, see
[Architecture & Deployment](docs/ARCHITECTURE.md).

## Current Capabilities

| Capability | What it provides |
|------------|------------------|
| Governed memory | Persistent, attributed memories with consensus validation, semantic recall, confidence, and lifecycle controls |
| Durable tasks | Exact-agent assigned backlog; open tasks do not decay; idempotent creation and workflow status |
| Unified inbox | Local/federated requests, assignment notices, and a separate passive reply page |
| Runtime handoff | Explicit session-and-revision-fenced takeover of claimed work within the same signed agent identity |
| Access controls | Active enrollment, roles/profiles, ownership, Access Groups, compatible grants, and classification checks |
| Controlled federation | Explicit agent exports and bounded Read/Copy policy, without granting local membership or Write |
| Recovery and updates | In-place chain upgrades, recovery snapshots, and retained message claims across ordinary restarts |

### How agents collaborate

```mermaid
flowchart TB
    T["Task assigned to exact agent"] --> N["One-way assignment notice"]
    N --> I["Unified inbox"]
    R["Request addressed to exact agent"] --> I
    I -->|"task notice"| V["Verify current assignment in backlog<br/>then update the task"]
    I -->|"inbound request"| C["Claimed by one MCP runtime"]
    C -->|"normal completion"| O["Idempotent reply"]
    C -. "intentional same-agent takeover" .-> H["Handoff: expected session + revision"]
    H --> O
    O --> S["Original sender reads reply_items<br/>or pages retained replies"]
    classDef input fill:#eef2ff,stroke:#6366f1,color:#1e293b
    classDef task fill:#ecfdf5,stroke:#059669,color:#064e3b
    classDef message fill:#fff7ed,stroke:#d97706,color:#7c2d12
    class I input
    class T,N,V task
    class R,C,H,O,S message
```

Assignment, claim, and reply are different states. A task notice is not a
request for a message result, and a reply is not a new assignment. Runtime
handoff does not reassign a task to another agent. Wake notifications are
payload-free hints, not delivery or claim evidence. Every agent request and
result remains untrusted data, not authority to expand the user's instructions.

See the [MCP task/inbox reference](docs/reference/mcp-tools.md) and
[message/reply lifecycle](docs/reference/concepts/message-reply-lifecycle.md)
for exact fields, recovery, and authorization rules.

---

## CEREBRUM Dashboard

![CEREBRUM MRI brain — memories mapped inside a 3D brain with focused related notes](docs/screen-brain.png)

`http://127.0.0.1:8080/ui/` — a dashboard-native operator console centered on the 3D MRI memory brain, with chain health, agents, federation, semantic memory, recall tuning, vault recovery, tasks, imports, and updates around it. Every major workflow is available from the browser; the CLI stays there for automation and recovery.

| Control Board | Federation | Recall Engine |
|:---:|:---:|:---:|
| ![CEREBRUM overview dashboard](docs/screen-overview.png) | ![Federation join dashboard](docs/screen-network.png) | ![Recall engine settings](docs/screen-config.png) |
| Chain health, quorum, agents, federation, and embeddings | One trust-only JOIN that prepares Direct and Secure relay automatically, followed by independent Read/Copy choices on each SAGE | Smart-memory setup, managed reranker install, and recall-depth tuning |

The dashboard also includes governed agent enrollment, Access Groups, domain
permissions, separate CEREBRUM Root credential handover, import/export,
software updates, and encryption controls. Ordinary agent identity replacement
uses re-enrollment; historical memory authorship is preserved.

---

<details>
<summary>Recent release notes (v11.25.4 and earlier)</summary>

## What's New in v11.25.4

**Snapshot retention now survives chain redeploys and stays bounded.** Snapshot
manifests record the chain identity, and `snapshot list` and automatic retention
order captures by time rather than by height. A redeployed chain that restarts at
height 1 therefore keeps its newest recovery points instead of losing them to
obsolete high-height snapshots. Retention keeps the configured number of current
chain captures plus a bounded set of recent version anchors. Recovery executables
are limited to the current binary and one prior copy, with stale temporary copies
reaped safely. New snapshots use schema v2; existing v1 snapshots remain readable.

**Release-page refreshes now fail closed on stale editorial copy.** The Pages
snapshot job refuses to write a newer version stamp when the landing page's
What's New block, FAQ, or version-pinned documentation links still describe an
older release. Dynamic download counts remain automatic; release copy must move
with them.

No consensus version change, app-version change, chain reset, or data migration.
`latest` and automatic upgrade voting remain app29; app30 remains explicit.
Container: `ghcr.io/l33tdawg/sage:11.25.4`. SDK 11.25.4.

## What's New in v11.25.3

**Memory submit now reports fields it did not apply.** Unknown top-level body
keys are still accepted and ignored for compatibility, but the response names
them in a bounded, sorted `ignored_fields` array and the node logs a warning
without their values. This makes a correction-shaped request visible when a
client sends fields such as `replaces_memory_id` to a route that only stores the
replacement memory. Corrections still use submit, wait for commit, then challenge
the old memory.

**The Go dependency baseline closes two high-severity pgx vulnerabilities.**
`pgx` moves to 5.12.0 for the simple-protocol batch SQL-injection and
authentication-requirement fixes, with `puddle` 2.2.3. The SQLite driver moves
to 1.61.1 for prepared-statement and read-only VFS correctness. The test-only
PostgreSQL mock moves to its pgx-5.12-compatible v6 line.

No consensus version change or chain migration. `latest` and automatic upgrade
voting remain app29; app30 remains explicit.

## What's New in v11.25.2

**Fresh-node setup imports now use the enrolled Companion identity.** On a new
post-v23 chain, the setup wizard's pending memories previously tried to embed and
submit as the genesis Root, which is deliberately not an ordinary agent. The
import now signs as the enrolled Companion, routes an unqualified entry to that
Companion's home domain, and reports embed, submit, and zero-import failures at
visible log levels instead of producing only `Imported 0/N`.

**The optional local memory judge is pinned to v17b.** The default-off managed
judge now uses a separate immutable model artifact, verifies both the downloaded
GGUF and Ollama's registered blob, and keeps explicit v16 selections unchanged.
The v17b training pass targets the short user decisions and task-shaped memories
that v16 often rejected or held, while retaining the chat-only and session-remark
traps. New writing guidance is linked from the write-gate reference.

No consensus version change or chain migration. `latest` and automatic upgrade
voting remain app29; app30 remains explicit.

## What's New in v11.25.1

**AMID can approve a distinct local agent.** Operators can opt into `--local-agent-key-dir` (`SAGE_LOCAL_AGENT_KEY_DIR`) to supply identity-bound target consent keys to the existing access-policy route and Python SDK methods. Root authorization, same-machine checks, and consensus validation remain required. Unregistered targets are refused before signing or broadcast, and malformed Ed25519 private-key encodings fail closed.

**Hybrid recall sizes reranking work from the requested results.** The authorization scan retains its full candidate coverage while the cross-encoder scores the smaller requested pool. `SAGE_RERANK_MAX_CANDIDATES` adds an optional cap. Rate-limited fallback warnings expose operational failures without logging upstream error text or submitted content.

**Explicit federation settings survive config saves.** Disabled P2P, an empty relay list, and disabled force-private mode no longer disappear during serialization and revert to defaults on reload.

**Force-quitting the macOS tray no longer leaves its daemon orphaned after startup.** The tray identifies itself to its child; once graceful shutdown is ready, the daemon monitors that parent and stops if it disappears. Standalone and externally supervised daemons remain independent unless explicitly configured with the parent relationship.

No consensus version change or chain migration. `latest` and automatic upgrade voting remain app29; app30 remains explicit. Existing reply catch-up and v11.24.4 fixes are already included through release history.

Container: `ghcr.io/l33tdawg/sage:11.25.4`. SDK 11.25.4.

## What's New in v11.25.0

**Fresh chains start at the supported app version.** A new personal `sage-gui serve`
starts directly at app29. For a shared chain, create one signed, full-roster
artifact with `init-genesis`, then run `init-fresh-node` on each Unix node against
its exact genesis digest before starting `serve`. Existing chains keep their
keys, genesis and governed upgrade history. See the
[fresh-genesis guide](docs/reference/fresh-genesis.md).

**App30 taint and authenticated lineage ship as explicit rules.** The merged
implementation includes immutable multi-parent `derived_from` references,
governed apply/clear decisions, bounded canonical traversal, provenance and
recovery/state-sync support. `latest` and automatic upgrade voting remain at
app29; an explicit signed app30 genesis or quorum-approved plan selects app30.

**The native-shell control contract accepts v11.25 daemons.** Native standalone
packages retain their preview identity and separate promotion requirements.
Evidence-operator integration and complete count, coverage and error parity
across clients/backends remain open in [#460](https://github.com/l33tdawg/sage/issues/460).

Container: `ghcr.io/l33tdawg/sage:11.25.0`. SDK 11.25.0.

## What's New in v11.24.5

**Task identity is now domain-aware.** App-v23 tasks use their permanent idempotency identity—caller, exact signed domain, canonical `[TASK]` content, or an explicit occurrence key—instead of the global memory-content tombstone. The same task body can exist as a distinct task in another governed domain without being deprecated after consensus.

**Deprecated tasks can no longer mutate.** REST and the SQLite and PostgreSQL stores reject claim, completion, and status changes on deprecated task rows, so a full-ID update cannot report success against a task that has disappeared from the backlog.

**No app-version or data migration.** App-v29 remains active. Container: `ghcr.io/l33tdawg/sage:11.24.5`. SDK 11.24.5.

## What's New in v11.24.4

**macOS restarts now recover without Activity Monitor cleanup.** The tray keeps `sage-gui serve` supervised, restarts unexpected exits with bounded backoff, detects a live child that stops answering health checks, and retains the unlocked passphrase for the replacement process. Daemon logs are appended so a failed restart keeps its evidence.

**Shutdown no longer lets transport teardown strand an update.** MCP HTTP and federation P2P close stages are bounded. A timeout is logged without rolling back an otherwise valid update or preventing the replacement process from starting.

**CEREBRUM makes the restart wait visible.** The updater now shows a live five-minute countdown and phase-specific status while SAGE finishes in-flight work, closes its listener, starts the replacement, and reconnects. The countdown keeps moving even while a request or health probe is waiting on the network.

**No consensus change or chain migration.** App-v29 remains active. Container: `ghcr.io/l33tdawg/sage:11.24.4`. SDK 11.24.4.

## What's New in v11.24.3

**AMID exposes the signer-fence recovery surface without requiring CEREBRUM.** Operator-only `GET /v1/dashboard/signer-fence/status`, `POST /v1/dashboard/signer-fence/lift`, and `POST /v1/dashboard/signer-fence/abandon` routes now serve the cluster runtime. The exact configured governance operator must sign each request; caller-supplied proofs and evidence are rejected, request bodies are bounded, and the node rereads committed nonce, transaction, mempool, and peer state before every recovery decision.

**AMID health now follows the external Comet engine.** After the chain identity binds, AMID continually probes the configured CometBFT RPC `/health`, clears its Comet health bit on failure, and restores it after recovery. The compose validators use `restart: unless-stopped`, preserving deliberate operator stops while restarting unexpected exits.

**Public SAGE-Noesis outcome receipts establish an evidence-only interop boundary.** Receipt v1 is public-only, signed, off-consensus, and carries no REST or MCP route. It records reproducible control/treatment evidence without granting valuation, stake, governance, access, or memory authority to Noesis.

**No consensus change or chain migration.** App-v29 remains active. Container: `ghcr.io/l33tdawg/sage:11.24.3`. SDK 11.24.3.

## What's New in v11.24.2

**PostgreSQL stats now exclude deprecated memories from totals and per-domain counts, matching SQLite.** Status counts and last activity retain their audit history.

**CEREBRUM timelines now include in-range memories at fractional-second date boundaries.** Whole-second and fractional bounds keep exact inclusive timestamp checks and canonical visibility checks.

**No consensus change or chain migration.** App-v29 remains active. Container: `ghcr.io/l33tdawg/sage:11.24.2`. SDK 11.24.2.

## What's New in v11.24.1

**App-v29 now activates automatically after its evidence gates pass.** The auto-vote readiness ceiling moves from app-v28 to app-v29, so personal nodes converge on the architecture-independent PoE arithmetic already compiled in v11.24.0. The activation block keeps app-v28 behavior; deterministic EWMA, recency, corroboration, logarithm, exponential and final-weight calculations begin at H+1. Historical blocks continue to replay under their original app versions.

**The app-v29 evidence spans the real failure surfaces.** A four-validator ladder crosses app-v2 through app-v29 with byte-identical AppHash at H-1, H and H+1, then continues through the first post-activation PoE epoch. A separate quorum runs two validators and CometBFT processes on arm64 and two on amd64 against one chain. The real-process crash, partition, restart and state-sync gate targets exact app-v29 state.

**The patch closes the release security gaps.** Go 1.26.10 fixes GO-2026-6809 in `crypto/x509`; certifi 2026.10.19 removes the compromised emSign intermediate CA bundle from all benchmark environments; and the dependency group updates chi, klauspost/compress, go-winio, Playwright and pinned GitHub Actions.

**No chain migration.** Existing memories, identities, governance state and chain history are preserved. Container: `ghcr.io/l33tdawg/sage:11.24.1`. SDK 11.24.1.

## What's New in v11.24.0

**PoE weights now have an architecture-independent path.** App-v29 compiles a new consensus form of the proof-of-experience arithmetic: EWMA state updates, recency, corroboration and final weights use explicitly rounded operations that produce the same float64 bits on arm64 and amd64. The gate remains dormant above the app-v28 auto-vote ceiling, so existing chains keep their current app version and historical blocks keep replaying under their original arithmetic until the mixed-architecture, replay, snapshot and state-sync evidence is complete. CI and release workflows now run exact golden vectors on native amd64 and arm64.

**Org fleet enrollment Phase 1 lands.** Organizations can issue 24-hour, single-use tokens bound to one exact node key and immutable policy scope. Redemption atomically stores the consume marker, replayable result and first signed policy in node-local SQLite; concurrent attempts cannot overwrite the winner, and a lost response can be replayed even after token expiry or revocation. Signed policy delivery adds monotonic revisions, rollback protection, persisted rotation history and overlap, a durable owner-visible equivocation alarm, and per-operation offline/expiry gates for enrollment and new peering. `sage-gui org-token create|list|revoke` exposes the operator flow.

**No chain migration.** App-v28 remains active and app-v29 remains compiled but dormant. Existing memories, identities, governance state and chain history are preserved. Container: `ghcr.io/l33tdawg/sage:11.24.0`. SDK 11.24.0.

## What's New in v11.23.27

**Find the exact MCP session before a handover.** `sage_sessions` is a new read-only, self-only inventory of this agent's live MCP claimant sessions on the local node. It returns each exact `session_id`, transport kind, provider/project, whether it is the current session, liveness from the same OS advisory lock used by claimant identity acquisition, and the exact count of unfinished claims held by that session. Stale identity records are counted separately and are not presented as live sessions. The tool never claims, hands off, replies, or grants authority; session IDs remain coordination metadata, not authorization principals.

**Access Group controls say what they do.** CEREBRUM's Access Group editor now labels its close and delete actions accurately instead of putting Delete in the conventional close slot.

**No chain migration.** App-v28 remains active. The MCP catalog grows to 38 tools; clients with a cached catalog should re-list or reconnect. Container: `ghcr.io/l33tdawg/sage:11.23.27`. SDK 11.23.27.

## What's New in v11.23.26

**App-v28 activation now succeeds on legacy public corpora.** The public-memory stage is built before the activation block's consensus transaction, so a record it could not encode aborted the activation on every replay and left the pending plan with no in-band downgrade. Records born before app-v25 whose canonical envelope lacks a domain, author, or author principal, carries a non-32-byte content hash, or carries a co-commit tombstone are now quarantined out of the committed public set instead of refusing the build. Records born under app-v25 or later still fail closed, and a recorded-but-empty or malformed field still refuses on every record. A record returns to the public set in the block that re-anchors its envelope.

**Preflight now checks the corpus before the fork.** `sage-gui upgrade preflight` runs the same read-only census as `sage-gui upgrade public-memory-audit` when a chain still has to cross app-v28, and refuses "clear to climb" when a record would block activation. The audit names every record, the exact failed checks, and whether the stage would quarantine or refuse it. `--limit` bounds the printed list; the counters still cover the whole corpus.

**Quarantined records are visible, not silent.** The audit reports them by memory id, and they stay outside the app-v28 public-memory tree until re-anchored. No chain migration is required; app-v28 remains active.

Container: `ghcr.io/l33tdawg/sage:11.23.26`. SDK 11.23.26.

## What's New in v11.23.25

**Unscoped recall works again on a mature node.** An app-v23 node refuses a ranked recall whose candidate set exceeds its authorization scan budget rather than ranking an arbitrary prefix. On a node with a large corpus that made a domainless `sage_recall` fail permanently — the tool's default shape. Recall now falls back once to your governed home domain and reports the effective scope in `domain`, `recall_scope` and `recall_scope_note`, so an empty home-domain result is never read as proof the memory does not exist elsewhere. An explicitly scoped recall is never redirected.

**Federated recall is bounded, and says why it is empty.** `/v1/federation/recall-plan` now carries a server-side deadline with a per-peer budget, so one unreachable peer can no longer hold the request open until the caller gives up. An empty plan reports `unavailable_reason` — `no_active_agreement`, `requested_chains_not_connected`, `peer_unreachable`, `domain_not_shared`, `planner_unavailable` or `federation_unavailable` — instead of an empty error map that read as an authorization verdict. The reasons are aggregate by design and never name a peer.

**Federated agents appear inside their Access Group.** A federated agent linked to a local Access Group is now shown with the local members, with its authority stated. Federated write remains unavailable: it requires a consensus-bound federation ingress capability.

**Product-specific bootstrap policy leaves core.** A root-owned provisioning profile now drives `init-fresh-personal-sage` and `check-private-config`. SAGE core no longer carries any one product's home path, Unix account, or unit list. Products that shipped `init-lantern-private` must ship the profile and update their scripts before pinning this release.

App-v28 remains active and no chain migration is required.

Container: `ghcr.io/l33tdawg/sage:11.23.25`. SDK 11.23.25.

## What's New in v11.23.24

**Find agents across connected SAGEs in one call.** `sage_find_agent(name="...")` searches this SAGE and caller-authorized contacts on connected SAGEs together by default. Exact name matches rank first in one bounded list. Local matches no longer hide remote matches, and same-named agents keep distinct exact addresses so you can choose the intended recipient.

Use `scope="local"` to search only this SAGE, or `peer_chain` to select one connected SAGE. If federated discovery cannot be verified, local matches remain available with an explicit incomplete flag. Cached contacts retain their caller-specific authorization checks, and each continuation still reads one bounded peer page.

MCP descriptions and message guidance now point to the combined lookup. After upgrading, re-list tools or reconnect clients with a cached catalog to load the new parameter and guidance. App-v28 remains active and no chain migration is required.

Container: `ghcr.io/l33tdawg/sage:11.23.24`. SDK 11.23.24.

## What's New in v11.23.23

**Close reviewed notices without replying.** `sage_message_close(message_id, reason)` records an explicit “closed without reply” outcome for informational or withdrawn messages. Closing retains history and clears pending and unfinished inbox reminders across sessions and restarts. Exact-recipient pending messages need no claim; existing claims remain protected by their current session.

The close reason stays in recipient history and uses the content vault when enabled. Closures create no reply, read receipt, or sender reply activity. Inbound federated closure is local to the receiving SAGE. REST and both Python clients expose the same action, and startup nudges explain when to use it.

App-v28 remains active and no chain migration is required. Clients with a cached tool catalog re-list or reconnect to discover the new action.

Container: `ghcr.io/l33tdawg/sage:11.23.23`. SDK 11.23.23.

## What's New in v11.23.22

**Choose which agents a peer can find.** Federation visibility uses the complete eligible roster instead of general registry entries that could make a partial selection fail. Search by name, provider, or ID, filter Visible/Hidden, and change an individual agent or only the agents matching your filters.

**Review choices in one place.** Compact rows, Save/Discard, and inline refresh controls keep visibility edits together. Filtered rows stay in place until saving, preserving keyboard focus. The peer's contacts have their own read-only view, while optional memory sharing and access settings are collapsed separately. Agents whose security policy blocks messages remain marked Not accepting.

Individual and filtered choices stay an exact selection, even when all current agents are selected. **Show all agents** explicitly includes future eligible agents. Visibility grants discovery only; memory access and message delivery keep their existing authorization checks.

App-v28 remains active and no chain migration is required.

Container: `ghcr.io/l33tdawg/sage:11.23.22`. SDK 11.23.22.

## What's New in v11.23.21

**Reliable inbox reply catch-up.** The inbox now returns an explicit `reply_watermark_candidate` to save after processing the complete reply range. Its safety flags describe that inbox response and stay fixed while you page. For a truncated reply page, continue until `sage_message_replies` returns `page_truncated=false`, then use the candidate from the original inbox response as the next `reply_since`. An already complete inbox page needs no pager call. This replaces guidance that could send clients through the retained archive repeatedly.

**Paging keeps its bounds.** Each continuation supplies the next cursor with the same inclusive `since` and page limit. If the retained-reply pointer has no valid head, a returned reply page can still supply a candidate; a response with no valid candidate tells the client to omit `reply_since` on its next poll. Replies at the inclusive boundary remain deduplicated by message ID.

Clients carrying a tool catalog from before inbox v3 must re-list tools or reconnect to discover the existing `sage_message_claim` and `sage_task_notice_ack` actions. The server already advertises those tools and sends its tool-list change notification during runtime handoff.

App-v28 remains active and no chain migration is required.

Container: `ghcr.io/l33tdawg/sage:11.23.21`. SDK 11.23.21.

## What's New in v11.23.20

**Reading the inbox leaves work pending.** `sage_inbox` now inspects messages and task notices without claiming messages, marking notices read, or creating a reply obligation. Agents accept one authorized message with `sage_message_claim(message_id)` and acknowledge one reviewed task notice with `sage_task_notice_ack(notification_id)`. Message and task-notice pages advance independently, so a busy message inbox cannot hide task notices.

**Agent integrations use the explicit acceptance contract.** The old `sage_messages_receive` MCP tool is removed. Hooks, startup guidance, the Claude channel and the Python SDK use passive inspection; clients must explicitly claim a message before replying. Session ownership, signed federated receipts and recovery of existing claims remain enforced. Reconnect MCP clients after updating so they discover the 36-tool inventory.

Source builds and release builders move to Go 1.26.9, and both Go modules use `golang.org/x/net` v0.60.0 for the patched standard-library and HTTP/2 dependencies.

App-v28 remains active and no chain migration is required.

Container: `ghcr.io/l33tdawg/sage:11.23.20`. SDK 11.23.20.

## What's New in v11.23.18

**SQLite dependency maintenance.** The SQLite driver moves to 1.60.1 with its matching libc dependency. This includes WAL shared-memory read-fault handling that returns an I/O error instead of crashing, plus faster argument binding for statements with many parameters. The embedded SQLite engine remains 3.53.4; Go tooling dependencies are also refreshed.

**Reranker allocation checks.** The reranker keeps its existing limit of 1,000 results. Its result slice now grows only within the capped selection loop, with no input-sized preallocation. Regression tests cover extreme limits, empty and oversized candidate pools, upstream failures and malformed scores.

The optional LoCoMo and LongMemEval benchmark environments now pin `datasets==5.0.1`, addressing [GHSA-379c-qx7v-6h59 / CVE-2026-66007](https://github.com/advisories/GHSA-379c-qx7v-6h59). Browser fixture tests use Playwright 1.63.0.

No consensus execution change, app-version change or chain migration; app-v28 stays active. The experimental, default-off local judge remains pinned to v16, with its runtime, thresholds and published qualification limits unchanged.

Container: `ghcr.io/l33tdawg/sage:11.23.18`. SDK 11.23.18.

## What's New in v11.23.17

**The optional local judge is now pinned to v16.** On the disclosed frozen 40-item synthetic regression set, the attributed tank-warning example moves from rejection to operator review. All 18 genuine examples avoid rejection: 16 pass and two hold. All 22 negative examples still reject. These results were independently measured on Linux/arm64 with Ollama v0.31.1; they do not establish fresh-holdout accuracy or qualify production installation on every platform.

Select `SAGE_LOCAL_JUDGE_MODEL=sage-memory-judge:v16` to use the new pin. The memory gate remains experimental and off by default; upgrading does not rewrite an explicit v15 setting. The download uses an immutable Hugging Face revision with separate SHA-256 pins for the downloaded GGUF and Ollama's registered blob. Thresholds, serving template and runtime are unchanged. See the [memory-gate guide](docs/reference/write-gate.md) and [v16 regression results](bench/judge-qualify/results/sage-judge-v16-ollama-0.31.1-go-arm64.json). Thanks to [@ihubanov](https://github.com/ihubanov) for the update.

No consensus execution change, app-version change or chain migration; app-v28 stays active.

Container: `ghcr.io/l33tdawg/sage:11.23.17`. SDK 11.23.17.

## What's New in v11.23.16

**Task creation starts at 0.90 across MCP.** When confidence is omitted, `sage_remember(type="task")` now matches `sage_task`; other memory types keep their 0.80 default. Corrections resolve the inherited memory type before choosing the default. Explicit scores, including 0 and 0.80, are preserved; malformed, non-finite and out-of-range scores are rejected. The tool schema describes the conditional defaults without inserting a fixed value that could override correction inheritance.

**Submission receipts report the score that was signed.** `submitted_confidence` appears on submitted `sage_remember` writes, including corrections and indeterminate outcomes, and on `sage_task` creation, replay and committed-but-unconfirmed receipts. It describes the request, not a later stored or query-time score. Skipped or rejected pre-validation and task-status updates do not report a submitted score.

Existing memory scores and task idempotency checks remain intact. There is no consensus execution change, app-version change or chain migration; app-v28 stays active and the qualified v15 local judge pin is unchanged.

Container: `ghcr.io/l33tdawg/sage:11.23.16`. SDK 11.23.16.

## What's New in v11.23.15

**MCP stdio bridges exit when their client process dies.** Inherited pipes can keep a bridge's input open after its client has gone. SAGE now watches the original parent process, cancels its tools and subscriptions on confirmed parent exit, and bounds cleanup even when input or output is blocked. An idle client keeps its bridge.

**Correction lineage resolves by content hash in CEREBRUM.** The graph and related-memory view find the parent of a correction through bounded metadata lookups on SQLite and PostgreSQL. Legacy exact-ID pointers still work; ambiguous hashes and hidden parents do not expose a lineage edge or memory body.

**A malformed reranker response preserves the original recall results.** Missing, duplicate or invalid candidate indices and non-finite scores now discard the reranking response as a whole, keeping the existing reciprocal-rank-fusion ordering. The optional reranker remains off by default; its guidance now asks users to compare relevance and latency on their own queries.

**Federation and message failures explain the next step.** Local storage and target-resolution failures, plus failed requests to known peers, include bounded diagnostics and remedies. Route diagnostics report only attempted candidates and omit credentials, payloads and peer response bodies. Messaging controls also explain that blocking delivery does not hide an agent from discovery.

The release removes unused memory-transition helpers, expands bounded CI coverage, and documents reproducible retrieval benchmarks and the limits of the public research artifacts. No consensus execution change, app-version change or chain migration; app-v28 remains active. The local judge model stays pinned to the qualified v15 artifact.

Container: `ghcr.io/l33tdawg/sage:11.23.15`. SDK 11.23.15.

## What's New in v11.23.14

**MCP tool calls stay responsive while another tool waits on HTTP.** Stdio now runs up to 16 tool requests concurrently and reads cancellation notifications immediately. A slow history read can no longer hold later independent tools or the tool registry behind it. Cancellation stops the matching request context; an indeterminate write still requires its normal reconciliation.

**AMID restores unresolved signer fences before it starts serving.** A private, node-local SQLite ledger preserves identity-only submission intents across process exits. Startup refuses an unreadable or malformed ledger, and a restored fence settles only on chain-proven fate. Disabling the REST validator key also removes the inherited key from ordinary signing paths. A proven fence finishes its durable cleanup before reopening the signer, so a fast next submission cannot lose its new recovery record to the prior cleanup.

**Block sync rounds quorum-blocking power up correctly.** A validator with power 1 out of 4 no longer leaves block sync early. Actual quorum-blocking power keeps its existing behavior.

**An optional local judge checks lasting knowledge and its submitted evidence.** Set `SAGE_LOCAL_JUDGE_MODEL=sage-memory-judge:v15` to use SAGE's verified local model through its managed Ollama runtime. It remains experimental and off by default. Judge traffic is restricted to loopback, cloud aliases and mismatched model blobs are refused, and an unavailable judge holds proposals for operator review. Public seed-set qualification on SAGE's pinned runtime passed with external networking blocked; support precision was 97% with one accepted trap, and lasting precision was 100%. See the [memory-gate guide](docs/reference/write-gate.md) and [runtime qualification report](bench/judge-qualify/reports/sage-judge-v15-sage-runtime.md) for configuration and limits. Thanks to [@ihubanov](https://github.com/ihubanov) for the contribution.

No consensus execution change, app-version change or chain migration.

Container: `ghcr.io/l33tdawg/sage:11.23.14`. SDK 11.23.14.

## What's New in v11.23.13

**REST submissions keep their acknowledgment through the full write budget.** A memory could commit after the server's response deadline had expired, leaving the caller with a connection error instead of the result. The deadline now accounts for embedding retries, the bounded nonce-lease wait and the consensus commit wait, with time for the response. The default is 285.75 seconds and the combined budget is capped at ten minutes; larger custom settings can still outlast that cap.

**Vault recovery verifies the key before replacing `vault.key`.** An invalid recovery key is refused before it can overwrite the existing vault key file.

This patch retains the memory gate shipped in v11.23.11. The unreleased evidence checks, managed local judge and model work are deferred. There is no consensus execution change, app-version change or chain migration. The cancelled v11.23.12 tag remains unchanged.

Container: `ghcr.io/l33tdawg/sage:11.23.13`. SDK 11.23.13.

## What's New in v11.23.11

**An optional memory-quality gate can hold uncertain memories for review.** Set `SAGE_HUNCH_URL` to enable a background judge for proposed memories, with domain include/exempt settings controlling which memory text reaches the service. Built-in checks still run on every vote, and Settings → Memory gate lets the operator accept or reject held memories. The gate is off by default, supports SQLite stores, and does not change consensus or recall. See the [memory-gate guide](docs/reference/write-gate.md) for configuration and limits. Thanks to [@ihubanov](https://github.com/ihubanov) for the contribution.

**A provably stale memory vote can release its signer fence.** When a vote's target has already committed, a stale-vote mempool filter can reject every retry before it reaches an indexed block result. SAGE now recognizes a narrow, versioned refusal for complete canonical memories submitted after app-v25 activation. The resolver binds that refusal to the exact signed vote and rechecks the transaction index before reporting its outcome. Ordinary CheckTx 13 errors and historical or incomplete targets keep the fence held.

**CLI help is inert.** Asking for `serve --help`, `setup --help`, or `mcp --help` returns usage before command dispatch, configuration, or instance locking, without creating home or project files.

**Inbound federated messages wake their exact local recipient.** Wake allocation commits atomically with message admission and transport deduplication. Duplicate or rolled-back deliveries cannot create extra wakes, and startup catches up existing unfinished inbound work.

No consensus execution change, transaction-type change, upgrade height, or chain reset. AMID operators must preserve unresolved transaction identity and signed bytes during maintenance: `cmd/amid` does not wire the durable-intent restore hooks used by `sage-gui`, so restarting it is not a fence-recovery proof.

Container: `ghcr.io/l33tdawg/sage:11.23.11`. SDK 11.23.11.

## What's New in v11.23.10

**A held signing key can no longer park the node's whole write path.** A signer fence refuses every write from its key while it waits for proof of an earlier submission's fate, and that wait was bounded only by the caller's context — which the submit path passed as `context.Background()`, a context that never cancels and carries no deadline. The one goroutine holding the node's single signing lease sat there for as long as the fence stood — one observed node carried handlers parked 122–768 minutes — and every later writer for that key queued behind it on the same size-one lease, including the automatic reconciler whose job is to settle the fence and release it, so the hold could not clear itself. Reads stayed fast and denied writes still failed fast, which is why the incident reached the operator as *writes time out, no error*. `WithNonceLease` now derives a bounded wait (90 s) when the caller supplies no deadline, so a held fence fails retryable instead of parking, the lease is released, and the reconciler is no longer starved by the fence it exists to lift. A caller that supplies its own shorter deadline keeps it.

**Background work the embedded web handler starts can no longer outlive the store it writes to.** That handler started goroutines with no lifecycle owner, and unowned work that outlived its caller's store touched a closed database and panicked the process — first seen inside this repository's own suite, where one test's projection audit tore down another test's store. Unowned background work is counted now, and a caller that owns the stores drains it with `WaitBackground` before closing them.

**Build and tooling.** Local `make` builds pin to the host architecture instead of assuming amd64, and a Codex session started in a checkout inherits that checkout's Codex pin from `.codex/config.toml` — the counterpart of the existing `.mcp.json` Claude Code pin, so one workspace can carry both providers' pins. Dependency groups were refreshed.

No consensus change, no transaction-type change, no upgrade height, and no chain reset.

Container: `ghcr.io/l33tdawg/sage:11.23.10`. SDK 11.23.10.

## What's New in v11.23.9

**CEREBRUM now shows a held signing key.** A signer fence refuses every write from its key and every coordinated restart while it waits for proof of an earlier submission's fate, and until this release the dashboard said nothing about it — the field report that produced the fence workstream read from the outside as *reads are fine, writes time out, no error*. System Status gains a row that appears only while a key is held: how many keys and how long, the node's own explanation of why the hold is deliberate, and one line per fence naming its resolution. `reconciling` means the identical bytes are still being re-submitted and it clears itself; `waiting on proof` means the signed bytes did not survive the process, so the chain or an operator has to settle it. Each line carries the nonce, how long the key has been held, the attempt count and the last recorded detail.

**A hold that ends stays visible.** The row above disappears with the fence, which left no way to tell *it lifted while I was reading* from *it never happened*. The last resolution is now kept and rendered — `committed`, `rejected`, `spent`, or resolved without a proof — so a fence that cleared itself is still on screen afterwards.

**Two details that make the numbers trustworthy.** The nonce crosses the wire as a string: SAGE nonces are nanosecond allocations that exceed JavaScript's safe integer range, and as a JSON number it reached the browser silently rounded, in the one place the operator compares it against the chain. And the panel never suggests restarting to clear a hold — a restart discards the fence and loses the transaction it protects, which is the failure the whole mechanism exists to prevent.

No consensus change, no transaction-type change, no upgrade height, and no chain reset.

Container: `ghcr.io/l33tdawg/sage:11.23.9`. SDK 11.23.9.

## What's New in v11.23.8

**A node stops manufacturing signer fences on an ordinary quit.** Since the fence landed, every coordinated restart has drained signing before it committed, so its teardown could not sever a broadcast mid-flight. A plain signal or a serve error had no such drain: the HTTP force-close could catch a submission, raise an indeterminate outcome, write a durable fence record, and cost that payload at the next start — the fence can only lift on a proof, and a live one whose re-submission is refused by anything other than the nonce gate has no proof to reach. The ordinary exit now drains the same way the restart does: signing is quiesced, in-flight submissions get a bounded five-second window to finish, and only then do the listeners close. Signing is deliberately not resumed, because the process is leaving; an operator-ordered exit is never vetoed by the drain; and a submission that cannot finish in the window fails closed onto the durable record and the restored fence.

**`sage-gui fence abandon` works on a node that keeps a peer.** The credential-free operator exit added in 11.23.6 applies the same evidence gate as the daemon's abandon route, including its second acknowledgement for connected peers — a peer is a route the abandoned bytes could still take back into this node's mempool. The CLI had no way to carry that acknowledgement, so on a federated desktop node or a validator with a persistent peer it could only ever refuse and point at a field it had no way to set. `--peer-redelivery-acknowledged` now carries it, `fence list` names the requirement when peers are connected, and every unproven record states the restart step: a running daemon keeps holding the key until it restarts, and the durable record is what the next boot restores from.

No consensus change, no transaction-type change, no upgrade height, and no chain reset.

Container: `ghcr.io/l33tdawg/sage:11.23.8`. SDK 11.23.8.

## What's New in v11.23.7

**A node that has activated app-v28 can install its own updates again.** The signed update flow takes a pre-upgrade recovery snapshot and proves it before it touches the installed app: the manifest carries the AppHash the running chain committed, and the proof restores the Badger backup and re-derives that digest from the restored bytes. Since app-v28 the committed AppHash is the public-memory composite commitment — the app-v13 digest of the state WITHOUT the public-memory index nodes, composed with the sparse index root — and the proof only knew the three earlier eras. Every app-v28 node therefore refused its own recovery snapshot, and the field report was exactly this shape: `Failed to install signed app update: verify pre-upgrade snapshot: ... AppHash mismatch under every hash rule (legacy/app-v12/app-v13)`, with the update stuck on the snapshot step and no way forward from inside the app.

**What now happens:** the composite joins the candidate set, read through the same `internal/store` implementation the commit path uses instead of a second copy of the rule — the state-sync provider verification path already went stale exactly that way once, refusing every v28 provider while every pre-v28 chain stayed green. A pre-v28 state carries no public-memory commitment, so the composite is reported as not-applicable there and the three older candidates decide alone. The mismatch message now names the rules that were actually tried.

**If you are reading this from an app-v28 node on 11.23.6 or earlier, read this part.** The gate that just failed runs inside the binary you have installed, so that binary cannot install this release either — and the same gate vetoes a version-changing restart. Installing 11.23.7 once by hand is the path out: quit SAGE, drag `SAGE.app` from the DMG into `/Applications`, relaunch. Every update after that one works from inside the app again.

No consensus change, no transaction-type change, no upgrade height, and no chain reset.

Container: `ghcr.io/l33tdawg/sage:11.23.7`. SDK 11.23.7.

## What's New in v11.23.6

**A fence on a quiet chain settles itself, and the operator has a way in when it cannot.** SAGE chains are idle by design: since app-v12 every node sets `create_empty_blocks=false`, so a block is minted exactly when a signed transaction enters the mempool and the chain sits still otherwise. A fence restored from durable intent refuses to sign, and its signed bytes did not survive the process — so on a chain that was already quiet when the fence was raised, the fence was holding the only thing that could produce the proof it was waiting for. No transaction meant no block; no block meant no committed hash and no advanced committed nonce. The key was held forever, every write and every cleanup on that node was refused, and the field report was exactly this shape on a single-validator personal node.

**What now happens:** when the node is caught up, has no peer and has seen none while this fence was held, holds no mempool copy of the transaction, sees no committed fate for its hash and holds an unspent allocation, the node settles the fence itself, records `fence_abandoned` and the full evidence, reserves the abandoned allocation so the next transaction cannot reuse it, and lets the next write mint the block that wakes the chain. TWO EVIDENCE SETS REACH THAT DECISION and the log names which one did: `mode=automatic_unprovable` is the original startup resolution, and `mode=automatic_quiescent` is the rule added here for a chain that has minted nothing since the fence was raised — the first now succeeds where it previously could not, because the reader defects below were what stopped it reaching its gates.

**What still holds the fence:** a tip that has minted since the fence was raised, any connected peer, a peer seen under this fence, a mempool that holds the transaction — that is a chain with something to mint and the fence is what stops it, so it stays an operator decision — a node still catching up, a tip that cannot be read, a live fence whose exact bytes still exist, and any record without a nonce.

**Every outcome of the automatic route is now visible.** Its refusal reason reaches the fence's `last_detail`, and so does a FAULT — the fault branch was previously dropped silently, which made a node whose self-heal could not read its own evidence look identical to one that was merely waiting. A field report read that as "the automatic route never ran".

**The operator has a real entry.** `sage-gui fence list` prints every recorded fence with its signer, transaction, nonce and age, and says whether the chain can already settle it. `sage-gui fence abandon --signer <key> --reason <why> --acknowledge-payload-loss` retires one record from the node host through the same evidence gate the daemon's operator route applies — no credential, no browser, and it says plainly that a running daemon keeps its in-process fence until it restarts. This closes a field gap: the dashboard had no control for this action, and an HTTP MCP bearer token is not accepted by the operator gate, so the only local entry was a browser console.

No consensus change, no transaction-type change, no upgrade height, and no chain reset.

Container: `ghcr.io/l33tdawg/sage:11.23.6`. SDK 11.23.6.

## What's New in v11.23.4

**A fence on a quiet chain settles itself.** SAGE chains are idle by design: since app-v12 every node sets `create_empty_blocks=false`, so a block is minted exactly when a signed transaction enters the mempool and the chain sits still otherwise. A fence restored from durable intent refuses to sign, and its signed bytes did not survive the process — so on a chain that was already quiet when the fence was raised, the fence was holding the only thing that could produce the proof it was waiting for. No transaction meant no block; no block meant no committed hash and no advanced committed nonce. The key was held forever, every write and every cleanup on that node was refused, and on a single-validator personal node the hold had no exit at all — the operator route needed a credential the operator could not present.

**What now happens:** when the node is caught up, has no peer and has seen none while this fence was held, holds no mempool copy of the transaction, sees
历史前置条件说明(补充参考)

桌面安装包或 Docker/源码构建;源码构建需 Go 1.26.10+;Python SDK 需 Python 3.10+ 及运行中节点和已注册 Agent;HTTP MCP 需 bearer token 或 OAuth;可选远程模型提供方与本地评审模型的具体要求、API Key、费用、国内网络可用性待核验。

项目来源与清单版权许可

https://github.com/l33tdawg/sage

整理来源:https://github.com/slavakurilyak/awesome-ai-agents

清单版权与许可:

MIT License

Copyright (c) 2024 Slava Kurilyak

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.