@sema-agent/server 7.145.0 → 7.146.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 +492 -0
- package/USAGE.md +218 -47
- package/deploy/facts/CHANGES.json +25 -0
- package/deploy/facts/README.md +57 -0
- package/deploy/facts/lanes.json +54 -0
- package/deploy/facts/lanes.schema.json +57 -0
- package/deploy/facts/sandbox-rbac.json +113 -0
- package/deploy/facts/sandbox-rbac.schema.json +74 -0
- package/deploy/facts/sealed-key.json +9 -0
- package/deploy/facts/sealed-key.schema.json +52 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +19 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +4 -0
- package/deploy/sema-up/chart/templates/server.yaml +4 -0
- package/deploy/sema-up/chart/values.yaml +7 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +30 -14
- package/dist/adoption/import-limits.d.ts +6 -0
- package/dist/adoption/import-limits.js +7 -0
- package/dist/adoption/import.d.ts +62 -0
- package/dist/adoption/import.js +107 -0
- package/dist/adoption/wire.d.ts +52 -0
- package/dist/adoption/wire.js +9 -0
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +3 -12
- package/dist/approval-card.js +0 -4
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/approval-gate-currency.js +1 -1
- package/dist/approval-reconciler.d.ts +1 -1
- package/dist/boot/deployment-mods.d.ts +11 -1
- package/dist/boot/deployment-mods.js +15 -2
- package/dist/boot/device-lane.js +2 -0
- package/dist/boot/engine-lease.d.ts +193 -21
- package/dist/boot/engine-lease.js +146 -20
- package/dist/boot/execution-env.d.ts +4 -0
- package/dist/boot/execution-env.js +12 -0
- package/dist/boot/exit-boundary.d.ts +50 -0
- package/dist/boot/exit-boundary.js +32 -0
- package/dist/boot/exit-last.d.ts +20 -4
- package/dist/boot/exit-last.js +21 -4
- package/dist/boot/governance-seams.js +1 -0
- package/dist/boot/memory-consolidation.d.ts +29 -17
- package/dist/boot/memory-consolidation.js +26 -15
- package/dist/boot/reapers.d.ts +12 -4
- package/dist/boot/reapers.js +39 -15
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +38 -15
- package/dist/boot/runner-deps.js +1 -1
- package/dist/boot/session-faces.js +3 -1
- package/dist/boot/shutdown.js +27 -9
- package/dist/boot/stage-01-config.js +1 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-05-execution-env.d.ts +3 -0
- package/dist/boot/stage-05-execution-env.js +3 -3
- package/dist/boot/stage-06-runners.d.ts +3 -0
- package/dist/boot/stage-06-runners.js +11 -10
- package/dist/boot/stage-07-capability-layer.d.ts +3 -0
- package/dist/boot/stage-07-capability-layer.js +7 -2
- package/dist/boot/stage-08-reapers.d.ts +3 -0
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +3 -0
- package/dist/boot/stage-10-http-server.d.ts +3 -0
- package/dist/boot/stage-10-http-server.js +3 -2
- package/dist/boot/stores.d.ts +1 -0
- package/dist/boot/stores.js +35 -19
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/capabilities/composite-members.d.ts +3 -1
- package/dist/capabilities/composite-members.js +3 -1
- package/dist/capabilities/scenarios.d.ts +2 -2
- package/dist/capability-facts.d.ts +18 -1
- package/dist/capability-facts.js +25 -7
- package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
- package/dist/config-catalog.js +13 -4
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-types.d.ts +43 -4
- package/dist/config.d.ts +6 -1
- package/dist/config.js +67 -11
- package/dist/deleted-session-ids.d.ts +19 -0
- package/dist/deleted-session-ids.js +26 -0
- package/dist/deploy-facts.d.ts +155 -0
- package/dist/deploy-facts.js +94 -0
- package/dist/device-ws-hub.d.ts +48 -3
- package/dist/device-ws-hub.js +48 -2
- package/dist/error-code-family.d.ts +35 -0
- package/dist/error-code-family.js +26 -0
- package/dist/fleet/drain-entry.d.ts +39 -3
- package/dist/fleet/drain-entry.js +6 -0
- package/dist/fleet/fleet-bus.d.ts +2 -1
- package/dist/hooks/branch-transcript.d.ts +1 -1
- package/dist/hooks/branch-transcript.js +1 -0
- package/dist/hooks/classic-stations.d.ts +25 -8
- package/dist/hooks/classic-stations.js +29 -3
- package/dist/hooks/hook-runner.d.ts +33 -16
- package/dist/hooks/hook-runner.js +166 -73
- package/dist/hooks/hook-source.d.ts +14 -2
- package/dist/hooks/hook-source.js +8 -0
- package/dist/http/active-run-conflict.d.ts +1 -1
- package/dist/http/active-run-conflict.js +1 -1
- package/dist/http/admission.js +11 -1
- package/dist/http/checkpoint-ctx.d.ts +59 -71
- package/dist/http/checkpoint-ctx.js +34 -40
- package/dist/http/dispatch.js +18 -2
- package/dist/http/durable-run-leg.d.ts +5 -0
- package/dist/http/durable-run-leg.js +1 -0
- package/dist/http/execution-context.d.ts +4 -0
- package/dist/http/execution-context.js +9 -0
- package/dist/http/health-self-report.d.ts +6 -2
- package/dist/http/health-self-report.js +3 -2
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -1
- package/dist/http/memory-compliance-failure-reply.js +2 -15
- package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
- package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
- package/dist/http/principal-gate.d.ts +35 -12
- package/dist/http/principal-gate.js +16 -12
- package/dist/http/request-guards.d.ts +1 -1
- package/dist/http/request-guards.js +5 -5
- package/dist/http/resume-legs.d.ts +22 -0
- package/dist/http/resume-legs.js +26 -17
- package/dist/http/route-ctx.d.ts +11 -10
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/adoption.d.ts +11 -0
- package/dist/http/routes/adoption.js +80 -6
- package/dist/http/routes/agents-roster.js +1 -0
- package/dist/http/routes/approvals-assistant.js +2 -1
- package/dist/http/routes/background.js +1 -0
- package/dist/http/routes/capabilities.js +4 -1
- package/dist/http/routes/diagnostics.d.ts +9 -14
- package/dist/http/routes/diagnostics.js +10 -20
- package/dist/http/routes/engine.d.ts +31 -0
- package/dist/http/routes/engine.js +81 -0
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-consolidation.js +3 -5
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/memory-origin.js +2 -4
- package/dist/http/routes/memory-policy.js +5 -1
- package/dist/http/routes/observability.js +3 -6
- package/dist/http/routes/runs.js +7 -3
- package/dist/http/routes/session-sync.js +12 -25
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.js +4 -0
- package/dist/http/routes/tasks.js +23 -5
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/run-concurrency-cap.d.ts +86 -0
- package/dist/http/run-concurrency-cap.js +54 -0
- package/dist/http/server.d.ts +15 -12
- package/dist/http/server.js +18 -3
- package/dist/http/stored-body-replay.d.ts +9 -6
- package/dist/http/stored-body-replay.js +19 -5
- package/dist/http/wire-types.d.ts +8 -3
- package/dist/json-body-limit.d.ts +8 -0
- package/dist/json-body-limit.js +2 -0
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/local-data-root.d.ts +2 -2
- package/dist/memory-operator-faces.d.ts +9 -4
- package/dist/memory-scope-stores.d.ts +9 -7
- package/dist/memory-scope-stores.js +3 -14
- package/dist/memory-scope.d.ts +36 -0
- package/dist/memory-scope.js +32 -1
- package/dist/net-address.d.ts +53 -0
- package/dist/net-address.js +111 -0
- package/dist/observability/fail-open.d.ts +14 -10
- package/dist/observability/fail-open.js +14 -10
- package/dist/orchestration/workflow-notify-journal.js +2 -3
- package/dist/org-delivery-gate.js +1 -1
- package/dist/peer-directory.d.ts +6 -12
- package/dist/peer-directory.js +5 -1
- package/dist/plugins/caching-session-store.d.ts +3 -1
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-face.d.ts +426 -0
- package/dist/plugins/checkpoint-store-face.js +152 -0
- package/dist/plugins/file-run-store.d.ts +0 -6
- package/dist/plugins/file-run-store.js +1 -12
- package/dist/plugins/fork-routing-session-store.d.ts +6 -2
- package/dist/plugins/fork-routing-session-store.js +2 -2
- package/dist/plugins/imported-layer-root-retirement.d.ts +10 -8
- package/dist/plugins/local-checkpoint-store.d.ts +2 -2
- package/dist/plugins/local-checkpoint-store.js +2 -1
- package/dist/plugins/local-session-store.d.ts +28 -5
- package/dist/plugins/local-session-store.js +32 -8
- package/dist/plugins/memory-engine-pg.d.ts +29 -6
- package/dist/plugins/memory-engine-pg.js +96 -214
- package/dist/plugins/memory-engine-sql-apply.d.ts +121 -0
- package/dist/plugins/memory-engine-sql-apply.js +358 -0
- package/dist/plugins/memory-engine-tidb.d.ts +35 -9
- package/dist/plugins/memory-engine-tidb.js +97 -227
- package/dist/plugins/memory-key-guards.d.ts +1 -1
- package/dist/plugins/memory-origin-law.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +32 -56
- package/dist/plugins/one-time-migrations.js +25 -117
- package/dist/plugins/permission-rule-store-file.d.ts +17 -3
- package/dist/plugins/permission-rule-store-file.js +8 -1
- package/dist/plugins/pg-pool.js +1 -1
- package/dist/plugins/pg-session-storage.d.ts +17 -4
- package/dist/plugins/pg-session-storage.js +8 -4
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/schema-ensure-legs.js +2 -2
- package/dist/plugins/session-fork.d.ts +31 -9
- package/dist/plugins/session-fork.js +3 -2
- package/dist/plugins/session-placement.d.ts +4 -2
- package/dist/plugins/sql-json-column.d.ts +5 -1
- package/dist/plugins/store-backend.d.ts +11 -8
- package/dist/plugins/store-backend.js +8 -7
- package/dist/plugins/store-contracts.d.ts +1 -11
- package/dist/plugins/store-contracts.js +0 -9
- package/dist/plugins/store-sweep.d.ts +63 -0
- package/dist/plugins/store-sweep.js +48 -0
- package/dist/plugins/tidb-pool.js +1 -1
- package/dist/plugins/tidb-session-store.d.ts +16 -3
- package/dist/plugins/tidb-session-store.js +8 -4
- package/dist/prompt-screen.d.ts +6 -9
- package/dist/prompt-screen.js +2 -5
- package/dist/rules-consent.d.ts +20 -27
- package/dist/rules-consent.js +82 -6
- package/dist/run-cancel-context.d.ts +4 -1
- package/dist/run-cancel-context.js +2 -1
- package/dist/runs.js +1 -1
- package/dist/sandbox-egress-policy.js +6 -11
- package/dist/sandbox-rbac-rules.d.ts +88 -0
- package/dist/sandbox-rbac-rules.js +80 -0
- package/dist/sealed-key-layout.d.ts +17 -0
- package/dist/sealed-key-layout.js +4 -0
- package/dist/sealed-key.js +5 -5
- package/dist/security.d.ts +38 -6
- package/dist/security.js +9 -2
- package/dist/session-notify-door.d.ts +5 -3
- package/dist/session-resident-background.d.ts +57 -0
- package/dist/session-resident-background.js +20 -0
- package/dist/session-sync-kernel.d.ts +53 -14
- package/dist/session-sync-kernel.js +70 -1
- package/dist/session-sync.d.ts +5 -3
- package/dist/session-workspace.d.ts +1 -0
- package/dist/session-workspace.js +1 -0
- package/dist/sighup-idle.d.ts +9 -7
- package/dist/sighup-idle.js +4 -5
- package/dist/spec-fields.d.ts +16 -0
- package/dist/spec-fields.js +7 -0
- package/dist/stored-request-env-credentials-m38.d.ts +3 -0
- package/dist/stored-request-env-credentials-m38.js +8 -0
- package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +13 -427
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +33 -194
- package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
- package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
- package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
- package/dist/task-settings.d.ts +59 -4
- package/dist/task-settings.js +50 -4
- package/dist/tool-approval.d.ts +2 -2
- package/dist/trace/core-keyset-guard.d.ts +8 -7
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +6 -0
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/project.js +9 -0
- package/dist/trace/redact.d.ts +13 -2
- package/dist/trace/redact.js +305 -24
- package/dist/trace/self-minted-wire.d.ts +326 -8
- package/dist/trace/self-minted-wire.js +125 -7
- package/dist/trace/wire-projection-faces.d.ts +1 -1
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/usage-analytics.d.ts +4 -0
- package/package.json +12 -4
- package/scripts/drain-check-local.mjs +8 -29
- package/scripts/drain-check.mysql.sql +3 -24
- package/scripts/drain-check.pg.sql +3 -24
- package/skills/update-config.md +1 -1
- package/wire-changes/server@7.146.0.json +3221 -0
- package/dist/approval-batch-census.d.ts +0 -27
- package/dist/approval-batch-census.js +0 -27
package/dist/trace/redact.js
CHANGED
|
@@ -1062,7 +1062,7 @@ function undecidedKeywordStart(text, t) {
|
|
|
1062
1062
|
}
|
|
1063
1063
|
const CREDENTIAL_NAME_ANCHORS = {
|
|
1064
1064
|
api_key: "declarative", apikey: "declarative", "api-key": "declarative", key: "structure-only",
|
|
1065
|
-
token: "
|
|
1065
|
+
token: "assignment", access_token: "declarative", refresh_token: "declarative", id_token: "declarative",
|
|
1066
1066
|
auth: "structure-only", authorization: "auth-scheme", "proxy-authorization": "auth-scheme",
|
|
1067
1067
|
password: "declarative", passwd: "any-form", pwd: "any-form",
|
|
1068
1068
|
secret: "declarative", client_secret: "declarative", private_key: "declarative",
|
|
@@ -1105,6 +1105,33 @@ function credentialNameAnchor(name) {
|
|
|
1105
1105
|
return CREDENTIAL_ANCHOR_OF.get(asciiLower(name));
|
|
1106
1106
|
}
|
|
1107
1107
|
const CREDENTIAL_ANCHOR_OF = new Map(Object.entries(CREDENTIAL_NAME_ANCHORS));
|
|
1108
|
+
const BARE_WORD_READINGS = {
|
|
1109
|
+
null: "absent-or-boolean", nil: "absent-or-boolean", none: "absent-or-boolean", undefined: "absent-or-boolean",
|
|
1110
|
+
true: "absent-or-boolean", false: "absent-or-boolean", yes: "absent-or-boolean", no: "absent-or-boolean",
|
|
1111
|
+
str: "type-name", string: "type-name", bytes: "type-name", int: "type-name", integer: "type-name", float: "type-name", number: "type-name",
|
|
1112
|
+
bool: "type-name", boolean: "type-name", any: "type-name", object: "type-name", array: "type-name", secretstr: "type-name",
|
|
1113
|
+
};
|
|
1114
|
+
for (const w of Object.keys(BARE_WORD_READINGS)) {
|
|
1115
|
+
if (!/^[a-z]+$/.test(w))
|
|
1116
|
+
throw new Error(`redact: bare value word ${JSON.stringify(w)} must be lowercase ASCII letters (values are ASCII-lowercased before the lookup)`);
|
|
1117
|
+
}
|
|
1118
|
+
const BARE_WORD_OF = new Map(Object.entries(BARE_WORD_READINGS));
|
|
1119
|
+
const BARE_WORD_MAX = Math.max(...Object.keys(BARE_WORD_READINGS).map((w) => w.length));
|
|
1120
|
+
function bareWordIsValue(reading, bare) {
|
|
1121
|
+
switch (reading) {
|
|
1122
|
+
case "absent-or-boolean":
|
|
1123
|
+
return false;
|
|
1124
|
+
case "type-name":
|
|
1125
|
+
return bare === "declared";
|
|
1126
|
+
default: {
|
|
1127
|
+
const unhandled = reading;
|
|
1128
|
+
throw new Error(`redact: unhandled bare value word reading ${String(unhandled)}`);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
export function lineKeyTypeNamesForTest() {
|
|
1133
|
+
return Object.entries(BARE_WORD_READINGS).filter(([, r]) => r === "type-name").map(([w]) => w);
|
|
1134
|
+
}
|
|
1108
1135
|
const STRUCTURAL_SECRET_PATTERNS = [
|
|
1109
1136
|
[/-----BEGIN(?:[^-](?:[^-](?:[^-]|-(?!-))*)?)?PRIVATE KEY(?: BLOCK)?-----[\s\S]{0,8192}?-----END(?:[^-](?:[^-](?:[^-]|-(?!-))*)?)?PRIVATE KEY(?: BLOCK)?-----/g, "«redacted:private-key»"],
|
|
1110
1137
|
[/---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----[\s\S]{0,8192}?---- END SSH2 ENCRYPTED PRIVATE KEY ----/g, "«redacted:private-key»"],
|
|
@@ -3126,8 +3153,6 @@ function isEngineMarkedCandidate(text, start, end, repl) {
|
|
|
3126
3153
|
return end - start === lead.length + REDACTION_MARK.length + trail.length && text.startsWith(lead, start) && text.startsWith(REDACTION_MARK, start + lead.length) && text.startsWith(trail, end - trail.length);
|
|
3127
3154
|
}
|
|
3128
3155
|
const STRONG_AUTH_SCHEME_MAX = Math.max(...[...STRONG_AUTH_SCHEMES].map((w) => w.length));
|
|
3129
|
-
const ABSENT_OR_BOOLEAN_WORDS = new Set(["null", "nil", "none", "undefined", "true", "false", "yes", "no"]);
|
|
3130
|
-
const ABSENT_OR_BOOLEAN_MAX = Math.max(...[...ABSENT_OR_BOOLEAN_WORDS].map((w) => w.length));
|
|
3131
3156
|
const CH_GRAVE = 96, CH_APOS = 39, CH_DOT = 46, CH_COMMA = 44, CH_SEMI = 59, CH_DOLLAR = 36;
|
|
3132
3157
|
const CH_LPAREN = 40, CH_RPAREN = 41, CH_RBRACKET = 93, CH_LBRACE = 123, CH_RBRACE = 125, CH_LT = 60, CH_GT = 62;
|
|
3133
3158
|
const CH_QMARK = 63, CH_AMP = 38, CH_HASH = 35;
|
|
@@ -3154,6 +3179,9 @@ const unitChOf = (unit) => (unit >> 3) - 1;
|
|
|
3154
3179
|
const unitLenOf = (unit) => unit & 7;
|
|
3155
3180
|
function readAnchorUnit(text, i, json) {
|
|
3156
3181
|
anchoredScanUnits += 1;
|
|
3182
|
+
return readTextUnit(text, i, json);
|
|
3183
|
+
}
|
|
3184
|
+
function readTextUnit(text, i, json) {
|
|
3157
3185
|
const c = text.charCodeAt(i);
|
|
3158
3186
|
if (!json)
|
|
3159
3187
|
return packUnit(c, 1);
|
|
@@ -3269,7 +3297,7 @@ function anchorHeadAt(scan, text, op, json) {
|
|
|
3269
3297
|
const left = k >= 0 ? text.charCodeAt(k) : 0;
|
|
3270
3298
|
listSep = left === CH_QMARK || left === CH_AMP || left === CH_HASH ? CH_AMP : left === CH_SEMI ? CH_SEMI : left === CH_COMMA || left === CH_LPAREN || left === CH_LBRACKET || left === CH_LBRACE ? CH_COMMA : 0;
|
|
3271
3299
|
}
|
|
3272
|
-
return { strength, quotedName: quote !== 0, spacedLeft, listSep };
|
|
3300
|
+
return { strength, quotedName: quote !== 0, spacedLeft, listSep, runStart };
|
|
3273
3301
|
}
|
|
3274
3302
|
function quotedValueEnd(text, cs, quote, json, isHead) {
|
|
3275
3303
|
const n = text.length;
|
|
@@ -3382,7 +3410,7 @@ function bareValueEnd(text, s, json, listSep, memo) {
|
|
|
3382
3410
|
}
|
|
3383
3411
|
return e;
|
|
3384
3412
|
}
|
|
3385
|
-
function literalValueAt(text, s, json,
|
|
3413
|
+
function literalValueAt(text, s, json, bare, listSep, isHead, memo) {
|
|
3386
3414
|
const n = text.length;
|
|
3387
3415
|
if (s >= n)
|
|
3388
3416
|
return undefined;
|
|
@@ -3403,8 +3431,21 @@ function literalValueAt(text, s, json, declaredIfBare, listSep, isHead, memo) {
|
|
|
3403
3431
|
}
|
|
3404
3432
|
else if (!isAsciiAlnumCode(first))
|
|
3405
3433
|
return undefined;
|
|
3406
|
-
|
|
3407
|
-
|
|
3434
|
+
let lineKey;
|
|
3435
|
+
switch (bare) {
|
|
3436
|
+
case "never":
|
|
3437
|
+
return undefined;
|
|
3438
|
+
case "declared":
|
|
3439
|
+
lineKey = false;
|
|
3440
|
+
break;
|
|
3441
|
+
case "line-key":
|
|
3442
|
+
lineKey = true;
|
|
3443
|
+
break;
|
|
3444
|
+
default: {
|
|
3445
|
+
const unhandled = bare;
|
|
3446
|
+
throw new Error(`redact: unhandled bare literal form ${String(unhandled)}`);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3408
3449
|
if (isProgramIdentStartCode(text.charCodeAt(vs))) {
|
|
3409
3450
|
let k = vs;
|
|
3410
3451
|
while (k < n && isProgramIdentCode(text.charCodeAt(k)))
|
|
@@ -3417,10 +3458,92 @@ function literalValueAt(text, s, json, declaredIfBare, listSep, isHead, memo) {
|
|
|
3417
3458
|
const e = bareValueEnd(text, vs, json, listSep, memo);
|
|
3418
3459
|
if (e <= vs)
|
|
3419
3460
|
return undefined;
|
|
3420
|
-
if (e - vs <=
|
|
3421
|
-
|
|
3461
|
+
if (e - vs <= BARE_WORD_MAX) {
|
|
3462
|
+
const reading = BARE_WORD_OF.get(asciiLower(text.slice(vs, e)));
|
|
3463
|
+
if (reading !== undefined && !bareWordIsValue(reading, lineKey ? "line-key" : "declared"))
|
|
3464
|
+
return undefined;
|
|
3465
|
+
}
|
|
3466
|
+
if (lineKey) {
|
|
3467
|
+
const rest = lineKeyRestAt(text, e, json, isHead);
|
|
3468
|
+
switch (rest) {
|
|
3469
|
+
case "ends":
|
|
3470
|
+
break;
|
|
3471
|
+
case "goes-on":
|
|
3472
|
+
return undefined;
|
|
3473
|
+
case "undecided":
|
|
3474
|
+
return { start: vs, end: text.length, quoted: false, open: true };
|
|
3475
|
+
default: {
|
|
3476
|
+
const unhandled = rest;
|
|
3477
|
+
throw new Error(`redact: unhandled line-key rest ${String(unhandled)}`);
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3422
3481
|
return { start: vs, end: e, quoted: false };
|
|
3423
3482
|
}
|
|
3483
|
+
function lineKeyRestAt(text, e, json, isHead) {
|
|
3484
|
+
const n = text.length;
|
|
3485
|
+
let i = e;
|
|
3486
|
+
while (i < n) {
|
|
3487
|
+
const unit = readAnchorUnit(text, i, json);
|
|
3488
|
+
const ch = unitChOf(unit);
|
|
3489
|
+
if (isInlineSpaceUnit(ch) || (ch >= 0 && INVISIBLE_UNIT_CLASS[ch] === 1)) {
|
|
3490
|
+
i += unitLenOf(unit);
|
|
3491
|
+
continue;
|
|
3492
|
+
}
|
|
3493
|
+
return ch === JSON_STRING_END || isLineTerminator(ch) || ch === CH_HASH ? "ends" : "goes-on";
|
|
3494
|
+
}
|
|
3495
|
+
return isHead ? "undecided" : "ends";
|
|
3496
|
+
}
|
|
3497
|
+
function unitEndingAt(text, end, json) {
|
|
3498
|
+
const c = text.charCodeAt(end - 1);
|
|
3499
|
+
anchoredScanUnits += 1;
|
|
3500
|
+
if (!json)
|
|
3501
|
+
return packUnit(c, 1);
|
|
3502
|
+
if (end >= 6 && text.charCodeAt(end - 6) === CH_BACKSLASH && text.charCodeAt(end - 5) === CH_u && !escapedAt(text, end - 6)) {
|
|
3503
|
+
const h0 = hexDigitValue(text.charCodeAt(end - 4));
|
|
3504
|
+
const h1 = hexDigitValue(text.charCodeAt(end - 3));
|
|
3505
|
+
const h2 = hexDigitValue(text.charCodeAt(end - 2));
|
|
3506
|
+
const h3 = hexDigitValue(text.charCodeAt(end - 1));
|
|
3507
|
+
if (h0 >= 0 && h1 >= 0 && h2 >= 0 && h3 >= 0)
|
|
3508
|
+
return packUnit((h0 << 12) | (h1 << 8) | (h2 << 4) | h3, 6);
|
|
3509
|
+
}
|
|
3510
|
+
if (end >= 2 && text.charCodeAt(end - 2) === CH_BACKSLASH && escapedAt(text, end - 1)) {
|
|
3511
|
+
const two = readTextUnit(text, end - 2, true);
|
|
3512
|
+
if (unitLenOf(two) === 2)
|
|
3513
|
+
return two;
|
|
3514
|
+
}
|
|
3515
|
+
return c === CH_QUOTE ? packUnit(JSON_STRING_END, 1) : packUnit(c, 1);
|
|
3516
|
+
}
|
|
3517
|
+
function lineHeadBefore(text, at, json) {
|
|
3518
|
+
let i = at;
|
|
3519
|
+
let blank = false;
|
|
3520
|
+
for (;;) {
|
|
3521
|
+
if (i <= 0)
|
|
3522
|
+
return true;
|
|
3523
|
+
const unit = unitEndingAt(text, i, json);
|
|
3524
|
+
const ch = unitChOf(unit);
|
|
3525
|
+
if (isInlineSpaceUnit(ch)) {
|
|
3526
|
+
i -= unitLenOf(unit);
|
|
3527
|
+
blank = true;
|
|
3528
|
+
continue;
|
|
3529
|
+
}
|
|
3530
|
+
if (ch >= 0 && INVISIBLE_UNIT_CLASS[ch] === 1) {
|
|
3531
|
+
i -= unitLenOf(unit);
|
|
3532
|
+
continue;
|
|
3533
|
+
}
|
|
3534
|
+
if (ch === CH_MINUS && blank) {
|
|
3535
|
+
i -= unitLenOf(unit);
|
|
3536
|
+
blank = false;
|
|
3537
|
+
continue;
|
|
3538
|
+
}
|
|
3539
|
+
return isLineTerminator(ch) || ch === JSON_STRING_END;
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
function declarativeBareAt(text, head, spacedRight, json) {
|
|
3543
|
+
if (head.quotedName || (!head.spacedLeft && !spacedRight))
|
|
3544
|
+
return "declared";
|
|
3545
|
+
return spacedRight && lineHeadBefore(text, head.runStart, json) ? "line-key" : "never";
|
|
3546
|
+
}
|
|
3424
3547
|
function schemeValueAt(text, s, json) {
|
|
3425
3548
|
const n = text.length;
|
|
3426
3549
|
let i = s;
|
|
@@ -3504,11 +3627,16 @@ function anchoredValueAt(scan, text, op, json, span, isHead, memo) {
|
|
|
3504
3627
|
case "auth-scheme":
|
|
3505
3628
|
v = schemeValueAt(text, s, json);
|
|
3506
3629
|
break;
|
|
3630
|
+
case "assignment":
|
|
3631
|
+
if (text.charCodeAt(op) !== CH_EQ || head.quotedName || head.spacedLeft || spacedRight)
|
|
3632
|
+
return;
|
|
3633
|
+
v = literalValueAt(text, s, json, "declared", head.listSep, isHead, memo);
|
|
3634
|
+
break;
|
|
3507
3635
|
case "declarative":
|
|
3508
|
-
v = literalValueAt(text, s, json,
|
|
3636
|
+
v = literalValueAt(text, s, json, declarativeBareAt(text, head, spacedRight, json), head.listSep, isHead, memo);
|
|
3509
3637
|
break;
|
|
3510
3638
|
case "any-form":
|
|
3511
|
-
v = literalValueAt(text, s, json,
|
|
3639
|
+
v = literalValueAt(text, s, json, "declared", head.listSep, isHead, memo);
|
|
3512
3640
|
break;
|
|
3513
3641
|
default: {
|
|
3514
3642
|
const unhandled = head.strength;
|
|
@@ -3592,6 +3720,142 @@ function collectAnchoredValueSpans(scan, text, json, span, isHead) {
|
|
|
3592
3720
|
scan.footLo = armLo;
|
|
3593
3721
|
scan.footHi = armHi;
|
|
3594
3722
|
}
|
|
3723
|
+
const isRegexWordCode = (c) => isAsciiAlnumCode(c) || c === CH_UNDERSCORE;
|
|
3724
|
+
const isDiagnosticNameCode = (c) => isRegexWordCode(c) || c === CH_MINUS;
|
|
3725
|
+
const isDiagnosticValueUnit = (ch) => ch !== JSON_STRING_END && !isRegexSpace(ch) && ch !== CH_QUOTE && ch !== CH_APOS && ch !== CH_COMMA && ch !== CH_RBRACE;
|
|
3726
|
+
const isAsciiLetterCode = (ch) => (ch >= 0x41 && ch <= 0x5a) || (ch >= 0x61 && ch <= 0x7a);
|
|
3727
|
+
const isDiagnosticSchemeValueUnit = (ch) => isAsciiAlnumCode(ch) || ch === CH_DOT || ch === CH_UNDERSCORE || ch === CH_TILDE || ch === CH_PLUS || ch === CH_SLASH || ch === CH_EQ || ch === CH_MINUS;
|
|
3728
|
+
function diagnosticNameSlot(tier) {
|
|
3729
|
+
switch (tier) {
|
|
3730
|
+
case "assignment":
|
|
3731
|
+
case "declarative":
|
|
3732
|
+
case "any-form":
|
|
3733
|
+
case "auth-scheme":
|
|
3734
|
+
return true;
|
|
3735
|
+
case "structure-only":
|
|
3736
|
+
return false;
|
|
3737
|
+
default: {
|
|
3738
|
+
const unhandled = tier;
|
|
3739
|
+
throw new Error(`redact: unhandled free-text anchor strength ${String(unhandled)}`);
|
|
3740
|
+
}
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
const DIAGNOSTIC_SCHEME_RE = new RegExp([...STRONG_AUTH_SCHEMES].sort((a, b) => b.length - a.length).join("|"), "gi");
|
|
3744
|
+
let diagnosticScanUnits = 0;
|
|
3745
|
+
export function diagnosticScanUnitsForTest() {
|
|
3746
|
+
return diagnosticScanUnits;
|
|
3747
|
+
}
|
|
3748
|
+
export function resetDiagnosticScanUnitsForTest() {
|
|
3749
|
+
diagnosticScanUnits = 0;
|
|
3750
|
+
}
|
|
3751
|
+
function collectDiagnosticValueSpans(text, json, span, isHead, deletedAt) {
|
|
3752
|
+
const n = text.length;
|
|
3753
|
+
const readRun = (from, isValue) => {
|
|
3754
|
+
let i = from;
|
|
3755
|
+
while (i < n) {
|
|
3756
|
+
const unit = readTextUnit(text, i, json);
|
|
3757
|
+
diagnosticScanUnits += 1;
|
|
3758
|
+
if (!isValue(unitChOf(unit)))
|
|
3759
|
+
break;
|
|
3760
|
+
i += unitLenOf(unit);
|
|
3761
|
+
}
|
|
3762
|
+
return i;
|
|
3763
|
+
};
|
|
3764
|
+
const skipBlank = (from) => readRun(from, isRegexSpace);
|
|
3765
|
+
let valueEnd = 0;
|
|
3766
|
+
let nextEq = text.indexOf("=");
|
|
3767
|
+
let nextColon = text.indexOf(":");
|
|
3768
|
+
while (nextEq >= 0 || nextColon >= 0) {
|
|
3769
|
+
let op;
|
|
3770
|
+
if (nextColon < 0 || (nextEq >= 0 && nextEq < nextColon)) {
|
|
3771
|
+
op = nextEq;
|
|
3772
|
+
nextEq = text.indexOf("=", op + 1);
|
|
3773
|
+
}
|
|
3774
|
+
else {
|
|
3775
|
+
op = nextColon;
|
|
3776
|
+
nextColon = text.indexOf(":", op + 1);
|
|
3777
|
+
}
|
|
3778
|
+
if (op + 1 < valueEnd)
|
|
3779
|
+
continue;
|
|
3780
|
+
let e = op;
|
|
3781
|
+
while (e > 0 && isRegexSpace(text.charCodeAt(e - 1)))
|
|
3782
|
+
e -= 1;
|
|
3783
|
+
diagnosticScanUnits += op - e;
|
|
3784
|
+
if (e === 0 || !isRegexWordCode(text.charCodeAt(e - 1)))
|
|
3785
|
+
continue;
|
|
3786
|
+
const floor = Math.max(0, e - CREDENTIAL_NAME_MAX - 1);
|
|
3787
|
+
let runStart = e;
|
|
3788
|
+
while (runStart > floor && isDiagnosticNameCode(text.charCodeAt(runStart - 1)))
|
|
3789
|
+
runStart -= 1;
|
|
3790
|
+
diagnosticScanUnits += e - runStart;
|
|
3791
|
+
const runOpen = runStart === floor && floor > 0 && isDiagnosticNameCode(text.charCodeAt(floor - 1));
|
|
3792
|
+
let nameStart = -1;
|
|
3793
|
+
let nameTier;
|
|
3794
|
+
for (let q = runStart; q < e && nameStart < 0; q++) {
|
|
3795
|
+
if (e - q > CREDENTIAL_NAME_MAX || !isRegexWordCode(text.charCodeAt(q)))
|
|
3796
|
+
continue;
|
|
3797
|
+
const bounded = (q === runStart && !runOpen) || text.charCodeAt(q - 1) === CH_MINUS || deletedAt(q) !== "none";
|
|
3798
|
+
const tier = bounded ? credentialNameAnchor(text.slice(q, e)) : undefined;
|
|
3799
|
+
if (tier !== undefined && diagnosticNameSlot(tier)) {
|
|
3800
|
+
nameStart = q;
|
|
3801
|
+
nameTier = tier;
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
if (nameStart < 0)
|
|
3805
|
+
continue;
|
|
3806
|
+
let s = skipBlank(op + 1);
|
|
3807
|
+
if (s < n) {
|
|
3808
|
+
const unit = readTextUnit(text, s, json);
|
|
3809
|
+
if (unitChOf(unit) === CH_QUOTE)
|
|
3810
|
+
s += unitLenOf(unit);
|
|
3811
|
+
}
|
|
3812
|
+
if (s >= n) {
|
|
3813
|
+
if (isHead)
|
|
3814
|
+
span(nameStart, n, op, NOT_CLOSED, true);
|
|
3815
|
+
continue;
|
|
3816
|
+
}
|
|
3817
|
+
let end = readRun(s, isDiagnosticValueUnit);
|
|
3818
|
+
if (end > s && nameTier === "auth-scheme" && readRun(s, isAsciiLetterCode) === end) {
|
|
3819
|
+
const k = skipBlank(end);
|
|
3820
|
+
if (k > end && k >= n && isHead) {
|
|
3821
|
+
span(nameStart, n, op, NOT_CLOSED, true);
|
|
3822
|
+
continue;
|
|
3823
|
+
}
|
|
3824
|
+
if (k > end && k < n) {
|
|
3825
|
+
const credEnd = readRun(k, isDiagnosticSchemeValueUnit);
|
|
3826
|
+
if (credEnd > k)
|
|
3827
|
+
end = credEnd;
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
if (end > s) {
|
|
3831
|
+
span(s, end, op, NOT_CLOSED);
|
|
3832
|
+
valueEnd = end;
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
let schemeEnd = 0;
|
|
3836
|
+
DIAGNOSTIC_SCHEME_RE.lastIndex = 0;
|
|
3837
|
+
for (let m = DIAGNOSTIC_SCHEME_RE.exec(text); m !== null; m = DIAGNOSTIC_SCHEME_RE.exec(text)) {
|
|
3838
|
+
const at = m.index;
|
|
3839
|
+
const q = at + m[0].length;
|
|
3840
|
+
if (q < schemeEnd)
|
|
3841
|
+
continue;
|
|
3842
|
+
if (at > 0 && isRegexWordCode(text.charCodeAt(at - 1)) && deletedAt(at) === "none")
|
|
3843
|
+
continue;
|
|
3844
|
+
const k = skipBlank(q);
|
|
3845
|
+
if (k === q && deletedAt(q) !== "blank")
|
|
3846
|
+
continue;
|
|
3847
|
+
if (k >= n) {
|
|
3848
|
+
if (isHead)
|
|
3849
|
+
span(at, n, at, NOT_CLOSED, true);
|
|
3850
|
+
continue;
|
|
3851
|
+
}
|
|
3852
|
+
const end = readRun(k, isDiagnosticSchemeValueUnit);
|
|
3853
|
+
if (end > k) {
|
|
3854
|
+
span(k, end, at, NOT_CLOSED);
|
|
3855
|
+
schemeEnd = end;
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3595
3859
|
export function structuralScannerForTest(arm) {
|
|
3596
3860
|
const collect = (scan) => (text) => {
|
|
3597
3861
|
const out = [];
|
|
@@ -3750,6 +4014,7 @@ const armPool = (() => {
|
|
|
3750
4014
|
order,
|
|
3751
4015
|
phase: 1,
|
|
3752
4016
|
lexical: LEXICAL_KEYWORD_ARMS.has(re),
|
|
4017
|
+
diagnosticOnly: false,
|
|
3753
4018
|
collect: (text, _json, _eat, out, isHead) => {
|
|
3754
4019
|
if (boundary === undefined)
|
|
3755
4020
|
collectRegexSpans(arm, text, out);
|
|
@@ -3769,16 +4034,16 @@ const armPool = (() => {
|
|
|
3769
4034
|
prior: { kind: "bounded", gap: keywordTail === undefined ? NO_GAP : (c) => keywordTail.isSeparator(String.fromCharCode(c)) },
|
|
3770
4035
|
};
|
|
3771
4036
|
};
|
|
3772
|
-
const scannerMember = (token, order, arm, reach, family, prior) => {
|
|
4037
|
+
const scannerMember = (token, order, arm, reach, family, prior, rank = ARM_RANK.structural, lexical = false, diagnosticOnly = false) => {
|
|
3773
4038
|
const repl = spanRepl(token);
|
|
3774
|
-
const rank = ARM_RANK.structural;
|
|
3775
4039
|
return {
|
|
3776
4040
|
token,
|
|
3777
4041
|
rank,
|
|
3778
4042
|
order,
|
|
3779
4043
|
phase: 1,
|
|
3780
|
-
lexical
|
|
3781
|
-
|
|
4044
|
+
lexical,
|
|
4045
|
+
diagnosticOnly,
|
|
4046
|
+
collect: (text, json, eat, out, isHead, deletedAt) => arm(text, json, eat, (start, end, anchor, closeAt, undecided, r = repl) => out.push(undecided === true ? { start, end, repl: r, rank, order, undecided, anchor, closeAt } : { start, end, repl: r, rank, order, anchor, closeAt }), isHead, deletedAt),
|
|
3782
4047
|
retry: undefined,
|
|
3783
4048
|
headSrc: undefined,
|
|
3784
4049
|
headFirst: undefined,
|
|
@@ -3795,6 +4060,7 @@ const armPool = (() => {
|
|
|
3795
4060
|
order,
|
|
3796
4061
|
phase: 2,
|
|
3797
4062
|
lexical,
|
|
4063
|
+
diagnosticOnly: false,
|
|
3798
4064
|
collect: (scan, text, json, eat, out, isHead) => arm(scan, text, json, eat, (start, end, anchor, closeAt, undecided, r = repl) => out.push(undecided === true ? { start, end, repl: r, rank, order, undecided, anchor, closeAt } : { start, end, repl: r, rank, order, anchor, closeAt }), isHead),
|
|
3799
4065
|
retry: undefined,
|
|
3800
4066
|
headSrc: undefined,
|
|
@@ -3822,13 +4088,14 @@ const armPool = (() => {
|
|
|
3822
4088
|
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
4089
|
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
4090
|
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,
|
|
4091
|
+
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, BARE_WORD_MAX + 1, STRONG_AUTH_SCHEME_MAX + 1), "anchor", { kind: "bounded", gap: (c) => isInlineSpaceUnit(c) || isSchemeDelimiterCode(c) }, ARM_RANK.keyword, true));
|
|
3826
4092
|
for (const row of KEYWORD_SECRET_PATTERNS)
|
|
3827
4093
|
members.push(regexMember(row, ARM_RANK.keyword, members.length));
|
|
3828
4094
|
for (const row of SHAPE_SECRET_PATTERNS)
|
|
3829
4095
|
members.push(regexMember(row, ARM_RANK.shape, members.length));
|
|
3830
4096
|
for (const row of FRAGMENT_SECRET_PATTERNS)
|
|
3831
4097
|
members.push(regexMember(row, ARM_RANK.fragment, members.length));
|
|
4098
|
+
members.push(scannerMember(ANCHORED_VALUE_TOKEN, members.length, (text, json, _eat, span, isHead, deletedAt) => collectDiagnosticValueSpans(text, json, span, isHead, deletedAt), Math.max(CREDENTIAL_NAME_MAX, STRONG_AUTH_SCHEME_MAX) + 2, "prose", { kind: "bounded", gap: isRegexSpace }, ARM_RANK.keyword, true, true));
|
|
3832
4099
|
for (const [re] of KEYWORD_SECRET_PATTERNS) {
|
|
3833
4100
|
if (!LEXICAL_KEYWORD_ARMS.has(re))
|
|
3834
4101
|
throw new Error(`redact: keyword arm /${re.source}/ is not registered as lexical — build it with keywordArm() so the bounded-unit scope can exclude it`);
|
|
@@ -3840,8 +4107,9 @@ const armPool = (() => {
|
|
|
3840
4107
|
const laneOf = (scope) => {
|
|
3841
4108
|
const inScope = (m) => {
|
|
3842
4109
|
switch (scope) {
|
|
3843
|
-
case "free-text": return
|
|
3844
|
-
case "bounded-unit": return !m.lexical;
|
|
4110
|
+
case "free-text": return !m.diagnosticOnly;
|
|
4111
|
+
case "bounded-unit": return !m.lexical && !m.diagnosticOnly;
|
|
4112
|
+
case "diagnostic": return true;
|
|
3845
4113
|
}
|
|
3846
4114
|
};
|
|
3847
4115
|
return {
|
|
@@ -3853,13 +4121,14 @@ const armPool = (() => {
|
|
|
3853
4121
|
const LANES = {
|
|
3854
4122
|
"free-text": laneOf("free-text"),
|
|
3855
4123
|
"bounded-unit": laneOf("bounded-unit"),
|
|
4124
|
+
diagnostic: laneOf("diagnostic"),
|
|
3856
4125
|
};
|
|
3857
4126
|
const headScreen = new RegExp(`(?:${retryMembers.map((m) => m.headSrc).join("|")})`, "y");
|
|
3858
4127
|
const headFirstUnit = unionMembers(retryMembers.map((m) => m.headFirst)) ?? new Uint32Array(0x10000 >>> 5).fill(0xffffffff);
|
|
3859
4128
|
poolArmCount = members.length;
|
|
3860
4129
|
poolBoundaryArmCount = retryMembers.length;
|
|
3861
4130
|
const reaches = members.map((m) => ({ token: m.token, order: m.order, reach: m.reach }));
|
|
3862
|
-
const run = (text, wantCount, json, eat, scope, reach, engineMarked) => {
|
|
4131
|
+
const run = (text, wantCount, json, eat, scope, reach, engineMarked, deletedAt) => {
|
|
3863
4132
|
readings += 1;
|
|
3864
4133
|
const isHead = reach !== undefined;
|
|
3865
4134
|
const lane = LANES[scope];
|
|
@@ -3914,7 +4183,7 @@ const armPool = (() => {
|
|
|
3914
4183
|
}
|
|
3915
4184
|
};
|
|
3916
4185
|
for (const m of lane.phase1)
|
|
3917
|
-
m.collect(text, json, eat, spans, isHead);
|
|
4186
|
+
m.collect(text, json, eat, spans, isHead, deletedAt);
|
|
3918
4187
|
closeCoveragePositions(0);
|
|
3919
4188
|
if (lane.phase2.length > 0) {
|
|
3920
4189
|
const scan = buildForensicScan(tokenUnits(text), buildEvidenceRows(text), lane.phase2.length);
|
|
@@ -3999,8 +4268,8 @@ let onRedaction;
|
|
|
3999
4268
|
export function setRedactionObserver(fn) {
|
|
4000
4269
|
onRedaction = fn;
|
|
4001
4270
|
}
|
|
4002
|
-
function applyRules(text, wantCount, json, eat, scope, reach, engineMarked) {
|
|
4003
|
-
return armPool(text, wantCount, json, eat, scope, reach, engineMarked);
|
|
4271
|
+
function applyRules(text, wantCount, json, eat, scope, reach, engineMarked, deletedAt) {
|
|
4272
|
+
return armPool(text, wantCount, json, eat, scope, reach, engineMarked, deletedAt);
|
|
4004
4273
|
}
|
|
4005
4274
|
function reportHits(hits) {
|
|
4006
4275
|
if (onRedaction === undefined)
|
|
@@ -4072,7 +4341,19 @@ function runRedaction(text, observe, json, wantHits, scope, layout, extent, obse
|
|
|
4072
4341
|
const toOriginal = createViewToOriginal(layers);
|
|
4073
4342
|
const reach = extent.kind === "head" ? (viewStart) => toOriginal.start(viewStart) < extent.emitEnd : undefined;
|
|
4074
4343
|
const engineMarked = (viewStart, viewEnd, repl) => isEngineMarkedCandidate(text, toOriginal.start(viewStart), toOriginal.start(viewEnd - 1) + 1, repl);
|
|
4075
|
-
const
|
|
4344
|
+
const deletedAt = (viewIndex) => {
|
|
4345
|
+
if (viewIndex <= 0 || viewIndex > view.length)
|
|
4346
|
+
return "none";
|
|
4347
|
+
const lo = toOriginal.start(viewIndex - 1) + 1;
|
|
4348
|
+
const hi = viewIndex === view.length ? text.length : toOriginal.start(viewIndex);
|
|
4349
|
+
if (hi <= lo)
|
|
4350
|
+
return "none";
|
|
4351
|
+
for (let k = lo; k < hi; k++)
|
|
4352
|
+
if (isRegexSpace(text.charCodeAt(k)))
|
|
4353
|
+
return "blank";
|
|
4354
|
+
return "invisible";
|
|
4355
|
+
};
|
|
4356
|
+
const r = applyRules(view, wantCount, json, eat, scope, reach, engineMarked, deletedAt);
|
|
4076
4357
|
forgetEscapedSeparatorTails();
|
|
4077
4358
|
readsSoFar += 1;
|
|
4078
4359
|
if (readsSoFar === 1) {
|
|
@@ -4154,7 +4435,7 @@ export function redactSecretsWithArms(text, opts) {
|
|
|
4154
4435
|
return { text: r.text, arms: new Set(r.hits.map((h) => h.arm)) };
|
|
4155
4436
|
}
|
|
4156
4437
|
export function redactionSpansForTest(text, opts) {
|
|
4157
|
-
const r = runRedaction(text, false, opts?.json === true, false, "free-text", "multi-line", WHOLE_EXTENT);
|
|
4438
|
+
const r = runRedaction(text, false, opts?.json === true, false, opts?.scope ?? "free-text", "multi-line", WHOLE_EXTENT);
|
|
4158
4439
|
return { text: r.text, spans: r.spans.map((sp) => ({ start: sp.start, end: sp.end })) };
|
|
4159
4440
|
}
|
|
4160
4441
|
export function proposeRedactionSpans(text, scope, layout, extent) {
|