Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,19 +125,19 @@
- 新增状态/事件/持久化载荷:先定义 `.proto` 并生成类型,再接入实现;禁止先写临时结构后补 Protobuf。

## 文档系统(强制)
- `docs/canon/` 是唯一权威参考;一个 topic 一个文件,不可有重复。
- `docs/decisions/` 是 ADR(Architecture Decision Records),不可变,只可被新决策 supersede。
- `docs/canon/` 是唯一权威参考;一个 topic 一个文件,不可有重复。架构评审与重构讨论统一用 [docs/canon/architecture-vocabulary.md](docs/canon/architecture-vocabulary.md) 的词汇(Module / Interface / Depth / Seam / Adapter / Leverage / Locality)。
- `docs/adr/` 是 ADR(Architecture Decision Records),不可变,只可被新决策 supersede。文件名 `NNNN-slug.md`,编号唯一不可重用
- `docs/history/` 存放已归档的思考快照,按月份组织,明确标记非权威。
- AI 生成的设计文档在会话结束后默认不保留到 `docs/`;需要保留的必须添加 frontmatter(title/status/owner)并放入对应目录。
- 所有 `docs/canon/` 和 `docs/decisions/` 文件必须有 YAML frontmatter,包含 `title`、`status`、`owner` 字段。
- 所有 `docs/canon/` 和 `docs/adr/` 文件必须有 YAML frontmatter,包含 `title`、`status`、`owner` 字段。
- Lint 操作由 `tools/docs/lint.sh` 执行,已集成到 CI 门禁。
- 根目录允许的 `.md` 文件:`CLAUDE.md`、`README.md`、`CHANGELOG.md`、`LICENSE`、`AGENTS.md`。`src/` 下各项目允许自身 `README.md`。
- `docs/README.md` 由 `tools/docs/build-index.sh` 自动生成,不手动编辑。

## 项目结构
- `src/`:生产代码(`Aevatar.Foundation.*`、`Aevatar.AI.*`、`Aevatar.CQRS.Projection.Core.Abstractions/Runtime/Stores.Abstractions`、`src/workflow/Aevatar.Workflow.*`、`Aevatar.Host.*`)。
- `test/`:对应测试项目(单元、集成、API)。
- `docs/`:架构文档(`canon/` 权威参考、`decisions/` ADR、`history/` 归档、`audit-scorecard/` 审计)。
- `docs/`:架构文档(`canon/` 权威参考、`adr/` ADR、`history/` 归档、`audit-scorecard/` 审计)。
- `workflows/`:YAML 工作流定义;`tools/`:开发工具;`demos/`:示例程序。
- **CLI 项目**:`tools/Aevatar.Tools.Cli`——提到"CLI 项目"或"cli 项目"时,均指此路径。

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ sequenceDiagram
- **Event Sourcing**: [docs/canon/event-sourcing.md](docs/canon/event-sourcing.md) — 如何开启事件溯源。
- **Connector 配置详解**: [docs/canon/connector.md](docs/canon/connector.md) — 配置格式与示例。
- **Maker 示例**: [demos/Aevatar.Demos.Maker](demos/Aevatar.Demos.Maker) — 自定义步骤类型与 MAKER 工作流。
- **项目拆分策略**: [docs/decisions/0001-project-split-strategy.md](docs/decisions/0001-project-split-strategy.md) — 分片与拆仓路径。
- **项目拆分策略**: [docs/adr/0001-project-split-strategy.md](docs/adr/0001-project-split-strategy.md) — 分片与拆仓路径。

---

Expand Down
24 changes: 15 additions & 9 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Authoritative architecture and developer guides. Each covers one topic.

- [[RFC] Aevatar Chat — Multi-Channel Adapter Architecture](canon/aevatar-channel-architecture.md)
- [Architecture Vocabulary](canon/architecture-vocabulary.md)
- [Aevatar Foundation](canon/architecture.md)
- [Workflow Chat API 能力说明(框架层)](canon/chat-api.md)
- [Connector 配置与执行逻辑](canon/connector.md)
Expand All @@ -26,15 +27,20 @@ Authoritative architecture and developer guides. Each covers one topic.

Immutable records of architectural choices and their rationale.

