网关层模块规格
1. 范围
本文覆盖:
- HTTP / WS / SSE 等网关协议入口
- 对业务入站请求的治理标准化
- 控制面握手与状态快照
- 控制命令受理与分发
- 向路由层的入站交接
- 事件广播与审计记录
2. 四条主链路
2.1 WS 握手与状态链
GatewayConnectionRequest
-> GovernanceResult
-> GatewayConnectionAck
它回答:
- 这个连接能不能建立
- 这个连接现在以什么身份工作
- 当前网关支持哪些 methods / events
- 当前网关的状态快照是什么
这条链路主要经过:
M1 Surface / Protocol
M2 Access Governance
M3 Control Plane
2.2 控制命令链
GatewayCommandRequest
-> CommandDispatch
-> GatewayCommandResult
它回答:
- 这次请求是查询、修改还是转成真实业务入站
- 它应该由哪个控制面服务处理
- 返回结果是同步完成、异步接受还是被拒绝
这条链路主要经过:
M1 Surface / Protocol
M2 Access Governance
M4 Command Intake
2.3 真实业务消息链
RawRequest
-> NormalizedRequest
-> IngressRoutingEntry
它回答:
- 这条真实外部输入是否可信
- 这条输入在治理后应该以什么统一请求进入系统
- 这条输入交给路由层时携带哪些显式 hint
这条链路主要经过:
M2 Access Governance
M5 Ingress Routing Handoff
若入口来自 HTTP / WS,则在进入这条链路前还会先经过:
M1 Surface / Protocol
M4 Command Intake
2.4 事件回流链
EventRecord / AuditRecord
-> GatewayEventEnvelope
-> SurfaceWrite
它回答:
- 系统内部发生了什么
- 哪些连接或订阅者应该收到这些事件
- 这些事件应该通过 WS / SSE / HTTP 流中的哪一种方式发出去
这条链路主要经过:
M6 Events & Audit
M1 Surface / Protocol
3. 网关层职责与硬边界
3.1 网关层必须负责的事
- 接住外部 HTTP / WS / SSE 请求与连接
- 做认证、授权、限流、风控与审计前置
- 把
RawRequest 整理成可信 NormalizedRequest
- 把可信请求包装成
IngressRoutingEntry
- 处理控制面连接、状态快照和控制命令
- 把事件与审计记录向外广播或持久化
3.2 网关层不能越过的边界
网关层里的三个对象不是一回事:
RawRequest:输入层翻译出的原始事实请求
NormalizedRequest:网关治理后的可信请求
IngressRoutingEntry:网关交给路由层的入站入口
同理,网关层里的两个 delivery 概念也不是一回事:
DeliveryHint:入站时观察到的回发事实
DeliveryTarget:路由层产出的最终投递目标
必须写死的边界是:
- 网关层可以产出
NormalizedRequest
- 网关层可以产出
IngressRoutingEntry
- 网关层不能决定最终 agent / session /
DeliveryTarget
- 网关层不能替代执行层运行 session / task / runtime
4. 共享对象合同
本文复用 文档/输入层和网关层模块规格.md 中的:
RawRequest
NormalizedRequest
RoutingHint
IngressRoutingEntry
EventRecord
AuditRecord
4.1 网关控制面对象
type GatewayTransportRef struct {
// Protocol 是当前使用的传输协议。
Protocol string // http / ws / sse
// Method 是请求方法或 RPC 语义方法。
Method string // GET / POST / rpc
// Path 是当前入口路径或逻辑方法路径。
Path string
// ConnectionID 是长连接 ID;短连接请求可为空。
ConnectionID string
// ClientID 是客户端、设备或前端实例标识。
ClientID string
}
type GatewayCallerRef struct {
// UserID 是控制面调用者 ID。
UserID string
// AccountID 是当前账号、租户账号或平台账号。
AccountID string
// Roles 是当前调用者角色。
Roles []string
// SourceType 表示调用来源。
SourceType string // web / cli / channel / webhook
}
type GatewayConnectionRequest struct {
// ConnectionID 是待建立或已建立连接的稳定 ID。
ConnectionID string
// Transport 是连接来源协议。
Transport GatewayTransportRef
// AuthToken 是当前连接提交的认证材料。
AuthToken string
// RequestedScopes 是当前连接申请的能力范围。
RequestedScopes []string
// Metadata 是连接额外信息,例如 device / ui version。
Metadata map[string]string
}
type GatewaySnapshot struct {
// GatewayID 是当前网关实例标识。
GatewayID string
// Status 是当前网关状态。
Status string
// Methods 是当前连接可用的控制面方法。
Methods []string
// EventTopics 是当前连接可订阅的事件主题。
EventTopics []string
// StateVersion 是快照版本号。
StateVersion string
}
type GatewayConnectionAck struct {
// ConnectionID 是已经确认的连接 ID。
ConnectionID string
// Caller 是治理后确认的控制面主体。
Caller GatewayCallerRef
// Snapshot 是握手后返回的控制面快照。
Snapshot GatewaySnapshot
}
4.2 命令与事件对象
type GatewayCommandRequest struct {
// RequestID 是本次控制命令请求 ID。
RequestID string
// Transport 是命令来源协议。
Transport GatewayTransportRef
// Caller 是当前控制命令调用者。
Caller GatewayCallerRef
// Method 是逻辑命令名,例如 sessions.list / chat.send。
Method string
// ResourceID 是命令显式携带的目标对象 ID。
ResourceID string
// Params 是命令参数。
Params map[string]string
}
type CommandDispatch struct {
// Kind 是命令分发类型。
Kind string // query / mutate / ingress
// Target 表示命令应该进入哪个控制面域。
Target string // sessions / tasks / agents / ingress
// Action 是目标域中的动作名。
Action string
// RawRequest 是当 Kind=ingress 时产生的真实业务输入。
RawRequest RawRequest
// Hint 是当 Kind=ingress 时携带的显式 route hint。
Hint RoutingHint
// Metadata 是分发附加信息。
Metadata map[string]string
}
type GatewayCommandResult struct {
// RequestID 是本次命令请求 ID。
RequestID string
// Status 是命令处理状态。
Status string // completed / accepted / denied / failed
// Payload 是返回给调用者的结构化结果。
Payload map[string]string
// StreamID 是异步事件流或任务流标识;无则为空。
StreamID string
}
type GatewayEventSubscription struct {
// SubscriptionID 是订阅 ID。
SubscriptionID string
// SubscriberID 是订阅者 ID。
SubscriberID string
// Topics 是当前订阅主题。
Topics []string
// Transport 是当前订阅使用的输出协议。
Transport GatewayTransportRef
}
type GatewayEventEnvelope struct {
// EventType 是事件类型。
EventType string
// SubjectID 是事件关联对象。
SubjectID string
// Payload 是发给订阅者的序列化负载。
Payload map[string]string
// Audience 是目标订阅者或订阅组。
Audience []string
// OccurredAt 是事件发生时间。
OccurredAt string
}
设计约束:
CommandDispatch.Kind=ingress 时才允许填写 RawRequest
- 控制命令如果语义上是“真实业务消息”,必须转成
RawRequest -> NormalizedRequest -> IngressRoutingEntry 主链
GatewaySnapshot 只能表达网关状态,不能提前写入路由结论
GatewayEventEnvelope 只负责分发,不负责改写事件事实
5. M1: Surface / Protocol / 协议接入模块
5.1 职责
- 接住 HTTP / WS / SSE 请求与连接
- 解析协议层请求头、路径、query、frame 与 body
- 把协议输入翻译成网关内部可消费的连接请求、控制命令或业务入站
- 把结果、事件和错误写回对应传输层
5.3 输入结构体
type SurfaceAcceptInput struct {
// Transport 是当前协议入口。
Transport GatewayTransportRef
// Headers 是原始请求头。
Headers map[string]string
// Query 是原始 query 参数。
Query map[string]string
// Body 是原始请求体或 frame 内容。
Body map[string]string
}
5.4 输出结构体
type SurfaceAcceptOutput struct {
// Connection 是当入口属于 connect / ws 建连时的连接请求。
Connection GatewayConnectionRequest
// Command 是当入口属于控制命令时的命令请求。
Command GatewayCommandRequest
// RawRequest 是当入口属于真实业务输入时产出的原始请求。
RawRequest RawRequest
}
type SurfaceWriteOutput struct {
// Transport 是最终写回的协议出口。
Transport GatewayTransportRef
// StatusCode 是 HTTP / WS 语义状态码。
StatusCode int
// Payload 是最终写回内容。
Payload map[string]string
}
5.5 公开函数
// Accept 把协议层请求翻译成网关内部入口对象。
// 当前由各 HTTP handler / WS dispatcher 在入口第一步调用。
func (s Surface) Accept(input SurfaceAcceptInput) (SurfaceAcceptOutput, error)
// Write 把网关内部结果写回 HTTP / WS / SSE。
// 当前由 gateway response helper 与 ws connection loop 消费。
func (s Surface) Write(output SurfaceWriteOutput) error
5.6 设计约束
Surface 只做协议适配,不做最终治理、路由和执行决策
Surface 可以区分 connect / command / business ingress,但不能直接决定 agent / session
- 任何长连接事件输出都应走统一
Write(...) 或等价出口,不在业务模块内部直接拼协议细节
6. M2: Access Governance / 治理标准化模块
6.1 职责
- 对
RawRequest 做认证、授权、限流、风控和审计前置
- 把通过治理的
RawRequest 变成 NormalizedRequest
- 对连接和控制命令做权限检查
- 拒绝不可信请求,并产出统一拒绝原因
6.3 输入结构体
type GovernanceAcceptInput struct {
// Request 是输入层交给网关的原始请求。
Request RawRequest
}
type GovernanceConnectionInput struct {
// Connection 是待建立的控制面连接。
Connection GatewayConnectionRequest
}
type GovernanceCommandInput struct {
// Command 是待执行的控制面命令。
Command GatewayCommandRequest
}
6.4 输出结构体
type GovernanceAcceptOutput struct {
// Request 是治理后的可信请求。
Request NormalizedRequest
}
type GovernanceConnectionOutput struct {
// Caller 是治理后确认的连接主体。
Caller GatewayCallerRef
}
type GovernanceCommandOutput struct {
// Command 是通过权限校验后的控制命令。
Command GatewayCommandRequest
}
6.5 公开函数
// Accept 对业务入站执行治理,并产出可信 NormalizedRequest。
// 当前对应文档主链中的 RawRequest -> NormalizedRequest。
func (g AccessGovernance) Accept(raw RawRequest) (NormalizedRequest, error)
// AuthorizeConnection 对控制面连接进行认证与准入判断。
func (g AccessGovernance) AuthorizeConnection(req GatewayConnectionRequest) (GatewayCallerRef, error)
// AuthorizeCommand 对控制命令进行授权与限流判断。
func (g AccessGovernance) AuthorizeCommand(req GatewayCommandRequest) (GatewayCommandRequest, error)
// Reject 记录拒绝原因并追加审计。
func (g AccessGovernance) Reject(raw RawRequest, reason string) error
6.6 设计约束
AccessGovernance 是网关层第二次标准化,即 RawRequest -> NormalizedRequest
- 它做的是可信化标准化,不是再次做输入协议适配
- 对控制面连接和控制命令可以做权限判定,但不能替代
Control Plane 或 Command Intake
- 拒绝原因必须可审计,不允许静默丢弃
7. M3: Control Plane / 控制面握手与快照模块
7.1 职责
- 处理 WS connect / hello / status / snapshot
- 向控制面调用者暴露当前 methods / events / state version
- 提供 gateway health / presence / status 视图
- 管理控制面长连接的初始化状态
7.3 输入结构体
type ControlPlaneConnectInput struct {
// Request 是已经通过治理的连接请求。
Request GatewayConnectionRequest
// Caller 是治理后确认的连接主体。
Caller GatewayCallerRef
}
type ControlPlaneSnapshotInput struct {
// Caller 是当前查看控制面快照的主体。
Caller GatewayCallerRef
}
7.4 输出结构体
type ControlPlaneConnectOutput struct {
// Ack 是建连成功后的 hello / snapshot 响应。
Ack GatewayConnectionAck
}
type ControlPlaneSnapshotOutput struct {
// Snapshot 是当前控制面快照。
Snapshot GatewaySnapshot
}
7.5 公开函数
// Connect 完成控制面握手并返回连接确认结果。
func (c ControlPlane) Connect(req GatewayConnectionRequest, caller GatewayCallerRef) (GatewayConnectionAck, error)
// Snapshot 返回当前控制面可见状态。
func (c ControlPlane) Snapshot(caller GatewayCallerRef) GatewaySnapshot
7.6 设计约束
ControlPlane 只负责连接、快照和状态,不直接受理真实业务消息
GatewaySnapshot 只能包含控制面能力与状态,不提前暴露路由结论
- 若当前实现中
/status、/ws、presence 逻辑散落在多处,应视为同一模块的实现拆散,而不是不同职责
8. M4: Command Intake / 控制命令受理模块
8.1 职责
- 识别控制命令是查询、修改还是“需要转成真实业务入站”
- 产出统一
CommandDispatch
- 把查询类和管理类命令分发给对应控制面域
- 把
chat.send 这类真实业务消息命令转入业务入站主链
8.3 输入结构体
type CommandIntakeInput struct {
// Request 是通过治理后的控制命令。
Request GatewayCommandRequest
}
8.4 输出结构体
type CommandIntakeOutput struct {
// Dispatch 是命令受理后的分发结果。
Dispatch CommandDispatch
}
8.5 公开函数
// Dispatch 识别控制命令类型,并决定是直接走控制面服务还是转成业务入站。
func (c CommandIntake) Dispatch(req GatewayCommandRequest) (CommandDispatch, error)
// Complete 把控制命令处理结果包装成统一返回结果。
func (c CommandIntake) Complete(req GatewayCommandRequest, payload map[string]string, status string) GatewayCommandResult
8.6 设计约束
sessions.list、tasks.get、agents.list 这类命令应直接走控制面域
chat.send、message.send 这类真实业务输入命令必须转成 RawRequest 再进入治理与路由交接主链
Command Intake 可以决定“是否进入业务入站主链”,但不能自己决定最终 agent / session
9. M5: Ingress Routing Handoff / 入站路由交接模块
9.1 职责
- 把治理后的
NormalizedRequest 包装成 IngressRoutingEntry
- 只透传显式
RoutingHint
- 作为网关层向路由层的唯一业务入站出口
- 保证进入路由层的对象合同稳定、精简、可信
9.3 输入结构体
type IngressRoutingHandoffInput struct {
// Request 是通过治理后的可信请求。
Request NormalizedRequest
// Hint 是显式 agent / session hint。
Hint RoutingHint
}
9.4 输出结构体
type IngressRoutingHandoffOutput struct {
// Entry 是交给路由层的唯一业务入站入口。
Entry IngressRoutingEntry
}
9.5 公开函数
// Prepare 把治理后的 NormalizedRequest 包装成 IngressRoutingEntry。
// 当前对应文档主链中的 NormalizedRequest -> IngressRoutingEntry。
func (h IngressRoutingHandoff) Prepare(request NormalizedRequest, hint RoutingHint) (IngressRoutingEntry, error)
9.6 设计约束
IngressRoutingHandoff 是网关层对路由层的唯一业务入站交接点
- 这里不能提前补写 agent / session / delivery 结论
- 这里做的是交接与封装,不是路由决策本身
10. M6: Events & Audit / 事件与审计模块
10.1 职责
- 记录系统事件与审计记录
- 管理事件订阅、事件流和广播
- 把内部事件包装成面向外部协议的
GatewayEventEnvelope
- 作为网关的统一事件回流中枢
10.3 输入结构体
type EventSubscribeInput struct {
// Subscription 是新的事件订阅。
Subscription GatewayEventSubscription
}
type EventPublishInput struct {
// Event 是待广播的系统事件。
Event EventRecord
}
type AuditAppendInput struct {
// Audit 是待持久化的审计记录。
Audit AuditRecord
}
10.4 输出结构体
type EventSubscribeOutput struct {
// Subscription 是确认后的订阅。
Subscription GatewayEventSubscription
}
type EventPublishOutput struct {
// Envelope 是发往订阅者的事件消息。
Envelope GatewayEventEnvelope
}
10.5 公开函数
// Subscribe 注册新的事件订阅。
func (e EventsAudit) Subscribe(sub GatewayEventSubscription) (GatewayEventSubscription, error)
// Publish 把内部事件包装后广播给外部订阅者。
func (e EventsAudit) Publish(event EventRecord) (GatewayEventEnvelope, error)
// AppendAudit 持久化审计记录。
func (e EventsAudit) AppendAudit(record AuditRecord) error
10.6 设计约束
Events & Audit 负责分发,不负责修改事件事实
- 事件广播可以承接执行层、路由层、网关层的结果,但不能替代这些层做决策
- 审计是独立职责,不能只依赖事件广播结果推导
11. 模块间接口关系
11.1 最常见的正向关系
Surface
-> AccessGovernance
-> ControlPlane / CommandIntake / IngressRoutingHandoff
11.2 真实业务消息关系
Surface
-> AccessGovernance.Accept(...)
-> IngressRoutingHandoff.Prepare(...)
-> Routing
11.3 事件回流关系
Routing / Runtime / Gateway Internal
-> EventsAudit.Publish(...)
-> Surface.Write(...)
12. anyclaw 当前总入口与交接
12.1 当前真实业务入站主链
HTTP / Webhook / Channel
-> gateway route / webhook handler
-> processChannelMessage(...) 或 runSessionMessage(...)
-> resolveChannelRoute(...)
-> route/ingress.Service.Route(...)
-> ensureChannelSession(...)
-> session runner
这条链说明:
- 当前
anyclaw1.2 里 Ingress Routing Handoff 还没有完全独立
- gateway 还夹带了一部分路由后衔接与执行入口
12.2 当前控制面链
/ws /status /control-plane /sessions /tasks
-> gateway route
-> auth / permission / rate limit
-> ws handler / api handler
-> response / stream
这条链说明:
- 当前
Surface、Governance、ControlPlane、CommandIntake 已经存在实现碎片
- 但它们还没有完全收口为稳定模块
12.3 当前事件回流链
appendEvent / appendAudit
-> gateway/events
-> store / bus
-> handleEventStream / ws event stream
这条链说明:
- 当前
Events & Audit 已经有较明确的中枢实现
- 但协议出口仍分散在 HTTP / WS helper 中
13. 最重要的边界结论
- 输入层负责协议标准化:
ExternalInput -> RawRequest
- 网关层负责治理标准化和路由交接:
RawRequest -> NormalizedRequest -> IngressRoutingEntry
- 路由层负责 agent / session /
DeliveryTarget
- 执行层负责真正运行 session / task / runtime
因此:
-
网关层的“入站标准化”不是再次做输入协议适配
-
网关层真正要补齐的是:
Surface
Governance
ControlPlane
CommandIntake
IngressRoutingHandoff
EventsAudit
-
其中最关键的业务主链只有一条:
RawRequest
-> NormalizedRequest
-> IngressRoutingEntry
- 其余链路是围绕这条主链配套存在的控制面、命令面和事件面
网关层模块规格
1. 范围
本文覆盖:
2. 四条主链路
2.1 WS 握手与状态链
它回答:
这条链路主要经过:
M1 Surface / ProtocolM2 Access GovernanceM3 Control Plane2.2 控制命令链
它回答:
这条链路主要经过:
M1 Surface / ProtocolM2 Access GovernanceM4 Command Intake2.3 真实业务消息链
它回答:
这条链路主要经过:
M2 Access GovernanceM5 Ingress Routing Handoff若入口来自 HTTP / WS,则在进入这条链路前还会先经过:
M1 Surface / ProtocolM4 Command Intake2.4 事件回流链
它回答:
这条链路主要经过:
M6 Events & AuditM1 Surface / Protocol3. 网关层职责与硬边界
3.1 网关层必须负责的事
RawRequest整理成可信NormalizedRequestIngressRoutingEntry3.2 网关层不能越过的边界
网关层里的三个对象不是一回事:
RawRequest:输入层翻译出的原始事实请求NormalizedRequest:网关治理后的可信请求IngressRoutingEntry:网关交给路由层的入站入口同理,网关层里的两个 delivery 概念也不是一回事:
DeliveryHint:入站时观察到的回发事实DeliveryTarget:路由层产出的最终投递目标必须写死的边界是:
NormalizedRequestIngressRoutingEntryDeliveryTarget4. 共享对象合同
本文复用
文档/输入层和网关层模块规格.md中的:RawRequestNormalizedRequestRoutingHintIngressRoutingEntryEventRecordAuditRecord4.1 网关控制面对象
4.2 命令与事件对象
设计约束:
CommandDispatch.Kind=ingress时才允许填写RawRequestRawRequest -> NormalizedRequest -> IngressRoutingEntry主链GatewaySnapshot只能表达网关状态,不能提前写入路由结论GatewayEventEnvelope只负责分发,不负责改写事件事实5. M1: Surface / Protocol / 协议接入模块
5.1 职责
5.3 输入结构体
5.4 输出结构体
5.5 公开函数
5.6 设计约束
Surface只做协议适配,不做最终治理、路由和执行决策Surface可以区分 connect / command / business ingress,但不能直接决定 agent / sessionWrite(...)或等价出口,不在业务模块内部直接拼协议细节6. M2: Access Governance / 治理标准化模块
6.1 职责
RawRequest做认证、授权、限流、风控和审计前置RawRequest变成NormalizedRequest6.3 输入结构体
6.4 输出结构体
6.5 公开函数
6.6 设计约束
AccessGovernance是网关层第二次标准化,即RawRequest -> NormalizedRequestControl Plane或Command Intake7. M3: Control Plane / 控制面握手与快照模块
7.1 职责
7.3 输入结构体
7.4 输出结构体
7.5 公开函数
7.6 设计约束
ControlPlane只负责连接、快照和状态,不直接受理真实业务消息GatewaySnapshot只能包含控制面能力与状态,不提前暴露路由结论/status、/ws、presence逻辑散落在多处,应视为同一模块的实现拆散,而不是不同职责8. M4: Command Intake / 控制命令受理模块
8.1 职责
CommandDispatchchat.send这类真实业务消息命令转入业务入站主链8.3 输入结构体
8.4 输出结构体
8.5 公开函数
8.6 设计约束
sessions.list、tasks.get、agents.list这类命令应直接走控制面域chat.send、message.send这类真实业务输入命令必须转成RawRequest再进入治理与路由交接主链Command Intake可以决定“是否进入业务入站主链”,但不能自己决定最终 agent / session9. M5: Ingress Routing Handoff / 入站路由交接模块
9.1 职责
NormalizedRequest包装成IngressRoutingEntryRoutingHint9.3 输入结构体
9.4 输出结构体
9.5 公开函数
9.6 设计约束
IngressRoutingHandoff是网关层对路由层的唯一业务入站交接点10. M6: Events & Audit / 事件与审计模块
10.1 职责
GatewayEventEnvelope10.3 输入结构体
10.4 输出结构体
10.5 公开函数
10.6 设计约束
Events & Audit负责分发,不负责修改事件事实11. 模块间接口关系
11.1 最常见的正向关系
11.2 真实业务消息关系
11.3 事件回流关系
12. anyclaw 当前总入口与交接
12.1 当前真实业务入站主链
这条链说明:
anyclaw1.2里Ingress Routing Handoff还没有完全独立12.2 当前控制面链
这条链说明:
Surface、Governance、ControlPlane、CommandIntake已经存在实现碎片12.3 当前事件回流链
这条链说明:
Events & Audit已经有较明确的中枢实现13. 最重要的边界结论
ExternalInput -> RawRequestRawRequest -> NormalizedRequest -> IngressRoutingEntryDeliveryTarget因此:
网关层的“入站标准化”不是再次做输入协议适配
网关层真正要补齐的是:
SurfaceGovernanceControlPlaneCommandIntakeIngressRoutingHandoffEventsAudit其中最关键的业务主链只有一条: