@sema-agent/server 7.144.0 → 7.145.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/MIGRATION.md +129 -0
- package/README.md +3 -0
- package/README.zh-CN.md +1 -0
- package/USAGE.md +16 -8
- package/dist/audit.d.ts +2 -21
- package/dist/audit.js +0 -9
- package/dist/boot/session-faces.d.ts +1 -1
- package/dist/boot/session-faces.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +1 -1
- package/dist/boot/stage-10-http-server.d.ts +1 -1
- package/dist/boot/stage-10-http-server.js +2 -2
- package/dist/config-d-migration.d.ts +3 -2
- package/dist/fleet/fleet-bus.d.ts +13 -3
- package/dist/fleet/fleet-bus.js +17 -3
- package/dist/http/admission.js +2 -1
- package/dist/http/checkpoint-ctx.d.ts +1 -0
- package/dist/http/checkpoint-ctx.js +1 -0
- package/dist/http/durable-run-leg.js +7 -6
- package/dist/http/resume-legs.js +5 -3
- package/dist/http/route-ctx.d.ts +15 -0
- package/dist/http/routes/approvals-assistant.d.ts +20 -1
- package/dist/http/routes/approvals-assistant.js +27 -6
- package/dist/http/routes/rules.d.ts +1 -1
- package/dist/http/routes/rules.js +5 -2
- package/dist/http/routes/session-sync.js +12 -0
- package/dist/http/routes/tasks.js +12 -9
- package/dist/http/run-meta.d.ts +14 -7
- package/dist/http/run-meta.js +5 -2
- package/dist/http/server.d.ts +13 -5
- package/dist/http/server.js +3 -0
- package/dist/http/submit-ctx.d.ts +12 -0
- package/dist/http/submit-ctx.js +23 -0
- package/dist/observability/fail-open.d.ts +15 -3
- package/dist/observability/fail-open.js +15 -3
- package/dist/plugins/approval-ask-store-file.d.ts +16 -2
- package/dist/plugins/approval-ask-store-file.js +21 -1
- package/dist/plugins/approval-ask-store-memory.d.ts +8 -2
- package/dist/plugins/approval-ask-store-memory.js +11 -8
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +29 -11
- package/dist/plugins/checkpoint-store-sql.js +38 -16
- package/dist/plugins/file-run-store.d.ts +13 -1
- package/dist/plugins/file-run-store.js +11 -1
- package/dist/plugins/local-checkpoint-store.d.ts +14 -3
- package/dist/plugins/local-checkpoint-store.js +23 -5
- package/dist/plugins/local-session-store.d.ts +52 -16
- package/dist/plugins/local-session-store.js +47 -14
- package/dist/plugins/memory-run-store.d.ts +2 -0
- package/dist/plugins/memory-run-store.js +6 -0
- package/dist/plugins/one-time-migrations.js +2 -2
- package/dist/plugins/run-store-sql.d.ts +4 -0
- package/dist/plugins/run-store-sql.js +3 -0
- package/dist/plugins/session-store.d.ts +1 -1
- package/dist/prompt-screen.d.ts +21 -0
- package/dist/prompt-screen.js +8 -0
- package/dist/rules-consent.d.ts +63 -51
- package/dist/rules-consent.js +6 -10
- package/dist/run-acceptance.d.ts +40 -10
- package/dist/run-acceptance.js +38 -5
- package/dist/runs.js +1 -1
- package/dist/security.d.ts +10 -3
- package/dist/session-agent.d.ts +39 -0
- package/dist/session-agent.js +16 -0
- package/dist/session-error-wire.d.ts +4 -4
- package/dist/trace/model-segment.d.ts +3 -2
- package/dist/trace/model-segment.js +16 -8
- package/dist/trace/redact.d.ts +66 -2
- package/dist/trace/redact.js +220 -101
- package/dist/trace/self-minted-wire.d.ts +73 -1
- package/dist/trace/self-minted-wire.js +27 -0
- package/package.json +2 -2
- package/wire-changes/server@7.145.0.json +146 -0
package/dist/trace/redact.js
CHANGED
|
@@ -73,7 +73,7 @@ function collectSpelledCuts(s) {
|
|
|
73
73
|
let present = 0;
|
|
74
74
|
let i = s.indexOf("\\");
|
|
75
75
|
if (i < 0)
|
|
76
|
-
return { cuts, present };
|
|
76
|
+
return { cuts, present, open: -1 };
|
|
77
77
|
const n = s.length;
|
|
78
78
|
const read = { end: 0 };
|
|
79
79
|
while (i >= 0) {
|
|
@@ -81,6 +81,8 @@ function collectSpelledCuts(s) {
|
|
|
81
81
|
while (body < n && s.charCodeAt(body) === CH_BACKSLASH)
|
|
82
82
|
body += 1;
|
|
83
83
|
const cp = readSpelledCodePoint(s, body, read);
|
|
84
|
+
if (cp === ESCAPE_TRUNCATED)
|
|
85
|
+
return { cuts, present, open: i };
|
|
84
86
|
const cls = cp < 0 ? 0 : isFormatCodePoint(cp) ? SPELLED_FORMAT : cp < 0x10000 && INVISIBLE_UNIT_CLASS[cp] === 1 ? SPELLED_CONTROL : 0;
|
|
85
87
|
if (cls !== 0) {
|
|
86
88
|
cuts.push(i, read.end, cls);
|
|
@@ -89,7 +91,7 @@ function collectSpelledCuts(s) {
|
|
|
89
91
|
}
|
|
90
92
|
i = s.indexOf("\\", body);
|
|
91
93
|
}
|
|
92
|
-
return { cuts, present };
|
|
94
|
+
return { cuts, present, open: -1 };
|
|
93
95
|
}
|
|
94
96
|
function deleteInvisibleCharacters(s, all, mask) {
|
|
95
97
|
const atList = [];
|
|
@@ -127,9 +129,12 @@ function viewIndexInInput(fold, v) {
|
|
|
127
129
|
}
|
|
128
130
|
return lo === 0 ? v : v + fold.cum[lo - 1];
|
|
129
131
|
}
|
|
132
|
+
const ESCAPE_TRUNCATED = -2;
|
|
130
133
|
function readHexRun(s, at, count) {
|
|
131
134
|
let v = 0;
|
|
132
135
|
for (let k = at; k < at + count; k++) {
|
|
136
|
+
if (k >= s.length)
|
|
137
|
+
return ESCAPE_TRUNCATED;
|
|
133
138
|
const d = hexDigitValue(s.charCodeAt(k));
|
|
134
139
|
if (d < 0)
|
|
135
140
|
return -1;
|
|
@@ -138,6 +143,8 @@ function readHexRun(s, at, count) {
|
|
|
138
143
|
return v;
|
|
139
144
|
}
|
|
140
145
|
function readEscapeElement(s, at, out) {
|
|
146
|
+
if (at >= s.length)
|
|
147
|
+
return ESCAPE_TRUNCATED;
|
|
141
148
|
const kind = s.charCodeAt(at);
|
|
142
149
|
if (kind === CH_x) {
|
|
143
150
|
out.end = at + 3;
|
|
@@ -145,6 +152,8 @@ function readEscapeElement(s, at, out) {
|
|
|
145
152
|
}
|
|
146
153
|
if (kind !== CH_u)
|
|
147
154
|
return -1;
|
|
155
|
+
if (at + 1 >= s.length)
|
|
156
|
+
return ESCAPE_TRUNCATED;
|
|
148
157
|
if (s.charCodeAt(at + 1) === CH_LBRACE) {
|
|
149
158
|
let v = 0;
|
|
150
159
|
let k = at + 2;
|
|
@@ -156,6 +165,8 @@ function readEscapeElement(s, at, out) {
|
|
|
156
165
|
if (v > 0x10ffff)
|
|
157
166
|
return -1;
|
|
158
167
|
}
|
|
168
|
+
if (k >= s.length)
|
|
169
|
+
return ESCAPE_TRUNCATED;
|
|
159
170
|
if (k === at + 2 || s.charCodeAt(k) !== CH_RBRACE)
|
|
160
171
|
return -1;
|
|
161
172
|
out.end = k + 1;
|
|
@@ -171,13 +182,20 @@ function readSpelledCodePoint(s, at, out) {
|
|
|
171
182
|
if (v > 0xdbff)
|
|
172
183
|
return -1;
|
|
173
184
|
let k = out.end;
|
|
185
|
+
if (k >= s.length)
|
|
186
|
+
return ESCAPE_TRUNCATED;
|
|
174
187
|
if (s.charCodeAt(k) !== CH_BACKSLASH)
|
|
175
188
|
return -1;
|
|
176
189
|
while (s.charCodeAt(k) === CH_BACKSLASH)
|
|
177
190
|
k += 1;
|
|
178
191
|
const lo = readEscapeElement(s, k, out);
|
|
192
|
+
if (lo === ESCAPE_TRUNCATED)
|
|
193
|
+
return ESCAPE_TRUNCATED;
|
|
179
194
|
return lo >= 0xdc00 && lo <= 0xdfff ? 0x10000 + ((v - 0xd800) << 10) + (lo - 0xdc00) : -1;
|
|
180
195
|
}
|
|
196
|
+
function isEscapeBodyUnit(c) {
|
|
197
|
+
return c === CH_BACKSLASH || c === CH_u || c === CH_x || c === CH_LBRACE || c === CH_RBRACE || hexDigitValue(c) >= 0;
|
|
198
|
+
}
|
|
181
199
|
const FORMAT_CODEPOINT_TABLE = (() => {
|
|
182
200
|
const table = new Uint8Array(0x10000);
|
|
183
201
|
const units = [];
|
|
@@ -463,9 +481,13 @@ let ssh2ScanBytes = 0;
|
|
|
463
481
|
let mappedUnits = 0;
|
|
464
482
|
let coverageVisits = 0;
|
|
465
483
|
let rowVisits = 0;
|
|
484
|
+
let scannedUnits = 0;
|
|
485
|
+
let windowAdvances = 0;
|
|
486
|
+
let windowRefusals = 0;
|
|
487
|
+
let windowEvaluations = 0;
|
|
466
488
|
let readings = 0;
|
|
467
489
|
export function armPoolBudgetForTest() {
|
|
468
|
-
return { spanCount: poolSpanCount, coveredPositions, headScreenHits, fullYCalls, armCount: poolArmCount, boundaryArmCount: poolBoundaryArmCount, forensicLevels, forensicRuns, forensicSkips, urlSegmentRuns, urlSegmentReplays, ssh2ScanBytes, mappedUnits, readings, coverageVisits, rowVisits };
|
|
490
|
+
return { spanCount: poolSpanCount, coveredPositions, headScreenHits, fullYCalls, armCount: poolArmCount, boundaryArmCount: poolBoundaryArmCount, forensicLevels, forensicRuns, forensicSkips, urlSegmentRuns, urlSegmentReplays, ssh2ScanBytes, mappedUnits, readings, coverageVisits, rowVisits, scannedUnits, windowAdvances, windowRefusals, windowEvaluations };
|
|
469
491
|
}
|
|
470
492
|
export function resetArmPoolBudgetForTest() {
|
|
471
493
|
poolSpanCount = 0;
|
|
@@ -482,6 +504,10 @@ export function resetArmPoolBudgetForTest() {
|
|
|
482
504
|
readings = 0;
|
|
483
505
|
coverageVisits = 0;
|
|
484
506
|
rowVisits = 0;
|
|
507
|
+
scannedUnits = 0;
|
|
508
|
+
windowAdvances = 0;
|
|
509
|
+
windowRefusals = 0;
|
|
510
|
+
windowEvaluations = 0;
|
|
485
511
|
}
|
|
486
512
|
const unitBit = (t, c) => (t[c >>> 5] >>> (c & 31)) & 1;
|
|
487
513
|
let codeUnitDomain;
|
|
@@ -3169,7 +3195,7 @@ function anchorHeadAt(scan, text, op, json) {
|
|
|
3169
3195
|
if (i < 0)
|
|
3170
3196
|
return undefined;
|
|
3171
3197
|
const c = text.charCodeAt(i);
|
|
3172
|
-
if (c
|
|
3198
|
+
if (isInlineSpaceUnit(c)) {
|
|
3173
3199
|
i -= 1;
|
|
3174
3200
|
spacedLeft = true;
|
|
3175
3201
|
anchoredScanUnits += 1;
|
|
@@ -3237,7 +3263,7 @@ function anchorHeadAt(scan, text, op, json) {
|
|
|
3237
3263
|
let listSep = 0;
|
|
3238
3264
|
if (!afterEscape) {
|
|
3239
3265
|
let k = before;
|
|
3240
|
-
while (k >= 0 && (text.charCodeAt(k)
|
|
3266
|
+
while (k >= 0 && isInlineSpaceUnit(text.charCodeAt(k)))
|
|
3241
3267
|
k -= 1;
|
|
3242
3268
|
anchoredScanUnits += before - k;
|
|
3243
3269
|
const left = k >= 0 ? text.charCodeAt(k) : 0;
|
|
@@ -3695,6 +3721,7 @@ function collectPpkContainerSpans(scan, text, eat, span, isHead) {
|
|
|
3695
3721
|
if (last >= 0 && isOpenHead(last) && !lineHeld(scan, last, text.length, readingKey(fam, last)))
|
|
3696
3722
|
span(last, text.length, last, NOT_CLOSED, true);
|
|
3697
3723
|
}
|
|
3724
|
+
const NO_GAP = (_unit) => false;
|
|
3698
3725
|
const armPool = (() => {
|
|
3699
3726
|
const spanRepl = (token) => {
|
|
3700
3727
|
const body = token.startsWith("$1") ? token.slice(2) : token;
|
|
@@ -3739,9 +3766,10 @@ const armPool = (() => {
|
|
|
3739
3766
|
headFirst: boundary === undefined ? undefined : headFirst,
|
|
3740
3767
|
family: "prose",
|
|
3741
3768
|
reach: regexDecisionReach(re, LEXICAL_KEYWORD_ARMS.has(re)),
|
|
3769
|
+
prior: { kind: "bounded", gap: keywordTail === undefined ? NO_GAP : (c) => keywordTail.isSeparator(String.fromCharCode(c)) },
|
|
3742
3770
|
};
|
|
3743
3771
|
};
|
|
3744
|
-
const scannerMember = (token, order, arm, reach, family) => {
|
|
3772
|
+
const scannerMember = (token, order, arm, reach, family, prior) => {
|
|
3745
3773
|
const repl = spanRepl(token);
|
|
3746
3774
|
const rank = ARM_RANK.structural;
|
|
3747
3775
|
return {
|
|
@@ -3756,9 +3784,10 @@ const armPool = (() => {
|
|
|
3756
3784
|
headFirst: undefined,
|
|
3757
3785
|
family,
|
|
3758
3786
|
reach,
|
|
3787
|
+
prior,
|
|
3759
3788
|
};
|
|
3760
3789
|
};
|
|
3761
|
-
const forensicMember = (token, order, arm, reach, family, rank = ARM_RANK.structural, lexical = false) => {
|
|
3790
|
+
const forensicMember = (token, order, arm, reach, family, prior, rank = ARM_RANK.structural, lexical = false) => {
|
|
3762
3791
|
const repl = spanRepl(token);
|
|
3763
3792
|
return {
|
|
3764
3793
|
token,
|
|
@@ -3773,26 +3802,27 @@ const armPool = (() => {
|
|
|
3773
3802
|
family,
|
|
3774
3803
|
repl,
|
|
3775
3804
|
reach,
|
|
3805
|
+
prior,
|
|
3776
3806
|
};
|
|
3777
3807
|
};
|
|
3778
3808
|
const structuralScannerMember = (row, order) => {
|
|
3779
3809
|
if (row === PEM_FENCE_PATTERN)
|
|
3780
|
-
return forensicMember(row[1], order, (scan, text, _json, _eat, span, isHead) => collectPemFenceSpans(scan, text, span, isHead), PEM_FENCE_OPEN.length, "pem-armor");
|
|
3810
|
+
return forensicMember(row[1], order, (scan, text, _json, _eat, span, isHead) => collectPemFenceSpans(scan, text, span, isHead), PEM_FENCE_OPEN.length, "pem-armor", { kind: "anchored", anchors: [PEM_FENCE_OPEN, PEM_END_OPEN] });
|
|
3781
3811
|
if (row === SSH2_FENCE_PATTERN)
|
|
3782
|
-
return forensicMember(row[1], order, (scan, text, json, _eat, span, isHead) => collectSsh2FenceSpans(scan, text, json, span, isHead), SSH2_FENCE_OPEN.length, "ssh2-armor");
|
|
3812
|
+
return forensicMember(row[1], order, (scan, text, json, _eat, span, isHead) => collectSsh2FenceSpans(scan, text, json, span, isHead), SSH2_FENCE_OPEN.length, "ssh2-armor", { kind: "anchored", anchors: [SSH2_FENCE_OPEN, SSH2_FENCE_CLOSE] });
|
|
3783
3813
|
if (row === URL_CREDENTIAL_PATTERN)
|
|
3784
|
-
return forensicMember(row[1], order, (scan, text, json, _eat, span, isHead) => collectUrlCredentialSpans(scan, text, json, span, isHead), "://".length, "url");
|
|
3814
|
+
return forensicMember(row[1], order, (scan, text, json, _eat, span, isHead) => collectUrlCredentialSpans(scan, text, json, span, isHead), "://".length, "url", { kind: "bounded", gap: NO_GAP });
|
|
3785
3815
|
if (row === JSON_SECRET_FIELD_PATTERN)
|
|
3786
|
-
return scannerMember(row[1], order, (text, _json, _eat, span, isHead) => collectJsonSecretFieldSpans(text, span, isHead), JSON_FIELD_BACK, "json-field");
|
|
3816
|
+
return scannerMember(row[1], order, (text, _json, _eat, span, isHead) => collectJsonSecretFieldSpans(text, span, isHead), JSON_FIELD_BACK, "json-field", { kind: "bounded", gap: isRegexSpace });
|
|
3787
3817
|
throw new Error(`redact: structural row /${row[0].source}/ has no hand-written scanner — structural grammars are declared as regexes but never executed as one (S-102 / S-265)`);
|
|
3788
3818
|
};
|
|
3789
3819
|
const members = [];
|
|
3790
3820
|
for (const row of STRUCTURAL_SECRET_PATTERNS)
|
|
3791
3821
|
members.push(structuralScannerMember(row, members.length));
|
|
3792
|
-
members.push(forensicMember(PPK_CONTAINER_TOKEN, members.length, (scan, text, _json, eat, span, isHead) => collectPpkContainerSpans(scan, text, eat, span, isHead), PPK_FILE_HEAD.length, "putty-ppk"));
|
|
3793
|
-
members.push(forensicMember(PEM_FRAGMENT_TOKEN, members.length, (scan, text, json, _eat, span, isHead) => collectPemFragmentSpans(scan, text, json, span, isHead), PEM_FENCE_OPEN.length, "pem-armor"));
|
|
3794
|
-
members.push(forensicMember(HEADLESS_PPK_TOKEN, members.length, (scan, text, _json, _eat, span, isHead) => collectHeadlessPpkSpans(scan, text, span, isHead), PPK_LINES_FIELD.length, "putty-ppk"));
|
|
3795
|
-
members.push(forensicMember(ANCHORED_VALUE_TOKEN, members.length, (scan, text, json, _eat, span, isHead) => collectAnchoredValueSpans(scan, text, json, span, isHead), Math.max(BEARER_VALUE_MIN, ABSENT_OR_BOOLEAN_MAX + 1, STRONG_AUTH_SCHEME_MAX + 1), "anchor", ARM_RANK.keyword, true));
|
|
3822
|
+
members.push(forensicMember(PPK_CONTAINER_TOKEN, members.length, (scan, text, _json, eat, span, isHead) => collectPpkContainerSpans(scan, text, eat, span, isHead), PPK_FILE_HEAD.length, "putty-ppk", { kind: "anchored", anchors: [PPK_FILE_HEAD] }));
|
|
3823
|
+
members.push(forensicMember(PEM_FRAGMENT_TOKEN, members.length, (scan, text, json, _eat, span, isHead) => collectPemFragmentSpans(scan, text, json, span, isHead), PEM_FENCE_OPEN.length, "pem-armor", { kind: "anchored", anchors: [PEM_FENCE_OPEN, PEM_END_OPEN] }));
|
|
3824
|
+
members.push(forensicMember(HEADLESS_PPK_TOKEN, members.length, (scan, text, _json, _eat, span, isHead) => collectHeadlessPpkSpans(scan, text, span, isHead), PPK_LINES_FIELD.length, "putty-ppk", { kind: "anchored", anchors: [PPK_LINES_FIELD] }));
|
|
3825
|
+
members.push(forensicMember(ANCHORED_VALUE_TOKEN, members.length, (scan, text, json, _eat, span, isHead) => collectAnchoredValueSpans(scan, text, json, span, isHead), Math.max(BEARER_VALUE_MIN, ABSENT_OR_BOOLEAN_MAX + 1, STRONG_AUTH_SCHEME_MAX + 1), "anchor", { kind: "bounded", gap: (c) => isInlineSpaceUnit(c) || isSchemeDelimiterCode(c) }, ARM_RANK.keyword, true));
|
|
3796
3826
|
for (const row of KEYWORD_SECRET_PATTERNS)
|
|
3797
3827
|
members.push(regexMember(row, ARM_RANK.keyword, members.length));
|
|
3798
3828
|
for (const row of SHAPE_SECRET_PATTERNS)
|
|
@@ -3963,7 +3993,7 @@ const armPool = (() => {
|
|
|
3963
3993
|
}
|
|
3964
3994
|
return { hits: [...byArmedToken.values()].map(({ token, arm, count }) => ({ label: labelOfToken(token), count, arm })), kept: stamped };
|
|
3965
3995
|
};
|
|
3966
|
-
return Object.assign(run, { reaches, pendingTailUnits: Math.max(...reaches.map((r) => r.reach)) });
|
|
3996
|
+
return Object.assign(run, { reaches, pendingTailUnits: Math.max(...reaches.map((r) => r.reach)), priors: members.map((m) => m.prior) });
|
|
3967
3997
|
})();
|
|
3968
3998
|
let onRedaction;
|
|
3969
3999
|
export function setRedactionObserver(fn) {
|
|
@@ -3996,70 +4026,6 @@ function invisibleClassesOf(layout) {
|
|
|
3996
4026
|
}
|
|
3997
4027
|
}
|
|
3998
4028
|
}
|
|
3999
|
-
function trailingPartialEscapeStart(s) {
|
|
4000
|
-
const n = s.length;
|
|
4001
|
-
const runStart = (end) => {
|
|
4002
|
-
let k = end;
|
|
4003
|
-
while (k > 0 && s.charCodeAt(k - 1) === CH_BACKSLASH)
|
|
4004
|
-
k -= 1;
|
|
4005
|
-
return k;
|
|
4006
|
-
};
|
|
4007
|
-
const highSurrogateEscapeStartBefore = (end) => {
|
|
4008
|
-
let j = end;
|
|
4009
|
-
let value = -1;
|
|
4010
|
-
let bodyStart = -1;
|
|
4011
|
-
if (j >= 1 && s.charCodeAt(j - 1) === CH_RBRACE) {
|
|
4012
|
-
let k = j - 1;
|
|
4013
|
-
while (k > 0 && hexDigitValue(s.charCodeAt(k - 1)) >= 0)
|
|
4014
|
-
k -= 1;
|
|
4015
|
-
if (k >= 2 && s.charCodeAt(k - 1) === CH_LBRACE && s.charCodeAt(k - 2) === CH_u && j - 1 - k >= 1) {
|
|
4016
|
-
value = readHexRunValue(s, k, j - 1);
|
|
4017
|
-
bodyStart = k - 2;
|
|
4018
|
-
}
|
|
4019
|
-
}
|
|
4020
|
-
else if (j >= 5 && s.charCodeAt(j - 5) === CH_u) {
|
|
4021
|
-
value = readHexRun(s, j - 4, 4);
|
|
4022
|
-
bodyStart = j - 5;
|
|
4023
|
-
}
|
|
4024
|
-
if (value < 0xd800 || value > 0xdbff)
|
|
4025
|
-
return -1;
|
|
4026
|
-
const k = runStart(bodyStart);
|
|
4027
|
-
return k < bodyStart ? k : -1;
|
|
4028
|
-
};
|
|
4029
|
-
let j = n;
|
|
4030
|
-
while (j > 0 && hexDigitValue(s.charCodeAt(j - 1)) >= 0)
|
|
4031
|
-
j -= 1;
|
|
4032
|
-
const hexRun = n - j;
|
|
4033
|
-
let element = -1;
|
|
4034
|
-
if (j >= 2 && s.charCodeAt(j - 1) === CH_LBRACE && s.charCodeAt(j - 2) === CH_u)
|
|
4035
|
-
element = j - 2;
|
|
4036
|
-
else if (j >= 1 && s.charCodeAt(j - 1) === CH_u && hexRun <= 3)
|
|
4037
|
-
element = j - 1;
|
|
4038
|
-
else if (j >= 1 && s.charCodeAt(j - 1) === CH_x && hexRun <= 1)
|
|
4039
|
-
element = j - 1;
|
|
4040
|
-
else if (hexRun === 0 && n >= 1 && s.charCodeAt(n - 1) === CH_BACKSLASH)
|
|
4041
|
-
element = n;
|
|
4042
|
-
if (element >= 0) {
|
|
4043
|
-
const k = runStart(element);
|
|
4044
|
-
if (k >= element)
|
|
4045
|
-
return -1;
|
|
4046
|
-
const high = highSurrogateEscapeStartBefore(k);
|
|
4047
|
-
return high >= 0 ? high : k;
|
|
4048
|
-
}
|
|
4049
|
-
return highSurrogateEscapeStartBefore(n);
|
|
4050
|
-
}
|
|
4051
|
-
function readHexRunValue(s, from, to) {
|
|
4052
|
-
let v = 0;
|
|
4053
|
-
for (let k = from; k < to; k++) {
|
|
4054
|
-
const d = hexDigitValue(s.charCodeAt(k));
|
|
4055
|
-
if (d < 0)
|
|
4056
|
-
return -1;
|
|
4057
|
-
v = v * 16 + d;
|
|
4058
|
-
if (v > 0x10ffff)
|
|
4059
|
-
return -1;
|
|
4060
|
-
}
|
|
4061
|
-
return v;
|
|
4062
|
-
}
|
|
4063
4029
|
function shortestReading(text, layout) {
|
|
4064
4030
|
const r = readShortest(text, layout);
|
|
4065
4031
|
return { visible: r.visible, partial: r.partial };
|
|
@@ -4068,8 +4034,8 @@ function readShortest(text, layout) {
|
|
|
4068
4034
|
const raw = collectRawControlCuts(text, invisibleClassesOf(layout));
|
|
4069
4035
|
const rfold = deleteInvisibleCharacters(text, raw, raw.present);
|
|
4070
4036
|
const normalized = normalizeForRedaction(rfold.text);
|
|
4071
|
-
const open = trailingPartialEscapeStart(normalized);
|
|
4072
4037
|
const spelled = collectSpelledCuts(normalized);
|
|
4038
|
+
const open = spelled.open;
|
|
4073
4039
|
const sfold = deleteInvisibleCharacters(normalized, spelled, spelled.present);
|
|
4074
4040
|
const layers = [{ fold: sfold }, { input: rfold.text, view: normalized }, { fold: rfold }];
|
|
4075
4041
|
return open < 0 ? { visible: sfold.text.length, partial: false, layers } : { visible: sfold.text.length - (normalized.length - open), partial: true, layers };
|
|
@@ -4095,6 +4061,7 @@ export function readingHeadEnd(text, layout, units, from = 0) {
|
|
|
4095
4061
|
return text.length;
|
|
4096
4062
|
}
|
|
4097
4063
|
function runRedaction(text, observe, json, wantHits, scope, layout, extent, observeFrom = 0) {
|
|
4064
|
+
scannedUnits += text.length;
|
|
4098
4065
|
const wantCount = wantHits || (onRedaction !== undefined && observe);
|
|
4099
4066
|
const eat = observe ? { from: -1, len: 0, capFrom: -1, capLen: 0 } : undefined;
|
|
4100
4067
|
let spans = [];
|
|
@@ -4225,67 +4192,219 @@ function renderRange(text, spans, from, until) {
|
|
|
4225
4192
|
}
|
|
4226
4193
|
const STREAM_RESCAN_MIN = 64;
|
|
4227
4194
|
const streamRescanStep = (n) => Math.max(STREAM_RESCAN_MIN, n >>> 5);
|
|
4195
|
+
const STREAM_WINDOW_HORIZON = 2;
|
|
4196
|
+
const STREAM_WINDOW_MIN = 2048;
|
|
4197
|
+
function deriveStreamWindowAlphabets(priors) {
|
|
4198
|
+
const blank = new Uint8Array(0x10000);
|
|
4199
|
+
const gaps = new Set();
|
|
4200
|
+
const containerDelimiters = [];
|
|
4201
|
+
for (const prior of priors) {
|
|
4202
|
+
switch (prior.kind) {
|
|
4203
|
+
case "bounded":
|
|
4204
|
+
if (prior.gap !== NO_GAP)
|
|
4205
|
+
gaps.add(prior.gap);
|
|
4206
|
+
break;
|
|
4207
|
+
case "anchored":
|
|
4208
|
+
if (prior.anchors.length === 0)
|
|
4209
|
+
throw new Error("redact: an anchored arm declares no anchor literal — the stream window cannot tell where its reading of prior text starts");
|
|
4210
|
+
for (const anchor of prior.anchors) {
|
|
4211
|
+
if (anchor.length === 0)
|
|
4212
|
+
throw new Error("redact: an anchored arm declares an empty anchor literal");
|
|
4213
|
+
for (let i = 0; i < anchor.length; i++) {
|
|
4214
|
+
const c = anchor.charCodeAt(i);
|
|
4215
|
+
if (INVISIBLE_UNIT_CLASS[c] !== 0 || FORMAT_CODEPOINT_TABLE[c] === 1 || (c & 0xf800) === 0xd800 || c === CH_BACKSLASH) {
|
|
4216
|
+
throw new Error(`redact: anchor literal ${JSON.stringify(anchor)} holds a unit some reading deletes or reads as an escape (index ${i}) — its presence is not monotone under deletion, so the stream window's delimiter check on the most-deleted reading would be incomplete`);
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
if (isEscapeBodyUnit(anchor.charCodeAt(0))) {
|
|
4220
|
+
throw new Error(`redact: anchor literal ${JSON.stringify(anchor)} starts with a unit an escape spelling's body can read — an escape begun just before it deletes that unit in the most-deleted reading, so its presence is not monotone under deletion and the stream window's delimiter check would be incomplete`);
|
|
4221
|
+
}
|
|
4222
|
+
if (!containerDelimiters.includes(anchor))
|
|
4223
|
+
containerDelimiters.push(anchor);
|
|
4224
|
+
}
|
|
4225
|
+
break;
|
|
4226
|
+
default: {
|
|
4227
|
+
const unhandled = prior;
|
|
4228
|
+
throw new Error(`redact: unhandled prior reading ${JSON.stringify(unhandled)}`);
|
|
4229
|
+
}
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
for (const gap of gaps)
|
|
4233
|
+
for (let u = 0; u < 0x10000; u++)
|
|
4234
|
+
if (gap(u))
|
|
4235
|
+
blank[u] = 1;
|
|
4236
|
+
return { blank, containerDelimiters };
|
|
4237
|
+
}
|
|
4238
|
+
const STREAM_WINDOW_ALPHABETS = deriveStreamWindowAlphabets(armPool.priors);
|
|
4239
|
+
export function streamWindowAlphabetsForTest(extra = []) {
|
|
4240
|
+
const a = extra.length === 0 ? STREAM_WINDOW_ALPHABETS : deriveStreamWindowAlphabets([...armPool.priors, ...extra]);
|
|
4241
|
+
return { isBlank: (unit) => a.blank[unit] === 1, containerDelimiters: a.containerDelimiters };
|
|
4242
|
+
}
|
|
4243
|
+
export function escapeGrammarForTest() {
|
|
4244
|
+
return {
|
|
4245
|
+
read: (s) => {
|
|
4246
|
+
let body = 0;
|
|
4247
|
+
while (body < s.length && s.charCodeAt(body) === CH_BACKSLASH)
|
|
4248
|
+
body += 1;
|
|
4249
|
+
const out = { end: -1 };
|
|
4250
|
+
const value = readSpelledCodePoint(s, body, out);
|
|
4251
|
+
return { value, end: value >= 0 ? out.end : -1 };
|
|
4252
|
+
},
|
|
4253
|
+
isBodyUnit: isEscapeBodyUnit,
|
|
4254
|
+
};
|
|
4255
|
+
}
|
|
4256
|
+
function windowAdvancePoint(text, units, alphabets = STREAM_WINDOW_ALPHABETS) {
|
|
4257
|
+
const r = readShortest(text, "multi-line");
|
|
4258
|
+
if (r.partial)
|
|
4259
|
+
return -1;
|
|
4260
|
+
const view = r.layers[0].fold.text;
|
|
4261
|
+
let k = r.visible;
|
|
4262
|
+
let n = 0;
|
|
4263
|
+
while (k > 0 && n < units) {
|
|
4264
|
+
k -= 1;
|
|
4265
|
+
if (alphabets.blank[view.charCodeAt(k)] !== 1)
|
|
4266
|
+
n += 1;
|
|
4267
|
+
}
|
|
4268
|
+
if (n < units)
|
|
4269
|
+
return 0;
|
|
4270
|
+
for (const d of alphabets.containerDelimiters) {
|
|
4271
|
+
const at = view.indexOf(d);
|
|
4272
|
+
if (at >= 0 && at < k)
|
|
4273
|
+
k = at;
|
|
4274
|
+
}
|
|
4275
|
+
const at = createViewToOriginal(r.layers).start(k);
|
|
4276
|
+
return at <= 0 ? 0 : text.lastIndexOf("\n", at - 1) + 1;
|
|
4277
|
+
}
|
|
4278
|
+
function windowIndependentAt(text, q) {
|
|
4279
|
+
const full = runRedaction(text, false, false, false, "free-text", "multi-line", { kind: "head", emitEnd: text.length }).spans;
|
|
4280
|
+
if (full.some((s) => s.start < q && s.end > q))
|
|
4281
|
+
return false;
|
|
4282
|
+
const after = full.filter((s) => s.start >= q);
|
|
4283
|
+
const tail = text.slice(q);
|
|
4284
|
+
const alone = runRedaction(tail, false, false, false, "free-text", "multi-line", { kind: "head", emitEnd: tail.length }).spans;
|
|
4285
|
+
if (after.length !== alone.length)
|
|
4286
|
+
return false;
|
|
4287
|
+
return after.every((a, i) => a.start - q === alone[i].start && a.end - q === alone[i].end && a.repl === alone[i].repl);
|
|
4288
|
+
}
|
|
4289
|
+
export function windowAdvancePointForTest(text, units, extra = []) {
|
|
4290
|
+
return windowAdvancePoint(text, units, extra.length === 0 ? STREAM_WINDOW_ALPHABETS : deriveStreamWindowAlphabets([...armPool.priors, ...extra]));
|
|
4291
|
+
}
|
|
4292
|
+
export function windowIndependentAtForTest(text, q) {
|
|
4293
|
+
return windowIndependentAt(text, q);
|
|
4294
|
+
}
|
|
4228
4295
|
export function createRedactionStream() {
|
|
4229
4296
|
return openRedactionStream(PENDING_TAIL_UNITS);
|
|
4230
4297
|
}
|
|
4298
|
+
export function createRedactionStreamWithoutWindowForTest() {
|
|
4299
|
+
return openRedactionStream(PENDING_TAIL_UNITS, false);
|
|
4300
|
+
}
|
|
4301
|
+
export function createRedactionStreamWithCertifierForTest(certify) {
|
|
4302
|
+
return openRedactionStream(PENDING_TAIL_UNITS, true, certify);
|
|
4303
|
+
}
|
|
4231
4304
|
export function createRedactionStreamWithTailForTest(units) {
|
|
4232
4305
|
return openRedactionStream(units);
|
|
4233
4306
|
}
|
|
4234
|
-
function openRedactionStream(pendingTail) {
|
|
4235
|
-
let
|
|
4307
|
+
function openRedactionStream(pendingTail, windowed = true, certify = windowIndependentAt) {
|
|
4308
|
+
let past = [];
|
|
4309
|
+
let total = 0;
|
|
4310
|
+
let win = "";
|
|
4311
|
+
let base = 0;
|
|
4312
|
+
let blockFrom = 0;
|
|
4236
4313
|
let released = 0;
|
|
4237
4314
|
let deliveredFrom = 0;
|
|
4238
4315
|
let sent = "";
|
|
4239
4316
|
let scannedAt = 0;
|
|
4317
|
+
let evaluatedAt = -1;
|
|
4318
|
+
let retryAt = 0;
|
|
4319
|
+
const whole = () => (past.length === 0 ? win : past.join("") + win);
|
|
4320
|
+
const advanceWindow = () => {
|
|
4321
|
+
if (!windowed || win.length < Math.max(STREAM_WINDOW_MIN, retryAt) || released < total || total === evaluatedAt)
|
|
4322
|
+
return;
|
|
4323
|
+
evaluatedAt = total;
|
|
4324
|
+
retryAt = win.length + (win.length >> 1);
|
|
4325
|
+
windowEvaluations += 1;
|
|
4326
|
+
const q = windowAdvancePoint(win, STREAM_WINDOW_HORIZON * pendingTail);
|
|
4327
|
+
if (q < 0) {
|
|
4328
|
+
retryAt = 0;
|
|
4329
|
+
return;
|
|
4330
|
+
}
|
|
4331
|
+
if (q === 0 || q * 2 < win.length)
|
|
4332
|
+
return;
|
|
4333
|
+
if (!certify(win, q)) {
|
|
4334
|
+
windowRefusals += 1;
|
|
4335
|
+
return;
|
|
4336
|
+
}
|
|
4337
|
+
past.push(win.slice(0, q));
|
|
4338
|
+
win = win.slice(q);
|
|
4339
|
+
base += q;
|
|
4340
|
+
retryAt = 0;
|
|
4341
|
+
windowAdvances += 1;
|
|
4342
|
+
};
|
|
4240
4343
|
return {
|
|
4241
4344
|
feed(chunk) {
|
|
4242
|
-
|
|
4345
|
+
win += chunk;
|
|
4346
|
+
total += chunk.length;
|
|
4243
4347
|
},
|
|
4244
4348
|
takeSettled() {
|
|
4245
|
-
if (
|
|
4349
|
+
if (total - released <= pendingTail)
|
|
4246
4350
|
return "";
|
|
4247
|
-
if (
|
|
4351
|
+
if (total - scannedAt < streamRescanStep(total))
|
|
4248
4352
|
return "";
|
|
4249
|
-
scannedAt =
|
|
4250
|
-
const emitEnd = pendingTailStart(
|
|
4251
|
-
|
|
4353
|
+
scannedAt = total;
|
|
4354
|
+
const emitEnd = pendingTailStart(win, pendingTail);
|
|
4355
|
+
const from = released - base;
|
|
4356
|
+
if (emitEnd <= from)
|
|
4252
4357
|
return "";
|
|
4253
|
-
const spans = runRedaction(
|
|
4358
|
+
const spans = runRedaction(win, false, false, false, "free-text", "multi-line", { kind: "head", emitEnd }).spans;
|
|
4254
4359
|
let cut = emitEnd;
|
|
4255
4360
|
for (const s of spans)
|
|
4256
4361
|
if (s.start < cut && s.end > cut)
|
|
4257
4362
|
cut = s.start;
|
|
4258
|
-
if (cut > 0 && cut <
|
|
4363
|
+
if (cut > 0 && cut < win.length && (win.charCodeAt(cut - 1) & 0xfc00) === 0xd800 && (win.charCodeAt(cut) & 0xfc00) === 0xdc00)
|
|
4259
4364
|
cut -= 1;
|
|
4260
|
-
if (cut <=
|
|
4365
|
+
if (cut <= from)
|
|
4261
4366
|
return "";
|
|
4262
|
-
const out = renderRange(
|
|
4263
|
-
released = cut;
|
|
4367
|
+
const out = renderRange(win, spans, from, cut);
|
|
4368
|
+
released = base + cut;
|
|
4264
4369
|
sent += out;
|
|
4265
4370
|
return out;
|
|
4266
4371
|
},
|
|
4267
4372
|
takeAll() {
|
|
4268
|
-
if (released ===
|
|
4373
|
+
if (released === total)
|
|
4269
4374
|
return "";
|
|
4270
|
-
const spans = runRedaction(
|
|
4271
|
-
const out = renderRange(
|
|
4272
|
-
released = scannedAt =
|
|
4375
|
+
const spans = runRedaction(win, false, false, false, "free-text", "multi-line", WHOLE_EXTENT).spans;
|
|
4376
|
+
const out = renderRange(win, spans, released - base, win.length);
|
|
4377
|
+
released = scannedAt = total;
|
|
4273
4378
|
sent += out;
|
|
4274
4379
|
return out;
|
|
4275
4380
|
},
|
|
4276
4381
|
flush() {
|
|
4277
|
-
if (deliveredFrom ===
|
|
4382
|
+
if (deliveredFrom === total)
|
|
4278
4383
|
return { rest: "", diverged: false };
|
|
4384
|
+
const buf = whole();
|
|
4279
4385
|
const spans = runRedaction(buf, false, false, false, "free-text", "multi-line", WHOLE_EXTENT).spans;
|
|
4280
4386
|
const split = released > deliveredFrom && spans.some((s) => s.start < released && s.end > released);
|
|
4281
4387
|
return { rest: renderRange(buf, spans, released, buf.length), diverged: split || renderRange(buf, spans, deliveredFrom, released) !== sent };
|
|
4282
4388
|
},
|
|
4283
4389
|
skip() {
|
|
4284
|
-
released = deliveredFrom = scannedAt =
|
|
4390
|
+
released = deliveredFrom = scannedAt = total;
|
|
4285
4391
|
sent = "";
|
|
4286
4392
|
},
|
|
4393
|
+
endBlock() {
|
|
4394
|
+
blockFrom = total;
|
|
4395
|
+
advanceWindow();
|
|
4396
|
+
},
|
|
4397
|
+
blockContext() {
|
|
4398
|
+
return win.slice(0, blockFrom - base);
|
|
4399
|
+
},
|
|
4400
|
+
blockBytes() {
|
|
4401
|
+
return win.slice(blockFrom - base);
|
|
4402
|
+
},
|
|
4287
4403
|
get fed() {
|
|
4288
|
-
return
|
|
4404
|
+
return whole();
|
|
4405
|
+
},
|
|
4406
|
+
get length() {
|
|
4407
|
+
return total;
|
|
4289
4408
|
},
|
|
4290
4409
|
};
|
|
4291
4410
|
}
|
|
@@ -1328,7 +1328,8 @@ export declare const SELF_MINTED_WIRE: {
|
|
|
1328
1328
|
/**
|
|
1329
1329
|
* 运维队列行与订阅流 `pending` 帧(停驻门族)上的 `rowVerdict`(7.144.0;core 7.62.0 [ref]):这一行**本引擎续不续得了** —— core 判官 `judgeCheckpointRow` 对这一行字节的判决,
|
|
1330
1330
|
* 与助手收件箱行的同名位、续跑第一级的拒同一个读者、同一答(逐字投,本服务不重算)。`satisfies Record<Extract<keyof PendingCheckpoint, "rowVerdict">, …>`:行形改名 / 删键而本表没跟 ⇒ tsc 红。
|
|
1331
|
-
* 在场律 `present-iff`:LOCAL 后端恒在;SQL
|
|
1331
|
+
* 在场律 `present-iff`:LOCAL 后端恒在;SQL 后端只在「两次读之间行离开待决」或「两次读之间行的字节变了」时缺席 —— 缺席不是 `ok`。
|
|
1332
|
+
* 字节读不成一只检查点的行(7.145.0 起)判官照答(恒 `damaged`,计数)、在场 —— 7.144.x 这一形缺席。
|
|
1332
1333
|
*/
|
|
1333
1334
|
readonly approvalQueueRowVerdict: {
|
|
1334
1335
|
readonly at: "GET /v1/approvals pending[] 行 · GET /v1/approvals/stream pending 帧(停驻门族)的 rowVerdict";
|
|
@@ -1339,6 +1340,21 @@ export declare const SELF_MINTED_WIRE: {
|
|
|
1339
1340
|
};
|
|
1340
1341
|
};
|
|
1341
1342
|
};
|
|
1343
|
+
/**
|
|
1344
|
+
* 运维队列停驻行(`kind: "checkpoint"`)与订阅流 `pending` 帧上的 `agent` —— 行的会话(`sessionId`)在委派树里的位置 `{ id?, parentSessionId?, rootSessionId? }`,
|
|
1345
|
+
* 与 `GET /v1/sessions/:sessionId` 体顶层的同名键同一只读口(`session-agent.ts` 的 `readSessionAgent`)、同一只投影,逐值同答。
|
|
1346
|
+
* 在场律 `present-iff`:这一次列表读到行的会话是一只 placed 委派子代(会话行上存着引擎写下的委派元组);宿主会话、同步委派的子代、`fork` 型后台子代、
|
|
1347
|
+
* 不存元组的店、那一读没读成(F 类 `server.approvals.queue-row-agent-unreadable`)⇒ 缺席 —— 缺席读作「这台 server 没有说」。`satisfies` 绑行形:删键 / 改名而本表没跟 ⇒ tsc 红。
|
|
1348
|
+
*/
|
|
1349
|
+
readonly approvalQueueRowAgent: {
|
|
1350
|
+
readonly at: "GET /v1/approvals pending[] 行 · GET /v1/approvals/stream pending 帧(停驻门族)的 agent";
|
|
1351
|
+
readonly members: {
|
|
1352
|
+
agent: {
|
|
1353
|
+
attr: string;
|
|
1354
|
+
since: string;
|
|
1355
|
+
};
|
|
1356
|
+
};
|
|
1357
|
+
};
|
|
1342
1358
|
/**
|
|
1343
1359
|
* 运维审批队列 `pending[]` 的**行族闭集**(7.143.0):每一行 / 每一帧(`pending` 与 `resolved`)恒带 `kind`,消费方先按它分支。
|
|
1344
1360
|
* `satisfies Record<ApprovalQueueKind, …>`(闭集属主 = `approval-queue-kind.ts` 的 `APPROVAL_QUEUE_KINDS`;加一族而本表没跟 ⇒ tsc 红)。
|
|
@@ -1653,6 +1669,10 @@ export declare const SELF_MINTED_WIRE: {
|
|
|
1653
1669
|
readonly attr: 409;
|
|
1654
1670
|
readonly since: "7.144.0";
|
|
1655
1671
|
};
|
|
1672
|
+
readonly "POST /v1/sessions/:id/sync/import#stamped_archive(DB_BACKEND=local;\u7B2C\u4E00\u9636\u6BB5\u6309 id \u5206\u7C7B\u51FA fork / stale \u4E14\u6CA1\u5E26\u540C\u610F,\u76EE\u7684\u7AEF\u5B58\u6863\u4ECD\u5E26\u5C5E\u4E3B\u6233;\u4E0D\u5F00\u6682\u5B58\u3001\u4E0D\u62FF\u79DF\u7EA6\u3001\u4E0D\u5199\u5B58\u6863;\u4F53 conflict.session_archive_stamped + \u5E26\u6233\u5B58\u6863\u7684\u56FA\u5B9A\u53E5,\u4E0D\u5E26 relation)": {
|
|
1673
|
+
readonly attr: 409;
|
|
1674
|
+
readonly since: "7.145.0";
|
|
1675
|
+
};
|
|
1656
1676
|
readonly "POST /v1/tasks|/v1/tasks/stream|/v1/runs#images_url_credential(\u65B0\u63D0\u4EA4;\u4F53 request.field_invalid + field images[i].url + reason url_userinfo|url_credential_param)": {
|
|
1657
1677
|
readonly attr: 400;
|
|
1658
1678
|
readonly since: "7.136.0";
|
|
@@ -1881,6 +1901,58 @@ export declare const SELF_MINTED_WIRE: {
|
|
|
1881
1901
|
readonly attr: 503;
|
|
1882
1902
|
readonly since: "7.143.0";
|
|
1883
1903
|
};
|
|
1904
|
+
readonly "POST /v1/rules/cc-import/redeem#member_refused(\u5151\u4ED8\u8D70\u5B8C\u3001\u5F15\u64CE\u7684\u5B8C\u6574\u6210\u5458\u8868\u91CC\u6709\u88AB\u62D2\u7684\u6210\u5458;\u4F53 = \u56DE\u6267 { members, rev },\u90A3\u51E0\u884C outcome indeterminate + reason store_refused + detail \u5F15\u64CE\u539F\u8BDD;\u7968\u7528\u6389,\u540C\u7968\u518D\u5151 404)": {
|
|
1905
|
+
readonly attr: 200;
|
|
1906
|
+
readonly since: "7.145.0";
|
|
1907
|
+
};
|
|
1908
|
+
};
|
|
1909
|
+
};
|
|
1910
|
+
/**
|
|
1911
|
+
* `POST /v1/rules/cc-import/redeem` 200 回执的顶层键(<键> → 在场律)。规则导入两只 redeem 口同一张回执、同一个铸点(`http/routes/rules.ts` 的 `sendImportReceipt`),
|
|
1912
|
+
* 键集属主 = `rules-consent.ts` 的 `ImportOutcome`(`satisfies` 穷举:回执加一键而本表没跟 / 登的键不在回执里 ⇒ tsc 红)。`POST /v1/rules/local-import/redeem` 早于本表就是这一形,
|
|
1913
|
+
* 本表的 `since` 记的是 cc-import 口换上这一形的版本;cc-import 口此前那一形的唯一顶层键 `result` 记在 `retired`。钉 test/rules-import-receipt.test.ts(两口逐字节同形)、
|
|
1914
|
+
* test/permission-rules-lane.test.ts(cc-import 200 体全等)。
|
|
1915
|
+
*/
|
|
1916
|
+
readonly ruleImportReceiptKey: {
|
|
1917
|
+
readonly at: "POST /v1/rules/cc-import/redeem 200 回执顶层键(<键> → 在场律;与 POST /v1/rules/local-import/redeem 同形)";
|
|
1918
|
+
readonly members: {
|
|
1919
|
+
members: {
|
|
1920
|
+
attr: string;
|
|
1921
|
+
since: string;
|
|
1922
|
+
};
|
|
1923
|
+
rev: {
|
|
1924
|
+
attr: string;
|
|
1925
|
+
since: string;
|
|
1926
|
+
};
|
|
1927
|
+
};
|
|
1928
|
+
readonly retired: {
|
|
1929
|
+
readonly "result(\u22647.144.0 \u7684 cc-import \u56DE\u6267:{ members: <\u5F15\u64CE RedeemedBatchMember \u539F\u5F62\u884C:candidateIndex / behavior / rule / scope \u5BF9\u8C61 / status / alreadyRedeemed / dot>, rev })": {
|
|
1930
|
+
readonly attr: "always";
|
|
1931
|
+
readonly since: "7.46.0";
|
|
1932
|
+
readonly until: "7.145.0";
|
|
1933
|
+
};
|
|
1934
|
+
};
|
|
1935
|
+
};
|
|
1936
|
+
/** 同上回执 `members[]` 一行的键(<键> → 在场律)。键集属主 = `ImportOutcomeMember`(`satisfies` 穷举),唯一投影 = `rules-consent.ts` 的 `buildImportOutcomeMembers`(两口同调)。 */
|
|
1937
|
+
readonly ruleImportReceiptMemberKey: {
|
|
1938
|
+
readonly at: "POST /v1/rules/cc-import/redeem 200 回执 members[] 行键(<键> → 在场律;与 POST /v1/rules/local-import/redeem 同形)";
|
|
1939
|
+
readonly members: {
|
|
1940
|
+
key: {
|
|
1941
|
+
attr: string;
|
|
1942
|
+
since: string;
|
|
1943
|
+
};
|
|
1944
|
+
outcome: {
|
|
1945
|
+
attr: string;
|
|
1946
|
+
since: string;
|
|
1947
|
+
};
|
|
1948
|
+
reason: {
|
|
1949
|
+
attr: string;
|
|
1950
|
+
since: string;
|
|
1951
|
+
};
|
|
1952
|
+
detail: {
|
|
1953
|
+
attr: string;
|
|
1954
|
+
since: string;
|
|
1955
|
+
};
|
|
1884
1956
|
};
|
|
1885
1957
|
};
|
|
1886
1958
|
/**
|