- [Aevatar 项目拆分策略(2026-02-21)](decisions/0001-project-split-strategy.md)
- [Aevatar Mainnet 架构说明](decisions/0002-mainnet-architecture.md)
- [Orleans Kafka Provider Backend Architecture](decisions/0003-kafka-transport.md)
- [Workflow 调度 Actor 化 & 多智能体协作演进方案](decisions/0006-multi-agent-evolution.md)
- [Aevatar Stream Forward 架构说明(2026-02-22)](decisions/0007-stream-forward.md)
- [Channel Runtime Multi-Token Credential Routing](decisions/0008-channel-runtime-multi-token-routing.md)
- [Channel Bot Callback Architecture — Lessons from Lark Integration](decisions/0009-channel-bot-callback-architecture.md)
- [Channel Phase 0 Persistent Provider Validation Result](decisions/0010-channel-phase0-provider-validation.md)
- [AGUI / SSE Projection Session Pipeline](decisions/0011-agui-sse-projection-session-pipeline.md)
- [Aevatar 项目拆分策略(2026-02-21)](adr/0001-project-split-strategy.md)
- [Aevatar Mainnet 架构说明](adr/0002-mainnet-architecture.md)
- [Orleans Kafka Provider Backend Architecture](adr/0003-kafka-transport.md)
- [Workflow 调度 Actor 化 & 多智能体协作演进方案](adr/0006-multi-agent-evolution.md)
- [Aevatar Stream Forward 架构说明(2026-02-22)](adr/0007-stream-forward.md)
- [Channel Runtime Multi-Token Credential Routing](adr/0008-channel-runtime-multi-token-routing.md)
- [Channel Bot Callback Architecture — Lessons from Lark Integration](adr/0009-channel-bot-callback-architecture.md)
- [Channel Phase 0 Persistent Provider Validation Result](adr/0010-channel-phase0-provider-validation.md)
- [Lark Nyx Relay Webhook Topology](adr/0011-lark-nyx-relay-webhook.md)
- [Channel Runtime Credential Boundary](adr/0012-channel-runtime-credential-boundary.md)
- [Unified Channel Inbound Backbone](adr/0013-unified-channel-inbound-backbone.md)
- [Channel Interactive Reply Abstraction](adr/0014-interactive-reply-abstraction.md)
- [AGUI / SSE Projection Session Pipeline](adr/0015-agui-sse-projection-session-pipeline.md)
- [Studio Member-First Published Service Identity](adr/0016-studio-member-first-published-service.md)

## History

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,5 @@ behaviour without redeploying.
- Issue `#328` — unified inbound trunk; this ADR's outbound abstraction slots into the
same `IChannelOutboundPort` surface once #328 lands.
- PR `#324` — inbound `card.action.trigger` processing; this ADR is its outbound dual.
- ADR-0011 (`docs/decisions/0011-lark-nyx-relay-webhook.md`) — relay webhook topology;
- ADR-0011 (`docs/adr/0011-lark-nyx-relay-webhook.md`) — relay webhook topology;
not superseded, outbound completeness augments it.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ status: active
owner: liyingpei
---

# ADR-0011: AGUI / SSE Projection Session Pipeline
# ADR-0015: AGUI / SSE Projection Session Pipeline

## Context

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ status: accepted
owner: codex
---

# ADR-0012: Studio Member-First Published Service Identity
# ADR-0016: Studio Member-First Published Service Identity

## Context

Expand Down
108 changes: 108 additions & 0 deletions docs/canon/architecture-vocabulary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
title: "Architecture Vocabulary"
status: active
owner: eanzhao
---

# Architecture Vocabulary

本文是架构评审与重构讨论时使用的统一词汇表。它把外部的 deepening / Ports & Adapters 词汇与 aevatar 内部已有的术语对齐,避免在 review 时同一个概念出现多种叫法。

适用场景:

- `arch-audit`、`improve-codebase-architecture` 等架构评审 skill 的产出
- ADR 的 Context / Decision 文段
- PR 描述中讨论"重构动机"时
- code review 中评估"接口该不该这样切"时

如果只是讲业务功能("member-first", "channel relay", "scripting"),用领域词汇即可,不必套用本表。

## 1. 核心词汇映射

| 通用词汇 | aevatar 已有术语 | 含义与口径 |
|---|---|---|
| Module | Actor / GAgent / 项目(`Aevatar.<Layer>.<Feature>`) | 任何"接口 + 实现"的单元,尺度无关;在 aevatar 主线上最常落到 Actor / GAgent / 一个 .csproj。 |
| Interface | Port + 命令/事件 proto + ReadModel 查询契约 | "调用方必须知道才能正确使用"的全部事实:类型签名、不变式(invariant)、顺序(ordering)、错误模式、配置、性能特性。**不只是 C# `interface` 关键字。** |
| Implementation | Actor body / Adapter 内部 / `*.cs` 实现文件 | 接口背后的代码主体。**与 Adapter 区分**:一个 thing 可以是"小 adapter + 大 implementation"(比如真实 ES 仓储),也可以是"大 adapter + 小 implementation"(比如 in-memory fake)。 |
| Depth(深度) | 业务实体内聚("Actor 即业务实体"原则);"删除优先"留下来的模块 | 接口杠杆率:接口很小、覆盖的行为很多 → **deep**;接口几乎和实现一样宽 → **shallow**。aevatar 的"Actor 即业务实体(数据 + 方法同住)"就是 depth 的具体实例。 |
| Seam(接缝) | Port(如 `IActorDispatchPort`、`IEventPublisher`)+ 命令分发契约 | 一个**可替换实现的位置**:能在不改这里代码的前提下换掉行为。在 aevatar 中,Port 就是 seam。 |
| Adapter | 同义。e.g. `LocalActorPublisher`、`RuntimeBackedActorRuntime`、各种 `InMemory*` | 满足某 seam 上 Interface 的具体实现。描述**角色**(填哪个槽),不描述**实质**(里面是什么)。 |
| Leverage | "一处 Port,N 处调用 + M 处测试都获益" | Depth 给调用方的回报:一份实现服务多个调用点和测试。 |
| Locality | "单一权威拥有者"原则、"事实源唯一" | Depth 给维护者的回报:变更、bug、知识、验证集中在一个位置;改一处 → 各处自动修复。 |

### 1.1 已经存在但容易和上面混淆的词

| aevatar 术语 | **不**等价于 | 区分 |
|---|---|---|
| 边界(如"Actor 边界"、"权威源边界") | Seam | "边界"在 aevatar 是**所有权 / 责任范围**(接近 DDD bounded context)。Seam 是**可替换实现的位置**。一个 actor 的边界不是 seam;它周围的 Port 才是 seam。 |
| ReadModel | Interface | ReadModel 是**查询副本**(actor-scoped current-state replica)。它的查询契约(IXxxQueryPort)才是 Interface / Seam。 |
| Projection Pipeline | Adapter | Projection 是**物化机制**(committed event → readmodel),不是某个 seam 上的具体实现。"Projection 通道下的具体投影器"才类比 Adapter。 |
| Service(如 `WriteService`、`QueryService`) | Module(无脑套用) | aevatar 的应用层契约必须承载业务语义、不是纯转发空壳;一个 "Service" 是不是 Module 取决于它的 Interface 是不是足够 deep。多数情况下,正确的形态是更窄的 `IXxxQueryPort` / `IActorDispatchPort`,而不是泛 `Service`。 |

## 2. 关键原则(与 CLAUDE.md 已有规则的映射)

### 2.1 Deletion test(删除测试)

> 想象删掉这个模块。如果复杂度消失了,它就是 pass-through;如果复杂度在 N 个调用方处重新出现,它就是有价值的。

对应 CLAUDE.md:

- **删除优先**:空转发、重复抽象、无业务价值代码直接删除,不保留兼容空壳。
- **抽象一旦能被滥用即设计未完成**:允许绕过读写分离 / actor 边界 / 权威源的通用接口须继续收窄。

> 落地口径:在评审一个新增"中间层"时,先做删除测试。如果删除后调用方各自要重新写出同样的逻辑,保留;如果调用方只是少调一层、自己已能完成,删除。

### 2.2 The interface is the test surface

> 调用方和测试穿过同一个 seam。如果想要测"接口背后"的内容,模块的形状大概率是错的。

对应 CLAUDE.md:

- **读写分离**:查询走 readmodel;不暴露 actor 内部 state 或 event replay 作为查询主路径。
- **Actor 测试通过 inbox / 行为契约**:不通过 reflection 拆 actor 内部状态字段。

### 2.3 One adapter = hypothetical seam, two adapters = real seam

> 只有一个 adapter 时,seam 是想象出来的;至少要有两个 adapter(通常是 production + test)才值得引入 Port。

对应 CLAUDE.md:

- **禁止预留兼容空壳**。
- **本地可用不等于分布式正确**:仅本地 runtime 偶然细节才成立的实现视为未完成设计。

> 落地口径:新增 Port 时必须同时给出至少两个 Adapter(典型:runtime-backed + in-memory test fake),且两个都被实际使用。只有"未来可能要换"的 Port 不能落地。

### 2.4 Deep over shallow(深 vs 浅)

> 模块要"深"——大量行为藏在小接口背后;不要"浅"——接口几乎和实现一样复杂。

对应 CLAUDE.md:

