# `@drama/observability` · `ctx` 贯穿约定(权威原文) > 本文件是「`RequestContext` 作为显式首参 `ctx` 贯穿所有服务签名」约定的**单一事实来源**。 > 下游所有 service / application-service / repo / 路由的签名设计都引用本文。任何对 `RequestContext` > 形状、`Logger` 形状或本约定的改动,**必须先改本文件与任务文档 §3,再改代码**,因为它影响全仓所有签名。 ## 约定原文(硬性,被全仓引用) 一切跨进程边界进来的逻辑入口(HTTP 路由、定时任务、消息消费)在**最外层**创建或续传 `RequestContext`, 并把它作为**显式首参 `ctx`** 一路传递到 service、application-service、必要时到 repo。形如: ```js dramaService.buildBundle(ctx, dramaId) ``` **全仓所有 service 方法的第一形参必须是 `ctx: RequestContext`。** ## 红线 - **禁止**用 `AsyncLocalStorage` 等隐式穿透携带 ctx(架构基线点名旧参照版靠 ALS 隐式穿 billing 是反模式)。 `ctx` 必须**显式、可见、可测**。 - **禁止**用全局可变单例「偷偷」携带 ctx。 - 包内**不读 `process.env`**、**不建顶层连接**、**不在顶层装 OTel SDK**;`import` 本包无副作用。 ## 为什么 如果一期不定 `ctx` 贯穿约定,二期接 OpenTelemetry 就要回头给**每一个 service 函数**加 trace 参数、 给**每一处日志**补 `trace_id`——改造面是全仓。一期花几行定下约定与日志工厂,把这个改造面压成接近零。 ## 二期升级点(签名不变,调用方零改动) - `createRequestContext` 升级为携带真实 OTel span context。 - `createLogger` 接 OTel log bridge。 - `RequestContext` 形态与 `child` / 工厂入口**不变**——这是「一期约定先行」的开闭兑现点。