@sema-agent/server 7.10.0 → 7.12.0
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/README.md +1 -1
- package/USAGE.md +56 -0
- package/dist/adoption/plan.d.ts +152 -0
- package/dist/adoption/plan.js +513 -0
- package/dist/adoption/runner.d.ts +54 -0
- package/dist/adoption/runner.js +505 -0
- package/dist/adoption/sql.d.ts +76 -0
- package/dist/adoption/sql.js +106 -0
- package/dist/adoption/wire.d.ts +250 -0
- package/dist/adoption/wire.js +153 -0
- package/dist/approval-card.d.ts +24 -0
- package/dist/approval-card.js +32 -0
- package/dist/auth-keys.d.ts +28 -4
- package/dist/auth-keys.js +60 -15
- package/dist/boot/adoption.d.ts +30 -0
- package/dist/boot/adoption.js +57 -0
- package/dist/boot/coordinators.d.ts +4 -0
- package/dist/boot/coordinators.js +3 -1
- package/dist/boot/parked-revive-gate.d.ts +56 -7
- package/dist/boot/parked-revive-gate.js +177 -8
- package/dist/boot/permission-rules-audit.d.ts +49 -0
- package/dist/boot/permission-rules-audit.js +57 -0
- package/dist/boot/resolve-spec.js +43 -12
- package/dist/boot/runner-deps.d.ts +10 -2
- package/dist/boot/runner-deps.js +12 -1
- package/dist/budget.js +22 -0
- package/dist/config-types.d.ts +24 -1
- package/dist/config.d.ts +28 -2
- package/dist/config.js +348 -75
- package/dist/governance-ask-marks.js +8 -2
- package/dist/http/route-ctx.d.ts +6 -3
- package/dist/http/routes/adoption.d.ts +26 -0
- package/dist/http/routes/adoption.js +120 -0
- package/dist/http/routes/approvals-assistant.js +2 -1
- package/dist/http/routes/capabilities.js +49 -2
- package/dist/http/routes/rules.d.ts +35 -0
- package/dist/http/routes/rules.js +293 -0
- package/dist/http/routes/shared-memory.d.ts +31 -0
- package/dist/http/routes/shared-memory.js +181 -0
- package/dist/http/routes/trace-usage.js +139 -3
- package/dist/http/server.d.ts +23 -3
- package/dist/http/server.js +123 -3
- package/dist/http/wire-types.d.ts +48 -0
- package/dist/main.js +70 -3
- package/dist/observability/fail-open.d.ts +12 -0
- package/dist/observability/fail-open.js +12 -0
- package/dist/observability/metrics.js +2 -1
- package/dist/observability/tool-trace.d.ts +5 -1
- package/dist/observability/tool-trace.js +33 -6
- package/dist/parked-decide.d.ts +13 -3
- package/dist/parked-decide.js +10 -1
- package/dist/plugins/adoption-log-sql.d.ts +191 -0
- package/dist/plugins/adoption-log-sql.js +273 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +13 -0
- package/dist/plugins/checkpoint-store-sql.js +11 -0
- package/dist/plugins/local-checkpoint-store.d.ts +10 -0
- package/dist/plugins/local-checkpoint-store.js +8 -0
- package/dist/plugins/permission-rule-store-file.d.ts +83 -0
- package/dist/plugins/permission-rule-store-file.js +371 -0
- package/dist/plugins/permission-rule-store-sql.d.ts +249 -0
- package/dist/plugins/permission-rule-store-sql.js +828 -0
- package/dist/plugins/pg-pool.js +37 -0
- package/dist/plugins/session-policy-store-sql.d.ts +6 -0
- package/dist/plugins/session-policy-store-sql.js +7 -1
- package/dist/plugins/shared-memory-store-sql.d.ts +223 -0
- package/dist/plugins/shared-memory-store-sql.js +516 -0
- package/dist/plugins/store-backend.d.ts +38 -2
- package/dist/plugins/store-backend.js +69 -6
- package/dist/plugins/tidb-pool.js +47 -0
- package/dist/rules-consent.d.ts +194 -0
- package/dist/rules-consent.js +240 -0
- package/dist/run-local.js +120 -13
- package/dist/runtime-governance.js +9 -3
- package/dist/shared-memory-scope-authorizer.d.ts +29 -0
- package/dist/shared-memory-scope-authorizer.js +17 -0
- package/dist/task-settings.d.ts +44 -0
- package/dist/task-settings.js +57 -1
- package/dist/tool-approval.d.ts +60 -0
- package/dist/tool-approval.js +223 -25
- package/dist/trace/core-keyset-guard.d.ts +15 -4
- package/dist/trace/project.d.ts +20 -2
- package/dist/trace/project.js +25 -4
- package/package.json +3 -3
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { type PersistedAllowRule, type PermissionRuleStore, type PermissionRuleStoreProvider, type PutResult, type QuarantinedRuleAdd, type RuleAdd, type RuleDot, type RuleScope, type RuleSyncFrontier, type RuleTombstone, type RuleApprovalRecord, type RuleApprovalRecordStore, type RuleOwner } from "@sema-agent/core";
|
|
2
|
+
import type { Pool as MySqlPool } from "mysql2/promise";
|
|
3
|
+
import type { PgQueryFn } from "./pg-query.js";
|
|
4
|
+
import { type SqlDriver } from "./sql-driver.js";
|
|
5
|
+
import type { Pool as PgPool } from "pg";
|
|
6
|
+
/** core `permission-rule-store.ts` 的 `PERMISSION_RULE_WRITER` 字面值(逐字)。`writerOf(store)` 读的
|
|
7
|
+
* 就是这把键——它是 core 与 backend 之间**事实上的**协议名,只是没被导出。 */
|
|
8
|
+
export declare const PERMISSION_RULE_WRITER_KEY = "__semaPermissionRuleWriter";
|
|
9
|
+
/** core `RedemptionAuthorization` 的镜像。 */
|
|
10
|
+
export interface RedemptionAuthorizationMirror {
|
|
11
|
+
recordId: string;
|
|
12
|
+
principal?: string;
|
|
13
|
+
owner?: RuleOwner;
|
|
14
|
+
}
|
|
15
|
+
/** core `RuleAddDelta` 的镜像。 */
|
|
16
|
+
export interface RuleAddDeltaMirror {
|
|
17
|
+
kind: "redemption-add";
|
|
18
|
+
rule: string;
|
|
19
|
+
scope: RuleScope;
|
|
20
|
+
tool: PersistedAllowRule["tool"];
|
|
21
|
+
match: PersistedAllowRule["match"];
|
|
22
|
+
command: string;
|
|
23
|
+
add: RuleAdd;
|
|
24
|
+
redemption: RedemptionAuthorizationMirror;
|
|
25
|
+
}
|
|
26
|
+
/** core `RuleDeleteDelta` 的镜像。 */
|
|
27
|
+
export interface RuleDeleteDeltaMirror {
|
|
28
|
+
kind: "tighten-delete";
|
|
29
|
+
tombstone: RuleTombstone;
|
|
30
|
+
}
|
|
31
|
+
/** core `RuleSyncJoinDelta` 的镜像(**本 backend 不实现**,只为判别式完整——见顶注 ②)。 */
|
|
32
|
+
export interface RuleSyncJoinDeltaMirror {
|
|
33
|
+
kind: "sync-join";
|
|
34
|
+
inbound: {
|
|
35
|
+
rules: PersistedAllowRule[];
|
|
36
|
+
tombstones: RuleTombstone[];
|
|
37
|
+
};
|
|
38
|
+
gcFrontier?: RuleSyncFrontier;
|
|
39
|
+
observedVector?: RuleSyncFrontier;
|
|
40
|
+
quarantine?: Array<{
|
|
41
|
+
rule: string;
|
|
42
|
+
scope: RuleScope;
|
|
43
|
+
dots: RuleDot[];
|
|
44
|
+
reason: QuarantinedRuleAdd["reason"];
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
export type RuleWriteDeltaMirror = RuleAddDeltaMirror | RuleDeleteDeltaMirror | RuleSyncJoinDeltaMirror;
|
|
48
|
+
/** core `RawRuleSyncState` 的镜像。 */
|
|
49
|
+
export interface RawRuleSyncStateMirror {
|
|
50
|
+
actor: string;
|
|
51
|
+
counter: number;
|
|
52
|
+
rev: number;
|
|
53
|
+
rules: PersistedAllowRule[];
|
|
54
|
+
tombstones: RuleTombstone[];
|
|
55
|
+
observedVector?: RuleSyncFrontier;
|
|
56
|
+
quarantined?: QuarantinedRuleAdd[];
|
|
57
|
+
}
|
|
58
|
+
/** core `PermissionRuleWriter` 的镜像。 */
|
|
59
|
+
export interface PermissionRuleWriterMirror {
|
|
60
|
+
nextDot(): Promise<RuleDot>;
|
|
61
|
+
apply(delta: RuleWriteDeltaMirror, opts: {
|
|
62
|
+
expectedRev: number;
|
|
63
|
+
}): Promise<PutResult | {
|
|
64
|
+
conflict: true;
|
|
65
|
+
rev: number;
|
|
66
|
+
}>;
|
|
67
|
+
readRaw(): Promise<RawRuleSyncStateMirror>;
|
|
68
|
+
}
|
|
69
|
+
/** core `WritablePermissionRuleStore` 的镜像(属性名 = {@link PERMISSION_RULE_WRITER_KEY})。 */
|
|
70
|
+
export interface WritablePermissionRuleStoreMirror extends PermissionRuleStore {
|
|
71
|
+
readonly __semaPermissionRuleWriter: PermissionRuleWriterMirror;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* core 私有 `writerOf` 的**本地对偶**:一只店的写面,或 `undefined`(该 backend 从引擎侧看是只读的)。
|
|
75
|
+
*
|
|
76
|
+
* 结构检查而不是断言 —— 它同时是本仓消费点(测试/诊断)读写面的**唯一**入口:没有这个函数,每个调用点
|
|
77
|
+
* 都会各写一次 `as unknown as {…}`,那既是三处宽松断言,也是三份会各自漂的形状假设。
|
|
78
|
+
*/
|
|
79
|
+
export declare function writerOfSqlRuleStore(store: PermissionRuleStore): PermissionRuleWriterMirror | undefined;
|
|
80
|
+
export declare const PERMISSION_RULE_TABLE = "permission_rule";
|
|
81
|
+
export declare const PERMISSION_RULE_APPROVAL_TABLE = "permission_rule_approval";
|
|
82
|
+
export declare const PERMISSION_RULE_TICKET_TABLE = "permission_rule_ticket";
|
|
83
|
+
/**
|
|
84
|
+
* MySQL-protocol(TiDB)侧的三条建表语句。真源在本文件(与 PG twin 并排,方言差异一眼可对);
|
|
85
|
+
* `tidb-pool.ts` 的 `SCHEMA_STATEMENTS` 用 `...TIDB_PERMISSION_RULE_STATEMENTS` 展开,于是三张表跟着
|
|
86
|
+
* 中央 `ensureSchema` 在 **named-lock 的那条 conn** 上建(同 `TIDB_APPROVAL_ASK_STATEMENTS` 先例)。
|
|
87
|
+
*
|
|
88
|
+
* 列宽依据(#192 A10 的「每列的值由谁铸、有没有入口上限」口径):
|
|
89
|
+
* · `owner_key` / `record_id` / `ticket_id` / `approval_id` / `payload_hash` / `checksum` → 190:
|
|
90
|
+
* 全是本仓自铸的键类值(sha256 hex 64 / uuid 36 / `sha256:` 前缀 71),190 是全仓键轴的统一宽度。
|
|
91
|
+
* · `principal` → 512:principal 入口上限是 `PRINCIPAL_MAX_LENGTH = 190`(`security.ts`),这里给
|
|
92
|
+
* 名类宽度 512 是**上界宽于入口**的方向(绝不制造静默截断面)。
|
|
93
|
+
* · `actor` → 190:本 backend 自铸的副本身份(`sql-<12 hex>`),按构造 ≤ 20 字符。
|
|
94
|
+
* · 内容列一律 LONGTEXT / TEXT:一只桶的规则集没有硬上限(导入一份大 settings 就能过 64K TEXT 墙)。
|
|
95
|
+
* · 毫秒列一律 `_ms` 后缀;OCC 列一律叫 `rev`(`version` 是形/schema 版本的保留词)。
|
|
96
|
+
*/
|
|
97
|
+
export declare const TIDB_PERMISSION_RULE_STATEMENTS: readonly string[];
|
|
98
|
+
/** {@link TIDB_PERMISSION_RULE_STATEMENTS} 的遍历壳(生产路径走 `tidb-pool.ts` 中央 `ensureSchema`;
|
|
99
|
+
* 本函数留给只需要这三张表的集成测试)。 */
|
|
100
|
+
export declare function ensureTiDBPermissionRuleSchema(pool: MySqlPool): Promise<void>;
|
|
101
|
+
export declare function ensurePgPermissionRuleSchema(q: PgQueryFn): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* 一只桶的**存储键**(纯数据 ⇒ `build*`)。
|
|
104
|
+
*
|
|
105
|
+
* 🔴 为什么 hash 而不是把 principal 直接当主键:①principal 是自由文本身份串,做主键会让**长度**与
|
|
106
|
+
* **排序规则**变成安全面(一个 191 字符的 principal 在 190 宽的列上被静默截断 ⇒ 两个身份共用一只桶,
|
|
107
|
+
* 那是一次跨租户放行);②`local-owner` 那一员**没有** principal,需要一个同域的定长表示。
|
|
108
|
+
* 种别前缀让两族键不可能相撞(`principal:` vs `local-owner`)。
|
|
109
|
+
*/
|
|
110
|
+
export declare function buildRuleOwnerKey(owner: RuleOwner): string;
|
|
111
|
+
/** 内容三列 + 观测向量的完整性指纹(core `ruleStoreChecksum` 同精神;**不含** rev/counter —— 那两样
|
|
112
|
+
* 是元数据轴,`nextDot` 只动 counter 就不该迫使重算内容指纹)。
|
|
113
|
+
*
|
|
114
|
+
* 导出(纯数据 ⇒ `build*`)是为了让**取证测试**能造一条「指纹自洽但语义矛盾」的行 —— 那正是
|
|
115
|
+
* codex round1 [high] 二的形:一条只靠指纹是拦不住的坏行,必须由语义筛拦。 */
|
|
116
|
+
export declare function buildRuleBucketChecksum(body: {
|
|
117
|
+
rules: readonly unknown[];
|
|
118
|
+
tombstones: readonly unknown[];
|
|
119
|
+
quarantined: readonly unknown[];
|
|
120
|
+
observedVector?: RuleSyncFrontier;
|
|
121
|
+
}): string;
|
|
122
|
+
/**
|
|
123
|
+
* SQL 双方言的 {@link PermissionRuleStoreProvider}。
|
|
124
|
+
*
|
|
125
|
+
* `forPrincipal(undefined)` 恒解析成**零规则**店(core 硬条款:未鉴权任务解析到零规则而不是一只共享桶
|
|
126
|
+
* —— 放宽面上的 fail-closed 是「更少的允许」,绝不是「一只共享的」)。
|
|
127
|
+
*/
|
|
128
|
+
export declare class SqlPermissionRuleStoreProvider implements PermissionRuleStoreProvider {
|
|
129
|
+
private readonly db;
|
|
130
|
+
private readonly now;
|
|
131
|
+
constructor(db: SqlDriver, now?: () => number);
|
|
132
|
+
forPrincipal(principal: string | undefined): PermissionRuleStore;
|
|
133
|
+
forLocalOwner(): PermissionRuleStore;
|
|
134
|
+
}
|
|
135
|
+
export declare function createTiDBPermissionRuleStoreProvider(pool: MySqlPool, now?: () => number): SqlPermissionRuleStoreProvider;
|
|
136
|
+
export declare function createPgPermissionRuleStoreProvider(pool: PgPool, now?: () => number): SqlPermissionRuleStoreProvider;
|
|
137
|
+
/**
|
|
138
|
+
* durable 审批记录。CAS **按 rev**,不按 state —— core 的原话:批记录的第二个候选会 redeemed→redeemed,
|
|
139
|
+
* 只比 state 的两次并发重试会**都**认为自己看到了预期状态,各铸一个 dot、各写一次,后者静默覆盖前者的
|
|
140
|
+
* `redeemedDots`。那正是「一次同意变成两个 add、一条删掉的规则复活」的机制。
|
|
141
|
+
*/
|
|
142
|
+
export declare class SqlRuleApprovalRecordStore implements RuleApprovalRecordStore {
|
|
143
|
+
private readonly db;
|
|
144
|
+
private readonly now;
|
|
145
|
+
constructor(db: SqlDriver, now?: () => number);
|
|
146
|
+
private q;
|
|
147
|
+
private enc;
|
|
148
|
+
get(id: string): Promise<RuleApprovalRecord | undefined>;
|
|
149
|
+
create(record: RuleApprovalRecord): Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* 丢弃一条**从未被确认**的记录(codex 交叉复审 round8 [medium],可控半场)。
|
|
152
|
+
*
|
|
153
|
+
* 用处只有一个:`prepareCcImport` 会在**返回预览之前**就把 pending 记录落盘,所以「预览超帽、这次导入
|
|
154
|
+
* 不做了」这条路会留下一条永远没人要的行。`WHERE state = 'pending'` 是硬的 —— 已确认/已兑付的记录是
|
|
155
|
+
* 一次真人同意的**审计事实**,任何路径都不许把它删掉(那条轴上的清理属于保留期策略,不是本方法)。
|
|
156
|
+
* 不是 core `RuleApprovalRecordStore` 的成员(那个接口只有 get/cas/create),故命名上与它区分。
|
|
157
|
+
*/
|
|
158
|
+
discardPendingRecord(recordId: string): Promise<boolean>;
|
|
159
|
+
/** compare-and-set on `rev`(core 硬条款)。`next.rev` 必须是 `expectRev + 1`;不是 ⇒ 响亮拒绝
|
|
160
|
+
* (一个不推进的 CAS 会让两次写互相覆盖而两边都以为自己赢了)。 */
|
|
161
|
+
cas(id: string, expectRev: number, next: RuleApprovalRecord): Promise<boolean>;
|
|
162
|
+
}
|
|
163
|
+
/** 一张已铸的票(呈给调用方的形;`payload` 是 prepare 时刻的候选快照)。 */
|
|
164
|
+
export interface RuleImportTicket {
|
|
165
|
+
ticketId: string;
|
|
166
|
+
approvalId: string;
|
|
167
|
+
payloadHash: string;
|
|
168
|
+
expiresAtMs: number;
|
|
169
|
+
}
|
|
170
|
+
/** 消费结果。**四种拒绝合并成一个 `refused` 形**是刻意的:调用点把它们全部翻成同一个 404,
|
|
171
|
+
* 于是「这张票不存在」「它是别人的」「它过期了」「它已经用过了」在 wire 上不可区分(禁存在性 oracle)。 */
|
|
172
|
+
export type RuleTicketRedeemResult = {
|
|
173
|
+
ok: true;
|
|
174
|
+
approvalId: string;
|
|
175
|
+
payloadHash: string;
|
|
176
|
+
} | {
|
|
177
|
+
ok: false;
|
|
178
|
+
reason: "unknown" | "wrong-principal" | "expired" | "consumed";
|
|
179
|
+
};
|
|
180
|
+
/** prepare 时刻候选集的规范摘要(载荷绑定 F1 ④ 的判据)。纯数据 ⇒ `build*`。 */
|
|
181
|
+
export declare function buildRulePayloadHash(candidates: ReadonlyArray<{
|
|
182
|
+
rule: string;
|
|
183
|
+
scope: RuleScope;
|
|
184
|
+
}>): string;
|
|
185
|
+
export declare class SqlRuleImportTicketStore {
|
|
186
|
+
private readonly db;
|
|
187
|
+
private readonly now;
|
|
188
|
+
constructor(db: SqlDriver, now?: () => number);
|
|
189
|
+
private q;
|
|
190
|
+
mint(input: {
|
|
191
|
+
ticketId: string;
|
|
192
|
+
principal: string;
|
|
193
|
+
approvalId: string;
|
|
194
|
+
candidates: ReadonlyArray<{
|
|
195
|
+
rule: string;
|
|
196
|
+
scope: RuleScope;
|
|
197
|
+
}>;
|
|
198
|
+
ttlMs: number;
|
|
199
|
+
}): Promise<RuleImportTicket>;
|
|
200
|
+
/**
|
|
201
|
+
* **一次性原子认领**(F1 ③)。四个条件全部写在 `WHERE` 里 —— ticket 身份、principal 绑定、未过期、
|
|
202
|
+
* 未认领 —— 于是并发双 redeem 由引擎的行锁裁决,恰一条 `affected === 1`。
|
|
203
|
+
*
|
|
204
|
+
* 🔴 **认领的 UPDATE 是这条方法的最后一次 I/O**(codex 交叉复审 round4 [high],验真后修)。
|
|
205
|
+
* 旧形是「先 UPDATE 认领、再 SELECT 取 approvalId/payloadHash」——那条 SELECT 失败时本方法**抛错**,
|
|
206
|
+
* 而调用方(`redeemImport`)此时还没进它的恢复 `try`,于是**没有任何人去放回认领**:票被永久烧掉,
|
|
207
|
+
* 重试收到不可重试的 404,人的确认凭空消失。改法不是加一层 catch,而是**把那次读挪到认领之前**:
|
|
208
|
+
* `approval_id` / `payload_hash` 自铸票起就是**不可变**列,先读与后读读到的是同一份字节。
|
|
209
|
+
*
|
|
210
|
+
* 🔴 **这仍然不是 read-then-write**(禁令的语义没有松动):**裁决**依旧只由那条条件 `UPDATE` 的
|
|
211
|
+
* `WHERE` 做出 —— 预读的三条否定项只用来**短路 + 归因**(把拒绝分成 unknown/wrong-principal/
|
|
212
|
+
* expired/consumed 四类给服务端日志;wire 面把四类折成同一个 404)。预读说「可以」而 UPDATE 命中零行,
|
|
213
|
+
* 只可能是我们在这两跳之间输给了一个并发认领者 —— 如实报 `consumed`,而不是把这次失败当成成功。
|
|
214
|
+
*/
|
|
215
|
+
consume(ticketId: string, principal: string): Promise<RuleTicketRedeemResult>;
|
|
216
|
+
/**
|
|
217
|
+
* **认领的释放**(codex 交叉复审 round1 [high] 一,验真后修)。
|
|
218
|
+
*
|
|
219
|
+
* `consume` 是一次**认领**(claim),不是「这件事已经做完了」。认领之后还有三步会失败:读记录、
|
|
220
|
+
* 载荷比对、confirm+批量兑付。旧形把认领当终局 ⇒ 一次数据库抖动就让票**永久**烧掉,而调用方拿到的
|
|
221
|
+
* 是与「票不存在」同形的 404:重试无门、最终状态对客户端不可判。
|
|
222
|
+
*
|
|
223
|
+
* ⇒ 认领之后**只有裁定性拒绝**才留着消费位(载荷被篡改、记录不存在 —— 重试不改判);**不确定/瞬时**
|
|
224
|
+
* 的失败(store 抛错、CAS 冲突)把认领**放回去**,让属主重试。放回去不会打开双兑付的门:同一时刻
|
|
225
|
+
* 只有一个持有者(认领本身仍是单条条件 UPDATE),而兑付腿(`redeemRuleBatch`)按 core 的设计是
|
|
226
|
+
* **幂等**的(记录里存着每个候选已铸的 dot,重放只会重放同一个 dot)。
|
|
227
|
+
*
|
|
228
|
+
* 残留(如实登记,不假称已解):认领与释放之间**硬崩**会把票留在已认领态 —— 它随 TTL 自然消失,
|
|
229
|
+
* 期间属主可以重新走 prepare 拿一张新票(导入是幂等的:同一条规则再兑付只是同一个 dot 的重放)。
|
|
230
|
+
* 要彻底消灭它需要一条带租约到期的认领状态机,属协议改动,列为后续件。
|
|
231
|
+
*/
|
|
232
|
+
release(ticketId: string, principal: string, mustRemainValidMs?: number): Promise<boolean>;
|
|
233
|
+
private readRow;
|
|
234
|
+
}
|
|
235
|
+
/** 三个 SQL 店的一次性装配束(one driver, three faces)。 */
|
|
236
|
+
export interface PermissionRuleStores {
|
|
237
|
+
provider: SqlPermissionRuleStoreProvider;
|
|
238
|
+
approvals: SqlRuleApprovalRecordStore;
|
|
239
|
+
tickets: SqlRuleImportTicketStore;
|
|
240
|
+
/** #203 §3 —— boot 期休眠行审计的**窄读口**:库里已有几只桶(`permission_rule` 一行一桶)。
|
|
241
|
+
*
|
|
242
|
+
* 🔴 为什么数**桶**而不是数**规则**:数规则要把每一行的 `rules_json` 都读回来再解析(一只桶的规则集
|
|
243
|
+
* 没有硬上限,顶注 §列宽依据已说明它是 LONGTEXT),那是一次无界的 boot 期扫描 —— 为一条诊断行付这个
|
|
244
|
+
* 代价不划算。桶数回答的正是审计要问的那个问题(「这台部署上有没有既有的规则状态」),而且是一次
|
|
245
|
+
* 索引级 `COUNT(*)`。消费点(`boot/permission-rules-audit.ts`)的文案因此逐字说的是 bucket,不是 rule。 */
|
|
246
|
+
countBuckets(): Promise<number>;
|
|
247
|
+
}
|
|
248
|
+
export declare function createSqlPermissionRuleStores(db: SqlDriver, now?: () => number): PermissionRuleStores;
|
|
249
|
+
//# sourceMappingURL=permission-rule-store-sql.d.ts.map
|