- **Actor 即业务实体**:一个 actor = 一个业务实体(数据 + 方法同住);禁止按技术功能(读 / 写 / 投影)拆分同一业务实体为多个 actor。
- **命名跟随职责**:接口 / 类型 / 目录命名描述职责边界,不泄露 `runtime/stream/protocol` 偶然细节。

## 3. 使用约定

1. **领域语言** vs **架构语言** 分开使用:
- 描述业务("member 是 Studio 的唯一主语")→ 用 `docs/canon/role-model.md` 等领域文档里的词汇。
- 描述结构("这个 module 太 shallow,应该 deepen 进 GAgent")→ 用本表词汇。
2. ADR 的 Context 段落用本表词汇描述当前结构问题;Decision 段落仍可使用领域语言落地。
3. **不要混用**:同一段话里"边界"和"seam"含义清晰可分;但"boundary 边界"如果用来指可替换位置就是错的,应该改成"port"或"seam"。
4. 中文写作时优先用括号显式给出英文术语:例如"接缝(seam)"、"深度(depth)"、"端口(port)"。`seam` 是概念(可替换实现的位置),`port` 是这个概念在 aevatar 里最常见的落地形态——两者不要互换使用,避免"边界"被随意替代。

## 4. 词汇拒绝清单

下列词在架构讨论中**不要单独使用**,因为它们已经被业务或基础设施语义占用 / 含糊:

- "boundary / 边界" 用于"可替换位置"——改用 **port / seam**。
- "service" 用于泛指一个模块——改用 **module / port** 或具体业务名(`*GAgent`、`*Projector`)。
- "API" 仅指类型签名——架构层面要谈 **interface**(含不变式与错误模式)。
- "component" 指 UI 组件以外的概念——通常是 **module** 或 **adapter**。

## 5. 参考

- [Mattpocock skills - improve-codebase-architecture/LANGUAGE.md](https://github.com/mattpocock/skills/blob/main/improve-codebase-architecture/LANGUAGE.md) — 本表的外部出处。
- Michael Feathers, *Working Effectively with Legacy Code* — seam 概念原始出处。
- [overview.md](overview.md) — aevatar 项目主架构。
- [architecture.md](architecture.md) — Foundation 层接口与运行时模型。
- [cqrs-projection.md](cqrs-projection.md) — 读写分离与 Projection Pipeline。
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ status: draft
owner: tbd
last_updated: 2026-04-23
references:
- "../decisions/0012-studio-member-first-published-service.md"
- "../adr/0016-studio-member-first-published-service.md"
- "./2026-04-22-team-member-first-prd.md"
- "./2026-04-22-studio-member-lifecycle-spec.md"
---
Expand All @@ -13,7 +13,7 @@ references:

## 0. 目标

把 [ADR-0012](../decisions/0012-studio-member-first-published-service.md) 落成可执行的后端实施清单。
把 [ADR-0016](../adr/0016-studio-member-first-published-service.md) 落成可执行的后端实施清单。

这份 checklist 锁定的不是视觉设计,而是后端事实模型:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ status: draft
owner: tbd
last_updated: 2026-04-23
references:
- "../decisions/0012-studio-member-first-published-service.md"
- "../adr/0016-studio-member-first-published-service.md"
- "./2026-04-22-studio-member-lifecycle-spec.md"
- "./2026-04-23-studio-member-first-backend-implementation-checklist.md"
---
Expand All @@ -13,7 +13,7 @@ references:

## 0. 目标

把 [ADR-0012](../decisions/0012-studio-member-first-published-service.md) 转成可执行的前端实施清单。
把 [ADR-0016](../adr/0016-studio-member-first-published-service.md) 转成可执行的前端实施清单。

这份 checklist 的核心目标有两个:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ owner: liyingpei

# Issue 204:AGUI / SSE Projection Session Pipeline 落地说明

> 本文档位于 `docs/history/2026-04/`,保留的是一份“落地后回看版”说明,不再保留最初那版大而全的设计推演。当前权威口径仍以 [ADR-0011:AGUI / SSE Projection Session Pipeline](../../decisions/0011-agui-sse-projection-session-pipeline.md) 为准;本文只回答三件事:原来哪里有问题,这次代码具体怎么收了,哪些还没做。
> 本文档位于 `docs/history/2026-04/`,保留的是一份“落地后回看版”说明,不再保留最初那版大而全的设计推演。当前权威口径仍以 [ADR-0015:AGUI / SSE Projection Session Pipeline](../../adr/0015-agui-sse-projection-session-pipeline.md) 为准;本文只回答三件事:原来哪里有问题,这次代码具体怎么收了,哪些还没做。

## 1. 这次到底在修什么

Expand Down
Loading
Loading