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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions