Skip to content

Gateway Layer Module Specification #112

@TheShigure7

Description

@TheShigure7

网关层模块规格

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 PlaneCommand 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/wspresence 逻辑散落在多处,应视为同一模块的实现拆散,而不是不同职责

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.listtasks.getagents.list 这类命令应直接走控制面域
  • chat.sendmessage.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.2Ingress Routing Handoff 还没有完全独立
  • gateway 还夹带了一部分路由后衔接与执行入口

12.2 当前控制面链

/ws /status /control-plane /sessions /tasks
  -> gateway route
  -> auth / permission / rate limit
  -> ws handler / api handler
  -> response / stream

这条链说明:

  • 当前 SurfaceGovernanceControlPlaneCommandIntake 已经存在实现碎片
  • 但它们还没有完全收口为稳定模块

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
  • 其余链路是围绕这条主链配套存在的控制面、命令面和事件面

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions