@sema-agent/server 7.79.0 → 7.79.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/file-history-disclosure.d.ts +53 -0
- package/dist/file-history-disclosure.js +89 -0
- package/dist/http/admission.d.ts +56 -0
- package/dist/http/admission.js +560 -0
- package/dist/http/approval-sweeps.d.ts +21 -0
- package/dist/http/approval-sweeps.js +138 -0
- package/dist/http/dispatch.d.ts +32 -0
- package/dist/http/dispatch.js +230 -0
- package/dist/http/request-guards.d.ts +51 -0
- package/dist/http/request-guards.js +205 -0
- package/dist/http/resume-legs.d.ts +80 -0
- package/dist/http/resume-legs.js +1230 -0
- package/dist/http/route-table.d.ts +113 -0
- package/dist/http/route-table.js +235 -0
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/memory-compliance.d.ts +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/rules.js +4 -4
- package/dist/http/server.d.ts +20 -104
- package/dist/http/server.js +24 -2589
- package/dist/main.js +2 -0
- package/dist/observability/metrics.js +1 -1
- package/dist/plugins/file-history-store-sql.js +12 -11
- package/dist/trace/redact.d.ts +9 -0
- package/dist/trace/redact.js +210 -78
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **路由声明表**(S-146,[ref] 波 2 第二刀)—— 「这是什么路由」这件事在本仓的**唯一属主**。
|
|
3
|
+
*
|
|
4
|
+
* ## 病(S-146 债行原文的读数)
|
|
5
|
+
* 同一件事此前有五份写法、两道扫源码文本的对账门,而那两道门已经**反向塑形了源码**:表里必须写
|
|
6
|
+
* 字面量不许引常量(否则门的正则抓不到)、注释里不许出现某两个字符(否则门的非贪婪捕获提前收尾)。
|
|
7
|
+
* ① 分派序 = `handle()` 里 37 只 `if (await handleX(...)) return;`,鉴权/排空/破坏性写三道门按**行号**
|
|
8
|
+
* 插在链中间(4 只 handler 落在凭据门前);
|
|
9
|
+
* ② `ROUTE_DOMAINS` = 同一条链的域名册,靠一道从 `handle()` 源码文本抽序的门与 ① 对拍(表曾漏员又乱序);
|
|
10
|
+
* ③ `ROUTE_LABEL_PATTERNS` / `ROUTE_LABEL_LITERALS` = metrics/日志的标签名册;
|
|
11
|
+
* ④ `isBillableSubmitPath` / `isMethodDispatchedSubmitPath` = 三道 503 计费门的 url 名单;
|
|
12
|
+
* ⑤ `isCredentialGatedRewrite` = 无凭据部署上的改写门 url×方法 名单。
|
|
13
|
+
* 五份各自漂过:wake 不在 ④ 里(三道门对一条烧模型的腿全不生效)、`handleDiagnostics` 从不在 ② 里、
|
|
14
|
+
* `/v1/fleet/stream` 整条对 ③ 隐形。
|
|
15
|
+
*
|
|
16
|
+
* ## 形(规则少了几条)
|
|
17
|
+
* **一行 = 一条路由事实**,两张表:
|
|
18
|
+
* · `ROUTES` —— **行序 = 分派序**,`position` 说它在全局服务凭据门的哪一侧。门不再「按行号插在链中间」,
|
|
19
|
+
* 而是在 `pre` 段与 `post` 段之间**恒定一处**执行 ⇒ ① 与 ② 合一(名册就是分派序本身,两者再不可能漂),
|
|
20
|
+
* 那道「从 handle() 源码抽序对拍」的门随之删掉 —— 不是放松,是它守的事变成了结构上不可违反。
|
|
21
|
+
* ⚠️ 刻意**不引入 matcher**:handler 自己判 url 这一点一个字不动(改它等于重写 34 个域模块的判路)。
|
|
22
|
+
* · `ROUTE_DECLARATIONS` —— ③④⑤ 合成一张;一行声明它的匹配式与它**真有**的性质
|
|
23
|
+
* (`billable` / `credentialGated` / `methodDispatched`),没有该性质就不写那一列(零默认值)。
|
|
24
|
+
*
|
|
25
|
+
* 判据两条,逐字:
|
|
26
|
+
* · **标签取首命中**(优先序):精确行先于形状行([[ref]] 的结论,这里是结构性的而不是靠行序),
|
|
27
|
+
* 形状行按声明序;没有任何行给标签 ⇒ `"other"`。
|
|
28
|
+
* · **门取并集**(宁紧):一条 url 只要**有一行**声明了某性质,它就有该性质 —— 这正是旧谓词那几个
|
|
29
|
+
* `||` 的逐字同义,也是「前缀行比标签行宽」这件事的正解(`/v1/devices/` 下将来长出的任何写动词
|
|
30
|
+
* 天然在改写门内,不必等谁想起来补一行标签)。
|
|
31
|
+
*
|
|
32
|
+
* 新增一条路由 = 新建 `routes/x.ts` + 本表加一行(+ `test/route-order-freeze.test.ts` 的冻结表加一行,
|
|
33
|
+
* 那是 position 的外部对拍源)。`position` 与匹配式都是必填 —— 忘了就是**编译红**,不是静默 404。
|
|
34
|
+
*
|
|
35
|
+
* 🔴 **旧禁令已解除**:标签表此前必须「写字面量不引常量」、注释里不许出现某两个字符 —— 那是两道
|
|
36
|
+
* 扫源码文本的门反向塑形源码的产物(它们的捕获正则抓不到常量、非贪婪捕获会被那对字符提前截断)。
|
|
37
|
+
* 两道门都改成读本表之后,这条禁令没有了对象,随它的 11 处行注一并删;要引常量就引(`routes/*.ts`
|
|
38
|
+
* 的 `*_PATH` 常量本来就是那些路径的单一属主)。
|
|
39
|
+
*
|
|
40
|
+
* 🔴 本文件是**叶模块**:只 import `routes/*.ts` 的 handler 与几只单源正则、以及类型。组合根与流水线
|
|
41
|
+
* (`server.ts` / `dispatch.ts`)一律反过来 import 它,值边单向,`test/module-cycle-gate.test.ts` 看守。
|
|
42
|
+
*/
|
|
43
|
+
import type { FlatServiceDeps } from "./server.js";
|
|
44
|
+
import type { RouteHandler } from "./route-ctx.js";
|
|
45
|
+
/** 一只域 handler 相对**全局服务凭据门**的位置。门前 = 未鉴权可达(每一只都要单独论证),门后 = 先过凭据。 */
|
|
46
|
+
export type RoutePosition = "pre-credential" | "post-credential";
|
|
47
|
+
export interface RouteRow {
|
|
48
|
+
/** 域入口(`routes/*.ts` 的 `handleX`)。签名一致性是编译期钉:入口漂了形 = 编译红,不是运行时静默 404。 */
|
|
49
|
+
readonly handler: RouteHandler;
|
|
50
|
+
/** 必填 —— 新增路由必须**显式**决定它在凭据门的哪一侧。 */
|
|
51
|
+
readonly position: RoutePosition;
|
|
52
|
+
/** 域名(kebab;= `routes/` 下的模块名)。评审把本表当「域全集」读时它是那份清单的名字列,
|
|
53
|
+
* `test/route-shape-roster.test.ts` 层E 的能力位词干也取自这里 —— 域的身份是声明出来的,
|
|
54
|
+
* 不是从函数名反推的。函数真名与它的一致性由 `route-order-freeze` 自检格钉住。 */
|
|
55
|
+
readonly label: string;
|
|
56
|
+
/** **挂载条件**(只有真有条件的行才写):缺席 = 恒挂载。域头的合取式就是挂载条件 —— 阀门没开 ⇒
|
|
57
|
+
* 请求落到分派器尾的全局 404(**诚实缺席,不是 501**;判据全文在各域模块头注)。 */
|
|
58
|
+
readonly enabled?: (deps: FlatServiceDeps) => boolean;
|
|
59
|
+
}
|
|
60
|
+
export declare const ROUTES: readonly RouteRow[];
|
|
61
|
+
/** 两段(`dispatch.ts` 的分派循环各跑一段)。段内序 = 本表行序;
|
|
62
|
+
* 「门前行不许出现在门后行之后」由 `test/route-order-freeze.test.ts` 钉住。 */
|
|
63
|
+
export declare const PRE_CREDENTIAL_ROUTES: readonly RouteRow[];
|
|
64
|
+
export declare const POST_CREDENTIAL_ROUTES: readonly RouteRow[];
|
|
65
|
+
/** 改写门是**方法感知**的(它的撤销动词是 DELETE)。闭集 —— 加第五个动词是编译红。 */
|
|
66
|
+
export type RouteMethod = "GET" | "POST" | "PUT" | "DELETE";
|
|
67
|
+
interface RouteDeclFacts {
|
|
68
|
+
/** 「这条 url **烧模型**」—— drain / model-roster-pending / 无 service-token 三道 503 的共同判别。
|
|
69
|
+
* 没有这一列 = 不烧模型(零默认值:要它为真必须显式写出来,漏写的方向是**少收一笔账单**而不是
|
|
70
|
+
* 少一道门 —— 反了才是灾难,所以三道门读的是 true 这一侧)。 */
|
|
71
|
+
readonly billable?: true;
|
|
72
|
+
/** 「本条 url 在**没有任何 service credential** 的部署形下,这几个方法必须 fail-closed」。
|
|
73
|
+
* 判据(两个合取项)= 「授权的唯一输入是 principal 头」∧「持久改写,或爆炸半径跨租户的治理读」;
|
|
74
|
+
* 逐口论证在各 `routes/*.ts` 的头注里,本表只记结论。 */
|
|
75
|
+
readonly credentialGated?: readonly RouteMethod[];
|
|
76
|
+
/** 「这条 url **是**计费提交面,但它到底提不提交由**请求体里的方法**决定」—— 单 URL 多方法的
|
|
77
|
+
* JSON-RPC 端点。两道**可用性** 503(drain / roster-pending)按 url 一刀切会把同端点上的纯读一起
|
|
78
|
+
* 关掉,所以分派器对本行**跳过**那两道,改由域模块在写分支里施加同样的两道(文案逐字同源)。
|
|
79
|
+
* 🔴 只豁免那两道,**不豁免安全轴**:`billable` 本身仍为 true,无 service token 那道 fail-closed
|
|
80
|
+
* 503 照旧罩着(它判的是「这台机能不能收写」,与方法无关,且必须在解析请求体之前)。 */
|
|
81
|
+
readonly methodDispatched?: true;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 一行的匹配式三选一(闭集;`path` 行的标签**就是** path 自身,所以它没有 label 列 —— 少一处手抄)。
|
|
85
|
+
* `prefix` 与 `pattern` 行的 label 可缺席:那是**纯门行**(比标签行宽,只供门的并集判据),
|
|
86
|
+
* 缺席 ⇒ 本行不铸任何标签。
|
|
87
|
+
*/
|
|
88
|
+
export type RouteDecl = (RouteDeclFacts & {
|
|
89
|
+
readonly path: string;
|
|
90
|
+
}) | (RouteDeclFacts & {
|
|
91
|
+
readonly prefix: string;
|
|
92
|
+
readonly label?: string;
|
|
93
|
+
}) | (RouteDeclFacts & {
|
|
94
|
+
readonly pattern: RegExp;
|
|
95
|
+
readonly label?: string;
|
|
96
|
+
});
|
|
97
|
+
/** 🔴 由 `test/route-shape-roster.test.ts` 棘轮看守:门机器枚举 `src/http/**` 的全部路由模式并断言每条
|
|
98
|
+
* 都映射到非 "other"——新路由不补本表该门当场红(census 抓获本表曾漂掉 56 条模式:session-sync/workspace/
|
|
99
|
+
* workflows/subagents/attachments/images/leader 等整族全折 "other",metrics 不可分桶)。 */
|
|
100
|
+
export declare const ROUTE_DECLARATIONS: readonly RouteDecl[];
|
|
101
|
+
/** Stable, low-cardinality route label for metrics/logs (ids collapsed to `:id`). */
|
|
102
|
+
export declare function routeLabel(_method: string, url: string): string;
|
|
103
|
+
/** POST endpoints that trigger BILLABLE work — the fail-closed auth guard must cover ALL of them. */
|
|
104
|
+
export declare function isBillableSubmitPath(url: string): boolean;
|
|
105
|
+
/** [ref]([ref] 件5)—— **改写门**:不烧模型、但在没有任何 service credential 的部署形下必须
|
|
106
|
+
* 与 billable / bake 两族一样 fail-closed 的写门。与 `isBillableSubmitPath` **刻意分开**:这几扇门
|
|
107
|
+
* `billable=false`(零模型工作),塞进那张名单会让它们连带吃 drain 与 roster-pending 两道 503 ——
|
|
108
|
+
* 而收编与规则读写在排空期/roster 未落时做完全无害。 */
|
|
109
|
+
export declare function isCredentialGatedRewrite(method: string, url: string): boolean;
|
|
110
|
+
/** 见 `RouteDeclFacts.methodDispatched` 的头注(单 URL 多方法端点)。 */
|
|
111
|
+
export declare function isMethodDispatchedSubmitPath(url: string): boolean;
|
|
112
|
+
export {};
|
|
113
|
+
//# sourceMappingURL=route-table.d.ts.map
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { handleCapabilities } from "./routes/capabilities.js";
|
|
2
|
+
import { handleObservability } from "./routes/observability.js";
|
|
3
|
+
import { handleDiagnostics } from "./routes/diagnostics.js";
|
|
4
|
+
import { handleAdoption } from "./routes/adoption.js";
|
|
5
|
+
import { handleRetention } from "./routes/retention-ops.js";
|
|
6
|
+
import { handleAdminDrain } from "./routes/admin-drain.js";
|
|
7
|
+
import { handleDevices } from "./routes/devices.js";
|
|
8
|
+
import { handleAdminConfigRefresh } from "./routes/admin-config-refresh.js";
|
|
9
|
+
import { handleConfigCatalog } from "./routes/config-catalog.js";
|
|
10
|
+
import { handleMemoryOptOut } from "./routes/admin-memory-optout.js";
|
|
11
|
+
import { handleMemoryPolicy } from "./routes/memory-policy.js";
|
|
12
|
+
import { handleMemoryBundle } from "./routes/memory-bundle.js";
|
|
13
|
+
import { handleMemoryCompliance } from "./routes/memory-compliance.js";
|
|
14
|
+
import { handleMemoryOrigin } from "./routes/memory-origin.js";
|
|
15
|
+
import { handleMemoryConsolidation } from "./routes/memory-consolidation.js";
|
|
16
|
+
import { handleSharedMemory } from "./routes/shared-memory.js";
|
|
17
|
+
import { handleRules } from "./routes/rules.js";
|
|
18
|
+
import { handleSessionsList } from "./routes/sessions-list.js";
|
|
19
|
+
import { handleAgentRoster } from "./routes/agents-roster.js";
|
|
20
|
+
import { handleSessions } from "./routes/sessions.js";
|
|
21
|
+
import { handleSessionSync } from "./routes/session-sync.js";
|
|
22
|
+
import { handleAttachments } from "./routes/attachments.js";
|
|
23
|
+
import { handleFleet } from "./routes/fleet.js";
|
|
24
|
+
import { handleA2aServe, handleA2a } from "./routes/a2a-serve.js";
|
|
25
|
+
import { handleTraceUsage } from "./routes/trace-usage.js";
|
|
26
|
+
import { handleWorkflows, handleWorkflowAgentSteer } from "./routes/workflows.js";
|
|
27
|
+
import { handleNotifyWake, SESSION_WAKE_RE } from "./routes/notify-wake.js";
|
|
28
|
+
import { handleApprovalsAssistant, ASSISTANT_RESUME_RE, ASSISTANT_PLAN_REVIEW_RE } from "./routes/approvals-assistant.js";
|
|
29
|
+
import { handleRuns, handleRunVerbs, RUN_SUBAGENT_RESUME_RE } from "./routes/runs.js";
|
|
30
|
+
import { handleRunMemoryCapture } from "./routes/run-memory-capture.js";
|
|
31
|
+
import { handleSideQuery } from "./routes/side-query.js";
|
|
32
|
+
import { handleTasks } from "./routes/tasks.js";
|
|
33
|
+
import { handleLeader } from "./routes/leader.js";
|
|
34
|
+
import { handleImages } from "./routes/images.js";
|
|
35
|
+
export const ROUTES = [
|
|
36
|
+
{ handler: handleTraceUsage, position: "pre-credential", label: "trace-usage" },
|
|
37
|
+
{ handler: handleWorkflows, position: "pre-credential", label: "workflows" },
|
|
38
|
+
{ handler: handleFleet, position: "pre-credential", label: "fleet" },
|
|
39
|
+
{ handler: handleA2aServe, position: "pre-credential", label: "a2a-serve" },
|
|
40
|
+
{ handler: handleCapabilities, position: "post-credential", label: "capabilities" },
|
|
41
|
+
{ handler: handleSideQuery, position: "post-credential", label: "side-query" },
|
|
42
|
+
{ handler: handleTasks, position: "post-credential", label: "tasks" },
|
|
43
|
+
{ handler: handleRuns, position: "post-credential", label: "runs" },
|
|
44
|
+
{ handler: handleA2a, position: "post-credential", label: "a2a" },
|
|
45
|
+
{ handler: handleWorkflowAgentSteer, position: "post-credential", label: "workflow-agent-steer" },
|
|
46
|
+
{ handler: handleRunVerbs, position: "post-credential", label: "run-verbs" },
|
|
47
|
+
{ handler: handleRunMemoryCapture, position: "post-credential", label: "run-memory-capture" },
|
|
48
|
+
{ handler: handleLeader, position: "post-credential", label: "leader" },
|
|
49
|
+
{ handler: handleImages, position: "post-credential", label: "images" },
|
|
50
|
+
{ handler: handleApprovalsAssistant, position: "post-credential", label: "approvals-assistant" },
|
|
51
|
+
{ handler: handleObservability, position: "post-credential", label: "observability" },
|
|
52
|
+
{ handler: handleDiagnostics, position: "post-credential", label: "diagnostics" },
|
|
53
|
+
{ handler: handleAdoption, position: "post-credential", label: "adoption" },
|
|
54
|
+
{ handler: handleRetention, position: "post-credential", label: "retention" },
|
|
55
|
+
{ handler: handleAdminDrain, position: "post-credential", label: "admin-drain" },
|
|
56
|
+
{ handler: handleDevices, position: "post-credential", label: "devices" },
|
|
57
|
+
{ handler: handleAdminConfigRefresh, position: "post-credential", label: "admin-config-refresh" },
|
|
58
|
+
{ handler: handleConfigCatalog, position: "post-credential", label: "config-catalog" },
|
|
59
|
+
{ handler: handleMemoryOptOut, position: "post-credential", label: "memory-opt-out" },
|
|
60
|
+
{ handler: handleMemoryPolicy, position: "post-credential", label: "memory-policy" },
|
|
61
|
+
{ handler: handleMemoryBundle, position: "post-credential", label: "memory-bundle" },
|
|
62
|
+
{ handler: handleMemoryCompliance, position: "post-credential", label: "memory-compliance" },
|
|
63
|
+
{ handler: handleMemoryOrigin, position: "post-credential", label: "memory-origin" },
|
|
64
|
+
{ handler: handleMemoryConsolidation, position: "post-credential", label: "memory-consolidation", enabled: (deps) => Boolean(deps.memoryConsolidation) },
|
|
65
|
+
{ handler: handleRules, position: "post-credential", label: "rules" },
|
|
66
|
+
{ handler: handleSharedMemory, position: "post-credential", label: "shared-memory", enabled: (deps) => Boolean(deps.sharedMemoryStore) && Boolean(deps.orgMemoryDirectory) },
|
|
67
|
+
{ handler: handleSessionsList, position: "post-credential", label: "sessions-list" },
|
|
68
|
+
{ handler: handleAgentRoster, position: "post-credential", label: "agent-roster" },
|
|
69
|
+
{ handler: handleSessions, position: "post-credential", label: "sessions" },
|
|
70
|
+
{ handler: handleSessionSync, position: "post-credential", label: "session-sync" },
|
|
71
|
+
{ handler: handleAttachments, position: "post-credential", label: "attachments" },
|
|
72
|
+
{ handler: handleNotifyWake, position: "post-credential", label: "notify-wake" },
|
|
73
|
+
];
|
|
74
|
+
export const PRE_CREDENTIAL_ROUTES = ROUTES.filter((r) => r.position === "pre-credential");
|
|
75
|
+
export const POST_CREDENTIAL_ROUTES = ROUTES.filter((r) => r.position === "post-credential");
|
|
76
|
+
export const ROUTE_DECLARATIONS = [
|
|
77
|
+
{ path: "/health" },
|
|
78
|
+
{ path: "/metrics" },
|
|
79
|
+
{ path: "/metrics/summary" },
|
|
80
|
+
{ path: "/metrics/plan-cache" },
|
|
81
|
+
{ path: "/v1/models" },
|
|
82
|
+
{ path: "/v1/tasks", billable: true },
|
|
83
|
+
{ path: "/v1/tasks/stream", billable: true },
|
|
84
|
+
{ path: "/v1/tasks/source-summary" },
|
|
85
|
+
{ path: "/v1/runs", billable: true },
|
|
86
|
+
{ path: "/v1/sessions" },
|
|
87
|
+
{ path: "/v1/approvals" },
|
|
88
|
+
{ path: "/v1/approvals/stream" },
|
|
89
|
+
{ path: "/v1/assistant/inbox" },
|
|
90
|
+
{ path: "/v1/assistant/tasks" },
|
|
91
|
+
{ path: "/v1/usage" },
|
|
92
|
+
{ path: "/v1/policy" },
|
|
93
|
+
{ path: "/v1/capabilities" },
|
|
94
|
+
{ path: "/v1/images" },
|
|
95
|
+
{ path: "/v1/images/bakes" },
|
|
96
|
+
{ path: "/v1/images/bakes/claim" },
|
|
97
|
+
{ path: "/v1/images/select" },
|
|
98
|
+
{ path: "/v1/images/register" },
|
|
99
|
+
{ path: "/v1/workflows" },
|
|
100
|
+
{ path: "/v1/attachments" },
|
|
101
|
+
{ path: "/v1/leader", billable: true },
|
|
102
|
+
{ path: "/v1/outcomes" },
|
|
103
|
+
{ path: "/v1/side-query", billable: true },
|
|
104
|
+
{ path: "/v1/devices", credentialGated: ["GET"] },
|
|
105
|
+
{ path: "/v1/fleet/stream" },
|
|
106
|
+
{ path: "/v1/memory/export", credentialGated: ["POST"] },
|
|
107
|
+
{ path: "/v1/sendfile-links" },
|
|
108
|
+
{ path: "/v1/memory/import", credentialGated: ["POST"] },
|
|
109
|
+
{ path: "/v1/memory/erase", credentialGated: ["POST"] },
|
|
110
|
+
{ path: "/v1/memory/origin/external", credentialGated: ["GET"] },
|
|
111
|
+
{ path: "/v1/memory/origin/clearances", credentialGated: ["GET"] },
|
|
112
|
+
{ path: "/v1/shared-memory/stores" },
|
|
113
|
+
{ path: "/v1/diagnostics/wiring" },
|
|
114
|
+
{ path: "/v1/adoption", credentialGated: ["POST"] },
|
|
115
|
+
{ path: "/v1/admin/drain" },
|
|
116
|
+
{ path: "/v1/admin/config/refresh" },
|
|
117
|
+
{ path: "/v1/config/catalog" },
|
|
118
|
+
{ path: "/v1/admin/memory-optout", credentialGated: ["GET", "PUT"] },
|
|
119
|
+
{ path: "/v1/admin/memory/consolidation/run", billable: true },
|
|
120
|
+
{ path: "/v1/admin/memory/consolidation" },
|
|
121
|
+
{ path: "/v1/rules/cc-import/prepare" },
|
|
122
|
+
{ path: "/v1/rules/cc-import/redeem" },
|
|
123
|
+
{ path: "/v1/rules/local-import/prepare" },
|
|
124
|
+
{ path: "/v1/rules/local-import/redeem" },
|
|
125
|
+
{ path: "/v1/rules", credentialGated: ["DELETE"] },
|
|
126
|
+
{ path: "/.well-known/agent-card.json" },
|
|
127
|
+
{ path: "/v1/a2a", billable: true, methodDispatched: true },
|
|
128
|
+
{ path: "/v1/agents/roster" },
|
|
129
|
+
{ path: "/v1/ops/retention/audit" },
|
|
130
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/steer$/, label: "/v1/runs/:id/steer" },
|
|
131
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/memory\/capture-optout$/, label: "/v1/runs/:id/memory/capture-optout" },
|
|
132
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/interrupt$/, label: "/v1/runs/:id/interrupt" },
|
|
133
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/detach$/, label: "/v1/runs/:id/detach" },
|
|
134
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/cancel$/, label: "/v1/runs/:id/cancel" },
|
|
135
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/compact$/, label: "/v1/runs/:id/compact" },
|
|
136
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/events$/, label: "/v1/runs/:id/events" },
|
|
137
|
+
{ pattern: RUN_SUBAGENT_RESUME_RE, label: "/v1/runs/:id/subagents/:sub/*", billable: true },
|
|
138
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/subagents\/[^/]+\/(steer|resume|output|stream)$/, label: "/v1/runs/:id/subagents/:sub/*" },
|
|
139
|
+
{ pattern: /^\/v1\/runs\/[^/]+\/tasks\/[^/]+\/(output|stop)$/, label: "/v1/runs/:id/tasks/:tid/*" },
|
|
140
|
+
{ pattern: /^\/v1\/runs\/[^/]+$/, label: "/v1/runs/:id" },
|
|
141
|
+
{ pattern: /^\/v1\/images\/bakes\/[^/]+\/events$/, label: "/v1/images/bakes/:id/events" },
|
|
142
|
+
{ pattern: /^\/v1\/images\/bakes\/[^/]+\/cancel$/, label: "/v1/images/bakes/:id/cancel" },
|
|
143
|
+
{ pattern: /^\/v1\/images\/bakes\/[^/]+\/claim$/, label: "/v1/images/bakes/:id/claim" },
|
|
144
|
+
{ pattern: /^\/v1\/images\/bakes\/[^/]+\/ingest$/, label: "/v1/images/bakes/:id/ingest" },
|
|
145
|
+
{ pattern: /^\/v1\/images\/bakes\/[^/]+$/, label: "/v1/images/bakes/:id" },
|
|
146
|
+
{ pattern: /^\/v1\/images\/digests\/[^/]+$/, label: "/v1/images/digests/:digest" },
|
|
147
|
+
{ pattern: /^\/v1\/images\/[^/]+$/, label: "/v1/images/:profile" },
|
|
148
|
+
{ pattern: /^\/v1\/approvals\/[^/]+\/decide$/, label: "/v1/approvals/:id/decide" },
|
|
149
|
+
{ pattern: /^\/v1\/approvals\/[^/]+\/exemptions(\/[^/]+)?$/, label: "/v1/approvals/:id/exemptions" },
|
|
150
|
+
{ pattern: SESSION_WAKE_RE, label: "/v1/sessions/:id/$verb", billable: true },
|
|
151
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/(wake|fork|init|notify|events|head|mcp|a2a|policy|settings)$/, label: "/v1/sessions/:id/$verb" },
|
|
152
|
+
{ pattern: /^\/v1\/admin\/memory-optout\/[^/]+$/, label: "/v1/admin/memory-optout/:principal" },
|
|
153
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/memory\/erase$/, label: "/v1/sessions/:id/memory/erase" },
|
|
154
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/memory-status$/, label: "/v1/sessions/:id/memory-status" },
|
|
155
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/sync\/(manifest|entries|plan)$/, label: "/v1/sessions/:id/sync/$verb" },
|
|
156
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/sync\/import(\/[^/]+\/entries)?$/, label: "/v1/sessions/:id/sync/import" },
|
|
157
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/sync\/blobs(\/[^/]+)?$/, label: "/v1/sessions/:id/sync/blobs" },
|
|
158
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/sync\/history\/blobs\/[^/]+$/, label: "/v1/sessions/:id/sync/history/blobs/:hash" },
|
|
159
|
+
{ pattern: /^\/v1\/sessions\/[^/]+\/workspace(\/[^/]+(\/(tree|file|archive))?)?$/, label: "/v1/sessions/:id/workspace" },
|
|
160
|
+
{ pattern: /^\/v1\/sessions\/[^/]+$/, label: "/v1/sessions/:id" },
|
|
161
|
+
{ pattern: /^\/v1\/assistant\/tasks\/[^/]+\/preempt$/, label: "/v1/assistant/tasks/:id/preempt" },
|
|
162
|
+
{ pattern: ASSISTANT_RESUME_RE, label: "/v1/assistant/tasks/:id/resume", billable: true },
|
|
163
|
+
{ pattern: ASSISTANT_PLAN_REVIEW_RE, label: "/v1/assistant/tasks/:id/plan_review", billable: true },
|
|
164
|
+
{ pattern: /^\/v1\/elicitations\/[^/]+\/respond$/, label: "/v1/elicitations/:id/respond" },
|
|
165
|
+
{ pattern: /^\/v1\/questions\/[^/]+\/respond$/, label: "/v1/questions/:id/respond" },
|
|
166
|
+
{ pattern: /^\/v1\/tool-approvals\/[^/]+\/respond$/, label: "/v1/tool-approvals/:id/respond" },
|
|
167
|
+
{ pattern: /^\/v1\/workflows\/[^/]+\/agents\/[^/]+\/steer$/, label: "/v1/workflows/:id/agents/:aid/steer" },
|
|
168
|
+
{ pattern: /^\/v1\/workflows\/[^/]+\/(stream|journal)$/, label: "/v1/workflows/:id/$sub" },
|
|
169
|
+
{ pattern: /^\/v1\/workflows\/[^/]+$/, label: "/v1/workflows/:id" },
|
|
170
|
+
{ pattern: /^\/v1\/tasks\/[^/]+\/asks\/[^/]+\/decision$/, label: "/v1/tasks/:id/asks/:askId/decision" },
|
|
171
|
+
{ pattern: /^\/v1\/tasks\/[^/]+\/tool-results\/[^/]+$/, label: "/v1/tasks/:id/tool-results/:ref" },
|
|
172
|
+
{ pattern: /^\/v1\/tasks\/[^/]+\/(turns|stream|artifacts)$/, label: "/v1/tasks/:id/$sub" },
|
|
173
|
+
{ pattern: /^\/v1\/leader\/[^/]+$/, label: "/v1/leader/:id" },
|
|
174
|
+
{ pattern: /^\/v1\/devices\/sessions\/[^/]+\/rebind$/, label: "/v1/devices/sessions/:id/rebind" },
|
|
175
|
+
{ pattern: /^\/v1\/devices\/sessions\/[^/]+$/, label: "/v1/devices/sessions/:id", credentialGated: ["GET"] },
|
|
176
|
+
{ pattern: /^\/v1\/attachments\/[^/]+$/, label: "/v1/attachments/:id" },
|
|
177
|
+
{ pattern: /^\/v1\/capabilities\/scenarios\/[^/]+$/, label: "/v1/capabilities/scenarios/:name" },
|
|
178
|
+
{ pattern: /^\/v1\/adoption\/[^/]+$/, label: "/v1/adoption/:id" },
|
|
179
|
+
{ pattern: /^\/v1\/ops\/retention\/holds\/[^/]*$/, label: "/v1/ops/retention/holds/:domain" },
|
|
180
|
+
{ pattern: /^\/v1\/memory\/sync\/[^/]+$/, label: "/v1/memory/sync/:scope" },
|
|
181
|
+
{ pattern: /^\/v1\/memory\/entries\/[^/]+\/provenance$/, label: "/v1/memory/entries/:entryId/provenance", credentialGated: ["GET"] },
|
|
182
|
+
{ pattern: /^\/v1\/memory\/origin\/entries\/[^/]+\/clear$/, label: "/v1/memory/origin/entries/:entryId/clear" },
|
|
183
|
+
{ pattern: /^\/v1\/usage\/(summary|series|breakdown)$/, label: "/v1/usage/$sub" },
|
|
184
|
+
{ pattern: /^\/v1\/shared-memory\/stores\/[^/]+\/documents$/, label: "/v1/shared-memory/stores/:store/documents" },
|
|
185
|
+
{ pattern: /^\/v1\/shared-memory\/stores\/[^/]+\/document$/, label: "/v1/shared-memory/stores/:store/document" },
|
|
186
|
+
{ prefix: "/v1/approvals", billable: true },
|
|
187
|
+
{ prefix: "/v1/rules/cc-import/", credentialGated: ["POST"] },
|
|
188
|
+
{ prefix: "/v1/rules/local-import/", credentialGated: ["POST"] },
|
|
189
|
+
{ prefix: "/v1/memory/origin/entries/", credentialGated: ["POST"] },
|
|
190
|
+
{ prefix: "/v1/devices/", credentialGated: ["POST"] },
|
|
191
|
+
{ prefix: "/v1/admin/memory-optout/", credentialGated: ["PUT", "DELETE"] },
|
|
192
|
+
];
|
|
193
|
+
function declMatches(d, url) {
|
|
194
|
+
if ("path" in d)
|
|
195
|
+
return url === d.path;
|
|
196
|
+
if ("prefix" in d)
|
|
197
|
+
return url.startsWith(d.prefix);
|
|
198
|
+
return d.pattern.test(url);
|
|
199
|
+
}
|
|
200
|
+
const LABEL_BY_PATH = new Map(ROUTE_DECLARATIONS.flatMap((d) => ("path" in d ? [[d.path, d.path]] : [])));
|
|
201
|
+
const SHAPED_LABEL_DECLS = ROUTE_DECLARATIONS.filter((d) => !("path" in d) && typeof d.label === "string");
|
|
202
|
+
const BILLABLE_DECLS = ROUTE_DECLARATIONS.filter((d) => d.billable === true);
|
|
203
|
+
const METHOD_DISPATCHED_DECLS = ROUTE_DECLARATIONS.filter((d) => d.methodDispatched === true);
|
|
204
|
+
const CREDENTIAL_GATED_BY_METHOD = (() => {
|
|
205
|
+
const m = new Map();
|
|
206
|
+
for (const d of ROUTE_DECLARATIONS)
|
|
207
|
+
for (const method of d.credentialGated ?? []) {
|
|
208
|
+
const bucket = m.get(method);
|
|
209
|
+
if (bucket === undefined)
|
|
210
|
+
m.set(method, [d]);
|
|
211
|
+
else
|
|
212
|
+
bucket.push(d);
|
|
213
|
+
}
|
|
214
|
+
return m;
|
|
215
|
+
})();
|
|
216
|
+
export function routeLabel(_method, url) {
|
|
217
|
+
const exact = LABEL_BY_PATH.get(url);
|
|
218
|
+
if (exact !== undefined)
|
|
219
|
+
return exact;
|
|
220
|
+
for (const d of SHAPED_LABEL_DECLS)
|
|
221
|
+
if (declMatches(d, url))
|
|
222
|
+
return d.label;
|
|
223
|
+
return "other";
|
|
224
|
+
}
|
|
225
|
+
export function isBillableSubmitPath(url) {
|
|
226
|
+
return BILLABLE_DECLS.some((d) => declMatches(d, url));
|
|
227
|
+
}
|
|
228
|
+
export function isCredentialGatedRewrite(method, url) {
|
|
229
|
+
const rows = CREDENTIAL_GATED_BY_METHOD.get(method.toUpperCase());
|
|
230
|
+
return rows !== undefined && rows.some((d) => declMatches(d, url));
|
|
231
|
+
}
|
|
232
|
+
export function isMethodDispatchedSubmitPath(url) {
|
|
233
|
+
return METHOD_DISPATCHED_DECLS.some((d) => declMatches(d, url));
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=route-table.js.map
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
43
43
|
import type { RouteCtx } from "../route-ctx.js";
|
|
44
44
|
export declare const ADMIN_MEMORY_OPTOUT_PATH = "/v1/admin/memory-optout";
|
|
45
|
-
/** 带参口(`:principal`)⇒
|
|
45
|
+
/** 带参口(`:principal`)⇒ 路由声明表(`http/route-table.ts`)里走 `pattern` 行,不是 `path` 行。 */
|
|
46
46
|
export declare const ADMIN_MEMORY_OPTOUT_OVERRIDE_RE: RegExp;
|
|
47
47
|
export declare function handleMemoryOptOut(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
|
|
48
48
|
//# sourceMappingURL=admin-memory-optout.d.ts.map
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
97
97
|
import type { RouteCtx } from "../route-ctx.js";
|
|
98
98
|
export declare const MEMORY_ERASE_PATH = "/v1/memory/erase";
|
|
99
|
-
/** 单条出处读面。带参路径 ⇒
|
|
99
|
+
/** 单条出处读面。带参路径 ⇒ 路由声明表(`http/route-table.ts`)里走 `pattern` 行,不是 `path` 行。 */
|
|
100
100
|
export declare const MEMORY_PROVENANCE_RE: RegExp;
|
|
101
101
|
export declare function handleMemoryCompliance(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
|
|
102
102
|
//# sourceMappingURL=memory-compliance.d.ts.map
|
|
@@ -82,7 +82,7 @@ import { type OriginClearanceRow } from "@sema-agent/core";
|
|
|
82
82
|
import type { RouteCtx } from "../route-ctx.js";
|
|
83
83
|
export declare const MEMORY_ORIGIN_EXTERNAL_PATH = "/v1/memory/origin/external";
|
|
84
84
|
export declare const MEMORY_ORIGIN_CLEARANCES_PATH = "/v1/memory/origin/clearances";
|
|
85
|
-
/** 带参写口 ⇒
|
|
85
|
+
/** 带参写口 ⇒ 路由声明表(`http/route-table.ts`)里走 `pattern` 行,不是 `path` 行。 */
|
|
86
86
|
export declare const MEMORY_ORIGIN_CLEAR_RE: RegExp;
|
|
87
87
|
/**
|
|
88
88
|
* 一条清标行 → wire 的**显式白名单**(F-7)。全文理由见文件头「为什么是白名单」。
|
|
@@ -92,10 +92,10 @@ async function handleRulesBody(req, res, url, ctx, miss) {
|
|
|
92
92
|
const { readJson, rateLimited } = ctx.helpers;
|
|
93
93
|
const isPrepare = req.method === "POST" && url === RULES_CC_IMPORT_PREPARE_PATH;
|
|
94
94
|
const isRedeem = req.method === "POST" && url === RULES_CC_IMPORT_REDEEM_PATH;
|
|
95
|
-
const isLocalPrepare = req.method === "POST" && url ===
|
|
96
|
-
const isLocalRedeem = req.method === "POST" && url ===
|
|
97
|
-
const isList = req.method === "GET" && url ===
|
|
98
|
-
const isRevoke = req.method === "DELETE" && url ===
|
|
95
|
+
const isLocalPrepare = req.method === "POST" && url === RULES_LOCAL_IMPORT_PREPARE_PATH;
|
|
96
|
+
const isLocalRedeem = req.method === "POST" && url === RULES_LOCAL_IMPORT_REDEEM_PATH;
|
|
97
|
+
const isList = req.method === "GET" && url === RULES_PATH;
|
|
98
|
+
const isRevoke = req.method === "DELETE" && url === RULES_PATH;
|
|
99
99
|
if (!isPrepare && !isRedeem && !isList && !isRevoke && !isLocalPrepare && !isLocalRedeem) {
|
|
100
100
|
miss.fell = true;
|
|
101
101
|
return;
|
package/dist/http/server.d.ts
CHANGED
|
@@ -34,6 +34,11 @@ import { cascadeConfig } from "./run-meta.js";
|
|
|
34
34
|
export { cascadeConfig };
|
|
35
35
|
import { coarseStatusForState, errorCodeForExit } from "./routes/images.js";
|
|
36
36
|
export { coarseStatusForState, errorCodeForExit };
|
|
37
|
+
import { MAX_SKILL_CONTENT_CHARS, MAX_SYSTEM_PROMPT_CHARS, MAX_OUTPUT_SCHEMA_CHARS, validateUserSkills } from "./admission.js";
|
|
38
|
+
import { hasServiceAuth } from "./dispatch.js";
|
|
39
|
+
import { routeLabel, isBillableSubmitPath, isCredentialGatedRewrite, isMethodDispatchedSubmitPath } from "./route-table.js";
|
|
40
|
+
export { routeLabel, isBillableSubmitPath, isCredentialGatedRewrite, isMethodDispatchedSubmitPath, hasServiceAuth };
|
|
41
|
+
export { MAX_SKILL_CONTENT_CHARS, MAX_SYSTEM_PROMPT_CHARS, MAX_OUTPUT_SCHEMA_CHARS, validateUserSkills };
|
|
37
42
|
import { explicitOperatorOk, isOperator } from "./principal-gate.js";
|
|
38
43
|
export { explicitOperatorOk, isOperator };
|
|
39
44
|
/** Per-request authorization context resolved before building the spec (identity, owned session). */
|
|
@@ -730,43 +735,15 @@ export type FlatServiceDeps = ServiceCoreDeps & Partial<ServiceStoreDeps & Servi
|
|
|
730
735
|
export type ServiceDeps = FlatServiceDeps & ServiceDepGroups;
|
|
731
736
|
/** 分组入参 → 平铺视图(createHttpServer 的第一件事)。一组都没给 ⇒ 原样返回(存量调用零开销、零形变)。 */
|
|
732
737
|
export declare function flattenServiceDeps(deps: ServiceDeps): FlatServiceDeps;
|
|
733
|
-
/**
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
738
|
-
*
|
|
739
|
-
*
|
|
740
|
-
*
|
|
741
|
-
|
|
742
|
-
export declare const MAX_SYSTEM_PROMPT_CHARS = 16384;
|
|
743
|
-
/** Cap on a request's `outputSchema` (JSON-serialized) — an uncapped schema bloats the prompt + the per-turn
|
|
744
|
-
* validation cost. 32KB comfortably holds a rich nested schema while bounding the abuse surface. */
|
|
745
|
-
export declare const MAX_OUTPUT_SCHEMA_CHARS = 32768;
|
|
746
|
-
/**
|
|
747
|
-
* Validate `body.skills` —— **形**校验 + 一条引擎孪生门。返回错误串(→ 400)或 null。
|
|
748
|
-
*
|
|
749
|
-
* 🔴 **[ref](7.77.0,硬 BREAKING;零别名零双读)**:此前这里有三条本仓自造的拒绝臂,全部退役 ——
|
|
750
|
-
* · `at most 10 skills per request`(条数帽);
|
|
751
|
-
* · `skill.description must be a string of at most 1024 characters`(描述长度帽);
|
|
752
|
-
* · `skill.name must be a non-empty string of at most 64 characters` 里的 **长度**那一半。
|
|
753
|
-
*
|
|
754
|
-
* 退役的判据是**上游两侧都没有同形门**:CC 2.1.259 的技能清单渲染(`cli259.js:23195` 的预算算法)
|
|
755
|
-
* 在超预算时把**描述裁短**、再不够就退成 name-only,**从不**因为条数多或描述长而拒掉一条技能;
|
|
756
|
-
* 它的 `Ir()` 名字校验也只判非空 / 无配对代理 / 无首尾空白 / 无括号逗号控制字符,没有长度帽。
|
|
757
|
-
* 引擎侧同理:唯一整拒的是 1 MiB 的单技能加载门。于是那三条帽是「装了 11 个技能就 400」这种
|
|
758
|
-
* 纯本仓面的伤——收益是零(预算由渲染侧按字节兜),代价是用户装不进自己的技能库。
|
|
759
|
-
*
|
|
760
|
-
* **补偿**(三问的第三问):`settings.skillListingBudgetFraction` / `settings.skillListingMaxDescChars`
|
|
761
|
-
* 两个旋钮直达引擎的渲染预算(per-turn 成本的真属主)。
|
|
762
|
-
* ⚠️ **fraction 是**单向**的**:引擎的预算 = `min(窗口 × fraction, 8 000 字节)`,8 000 是**投递车道的结构
|
|
763
|
-
* 上限**(清单帧与同 turn 的其它附件共用一份完整送达额度)⇒ **调低生效、调高被夹**;调高唯一的用处是让
|
|
764
|
-
* 一个声明窗口小于 200 000 token 的模型把清单预算拿回大窗口的水平。别把这句读成「调用方可以随便加大」。
|
|
765
|
-
* 体积面照旧由**非技能专属**的 8 MiB 请求体上限兜住(`MAX_BODY`),那是一条一直都在的门。
|
|
766
|
-
*
|
|
767
|
-
* 🔴 **server 侧禁裁列表 / 禁截描述**:渲染归引擎(单一属主)。本函数只判「这一条技能的形能不能用」。
|
|
768
|
-
*/
|
|
769
|
-
export declare function validateUserSkills(skills: unknown): string | null;
|
|
738
|
+
/** The TRUSTED end-user principal for an owner-gated / per-tenant request. On a direct-door worker the
|
|
739
|
+
* trusted-header path is OFF (x-agent-principal is client-self-asserted), so identity comes from the crypto-VERIFIED
|
|
740
|
+
* principal JWT (`x-approval-principal-token`, principal-only proof — no cnf.bnd action binding); otherwise the
|
|
741
|
+
* BFF-minted trusted header. undefined when absent/invalid (fail-closed → callers map to 401 / scope "__none__").
|
|
742
|
+
* 🔴 Use this for ANY endpoint that reads or gates PER-TENANT data — NOT `principalFrom` directly, which trusts
|
|
743
|
+
* the self-asserted header on a direct door (/v1/usage + the trace owner-gate
|
|
744
|
+
* had drifted to a bare principalFrom, unlike the leader/images/approvals identity paths). One source of truth
|
|
745
|
+
* so a future per-tenant endpoint can't re-introduce the bypass. The action-BOUND decide/answer paths keep their
|
|
746
|
+
* own verifyDirectDoorProof (cnf.bnd) — this is the identity-only twin. */
|
|
770
747
|
/**
|
|
771
748
|
* Managed-Agents-style HTTP/SSE service surface.
|
|
772
749
|
* GET /health
|
|
@@ -791,73 +768,12 @@ export declare function createHttpServer(rawDeps: ServiceDeps): http.Server & {
|
|
|
791
768
|
/** [ref]:live 回决腿的 PARKED 赎回席(装配层把它接进协调器的晚绑座,见 {@link redeemParkedAsk})。 */
|
|
792
769
|
redeemParkedAsk: ParkedAskRedeem;
|
|
793
770
|
};
|
|
794
|
-
/**
|
|
795
|
-
* guard's inline list had drifted from the handlers and missed `/v1/approvals/:id/decide`, which resumes a run
|
|
796
|
-
* via resumeCheckpoint/store.decide → paid tokens). Keep this in sync when adding a billable POST route. */
|
|
771
|
+
/** SSE: replay durable events after Last-Event-ID, then tail until the run is terminal (or stale). */
|
|
797
772
|
/**
|
|
798
|
-
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
* 本谓词让 `handle()` 对这条 url **跳过**那两道,改由域模块在 `message/send` 分支里施加同样的两道
|
|
804
|
-
* (`routes/a2a-serve.ts` 的 `submitUnavailable`,文案逐字同源)。
|
|
805
|
-
*
|
|
806
|
-
* 🔴 **只豁免那两道,不豁免安全轴**:`isBillableSubmitPath` 本身**不变**(它仍答 true),所以
|
|
807
|
-
* ① 无 service token 的部署上那道 fail-closed 503 照旧罩着这条 url —— 它判的是「这台机能不能收写」,
|
|
808
|
-
* 与方法无关,而且门必须在解析请求体**之前**;
|
|
809
|
-
* ② billable 申明门钉的仍是那只纯谓词(表里 `/v1/a2a` 依旧 billable=true)。
|
|
810
|
-
* 新成员进本表 = 承诺「该域在自己的方法分支里补齐那两道」,漏补就是一条静默旁路;所以本表只该有
|
|
811
|
-
* 「单 URL 多方法」这一种成员,加一条要连同它的域内补门一起过评审。
|
|
812
|
-
*/
|
|
813
|
-
export declare function isMethodDispatchedSubmitPath(url: string): boolean;
|
|
814
|
-
/** 「这台部署配了任何一把 service 凭证吗」—— fail-closed 写门族的真值源。**单一属主**:`handle()` 的
|
|
815
|
-
* 凭证门、[ref] 的 parked 赎回席、以及 [ref] 的 consolidation 阀门启动期告警读同一句(手抄迟早
|
|
816
|
-
* 只改一处,而这条判据决定的是「无凭证部署上写口开不开」)。导出仅为最后一个消费点(main.ts)。 */
|
|
817
|
-
export declare function hasServiceAuth(config: ServiceConfig): boolean;
|
|
818
|
-
export declare function isBillableSubmitPath(url: string): boolean;
|
|
819
|
-
/**
|
|
820
|
-
* [ref]([ref] 件5)—— **改写门**:不烧模型、但在**没有任何 service credential** 的部署形下必须与
|
|
821
|
-
* billable / bake 两族一样 fail-closed 的写门。谓词与 `isBillableSubmitPath` **刻意分开**:这几扇门
|
|
822
|
-
* `billable=false`(零模型工作),塞进那张名单会让它们连带吃 drain 与 model-roster-pending 两道 503 ——
|
|
823
|
-
* 而收编与规则读写在排空期/roster 未落时做完全无害。
|
|
824
|
-
*
|
|
825
|
-
* 判据(两个合取项,缺一不进本表)= 「授权的唯一输入是 principal 头」∧「动作是**持久改写**」:
|
|
826
|
-
* · `POST /v1/adoption` —— operator-only 的一次性部署级动作,把一个 principal 名下**每一行**重写到另一个
|
|
827
|
-
* 身份;授权判据 `explicitOperatorOk(gatedPrincipal(...))`。
|
|
828
|
-
* · `POST /v1/rules/cc-import/*` —— principal lane 的**持久 allow 规则**铸造口;一条持久 allow 规则对后续
|
|
829
|
-
* 同命令的 classify 档 ask 常驻消音(core [ref] 之后仍然如此,只是不再消 mandated 的那些)。
|
|
830
|
-
* · `DELETE /v1/rules` —— 同一个规则店的**撤销**口。方向相反(收紧)但同样是持久改写,而且它多一条
|
|
831
|
-
* operator 超范围域(`?principal=` / body 的 `principal` 让 operator 收回**任一**租户的规则)⇒ 自造一个
|
|
832
|
-
* 列在 `OPERATOR_PRINCIPALS` 里的头,就能把每一位租户的规则一次清空。
|
|
833
|
-
* 无 service token 的部署上 `verifiedPrincipal` 走的是「BFF/gated:头已由上游验过」那一支,而这一形恰恰
|
|
834
|
-
* 是**没有**那个上游 —— 于是自造一个头就能收编别人、替任意租户种下常驻放行、或替他们全删。bake 门当年
|
|
835
|
-
* 补的就是同一句话,`isDestructiveSessionWrite` 从逐条路由白名单改成族判定也是同一句话(那次的措辞逐字是
|
|
836
|
-
* 「a forged principal header alone could **tighten/DoS** a session's tools」——撤销口落的正是 DoS 那一半)。
|
|
837
|
-
*
|
|
838
|
-
* 🔴 **方法感知**(codex 交叉复审 R2-[high],验真后修):撤销走的是 `DELETE`,而本门最初只挂在 `POST` 的
|
|
839
|
-
* 合取里 —— 于是一个自称「持久改写」的谓词把爆炸半径最大的那条动词漏在门外,正是 `isDestructiveSessionWrite`
|
|
840
|
-
* 当年被抓到的同一形。签名因此收方法,与那只谓词逐字同形。
|
|
841
|
-
* 🔴 读面**原则上**不进本表:`GET /v1/adoption/:id` 与 `GET /v1/rules` 各有自己的**属主门**兜底,本门只拦写。
|
|
842
|
-
*
|
|
843
|
-
* 🔴 **第二个合取项的加宽**(codex 交叉复审 [high],[ref] 提货批,验真后修)——判据现在是
|
|
844
|
-
* 「持久改写 **或** 授权唯一输入是 principal 头的**跨租户治理读**」。加宽是为了收进 [ref] v2-c 的两口:
|
|
845
|
-
* · `POST /v1/memory/import` —— 直接落在**原**判据上,而且是本仓最深的那一种持久改写:它把别处铸的
|
|
846
|
-
* 条目 / 挑战 / 污染标记 / 托管链落进本部署的记忆平面。自造一个在册 operator 头 ⇒ 一份**不当调用方自制的
|
|
847
|
-
* 治理史**成为本店的账;而记忆是模型**每次挂载都读**的面,比种一条常驻 allow 规则更深(那条只影响
|
|
848
|
-
* ask 会不会问,这条影响模型相信什么)。
|
|
849
|
-
* · `POST /v1/memory/export` —— 是**读**,按原措辞本不该进。但被点名豁免的那两条读各有属主门兜底,
|
|
850
|
-
* 而本条**没有**:它的授权判据就是 `explicitOperatorOk`,过了就是**全库**——一次调用取走每个 scope 的
|
|
851
|
-
* 条目正文 + 托管链 + 跨会话污染标记 + lineage。把一次全租户记忆外泄留在门外、只为守住「本门只拦写」
|
|
852
|
-
* 这句措辞,是把措辞看得比它要保护的东西更重。加宽后的判据仍然是**闭**的(不是「写门以外都进」):
|
|
853
|
-
* 它要求「授权的唯一输入是那个头」∧「一次调用的爆炸半径跨租户」,`GET /v1/rules` 那种属主门读不满足。
|
|
854
|
-
* 行为面钉:`test/rewrite-door-service-token-gate.test.ts`(六扇门各一正一反 + 逃生口格 + 读面负控)。
|
|
773
|
+
* The differences a concrete log (task_run | image_bake) feeds the ONE resumable SSE reader (P2.8). Everything
|
|
774
|
+
* the reader does — Last-Event-ID/`?from=` resume, the 416 retention boundary, the per-poll concurrent
|
|
775
|
+
* status+events read, the terminal re-fetch (the terminal event lands in the gap before the status flips), the
|
|
776
|
+
* stale fallback, the 15-min cap, the 15s idle heartbeat — is provider-agnostic and lives in `streamSseLog`.
|
|
777
|
+
* 🔴 The task_run provider MUST keep the existing wire bytes EXACTLY (center's relay + 730+ tests depend on it).
|
|
855
778
|
*/
|
|
856
|
-
export declare function isCredentialGatedRewrite(method: string, url: string): boolean;
|
|
857
|
-
/** Stable, low-cardinality route label for metrics/logs (ids collapsed to `:id`).
|
|
858
|
-
* [[ref]] 字面量**先于**模式:此前模式先查,五条精确路由被形状桶吞掉(`/v1/approvals/stream`
|
|
859
|
-
* 落 ":id"、`/v1/images/{bakes,select,register}` 落 ":profile"、`/v1/images/bakes/claim` 落
|
|
860
|
-
* "bakes/:id")——长连接 stream 的 duration 混进 :id 桶正是 fleet/stream 案的同族错桶病。
|
|
861
|
-
* 精确匹配恒比形状匹配更对,序修零反例(billable-route-declaration 门逐样本钉)。 */
|
|
862
|
-
export declare function routeLabel(_method: string, url: string): string;
|
|
863
779
|
//# sourceMappingURL=server.d.ts.map
|