@sema-agent/server 7.107.0 → 7.109.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 +72 -1
- package/USAGE.md +51 -25
- package/dist/approval-ask-audit-store.d.ts +62 -4
- package/dist/approval-ask-audit-store.js +67 -11
- package/dist/approval-ask-machine.d.ts +9 -25
- package/dist/approval-ask-machine.js +5 -2
- package/dist/approval-card.d.ts +32 -3
- package/dist/approval-card.js +29 -2
- package/dist/approval.js +16 -13
- package/dist/bench/s1/live-deps.d.ts +4 -5
- package/dist/bench/s1/live-deps.js +9 -10
- package/dist/boot/coordinators.d.ts +4 -0
- package/dist/boot/coordinators.js +3 -2
- package/dist/boot/leader.js +0 -2
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +3 -8
- package/dist/boot/shutdown.d.ts +8 -0
- package/dist/boot/shutdown.js +31 -8
- package/dist/boot/stage-06-runners.d.ts +1 -0
- package/dist/boot/stage-06-runners.js +6 -3
- package/dist/boot/stage-07-capability-layer.d.ts +1 -0
- package/dist/boot/stage-08-reapers.d.ts +1 -0
- package/dist/boot/stage-09-leader.d.ts +1 -0
- package/dist/boot/stage-10-http-server.d.ts +1 -0
- package/dist/boot/stage-10-http-server.js +3 -1
- package/dist/brain.js +2 -1
- package/dist/capabilities/scenarios.d.ts +3 -2
- package/dist/config-catalog.js +1 -3
- package/dist/config-center/apply-effective.js +2 -0
- package/dist/config-center/types.d.ts +7 -0
- package/dist/config-provider.js +1 -0
- package/dist/config-types.d.ts +2 -9
- package/dist/config.js +2 -5
- package/dist/deployment-governance.js +2 -1
- package/dist/fleet-client.d.ts +10 -2
- package/dist/fleet-client.js +14 -8
- package/dist/http/admission.js +8 -2
- package/dist/http/memory-compliance-failure-reply.d.ts +41 -0
- package/dist/http/memory-compliance-failure-reply.js +73 -0
- package/dist/http/memory-store-refusal-reply.d.ts +2 -2
- package/dist/http/resume-legs.js +3 -2
- package/dist/http/route-ctx.d.ts +3 -3
- package/dist/http/routes/capabilities.js +1 -0
- package/dist/http/routes/diagnostics.js +2 -0
- package/dist/http/routes/memory-compliance.js +2 -34
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/sessions.js +3 -11
- package/dist/http/routes/side-query.js +7 -2
- package/dist/http/routes/tasks.js +2 -1
- package/dist/http/server.d.ts +2 -2
- package/dist/http/wire-types.d.ts +8 -0
- package/dist/leader/diffup.d.ts +53 -0
- package/dist/leader/diffup.js +95 -1
- package/dist/leader/leader.d.ts +0 -6
- package/dist/leader/leader.js +1 -1
- package/dist/leader/repair-wire.js +1 -1
- package/dist/leader/wire.d.ts +3 -10
- package/dist/leader/wire.js +39 -13
- package/dist/memory-store-refusal.d.ts +2 -1
- package/dist/model-entry-headers.d.ts +41 -0
- package/dist/model-entry-headers.js +61 -0
- package/dist/model-entry-refusal.d.ts +6 -0
- package/dist/model-entry-refusal.js +4 -0
- package/dist/model-reach-scope.d.ts +55 -0
- package/dist/model-reach-scope.js +16 -0
- package/dist/model-unreachable-notice.d.ts +38 -0
- package/dist/model-unreachable-notice.js +72 -0
- package/dist/observability/fail-open.d.ts +5 -5
- package/dist/observability/fail-open.js +5 -5
- package/dist/observability/run-terminal.d.ts +2 -1
- package/dist/outbound-dispatcher.d.ts +69 -0
- package/dist/outbound-dispatcher.js +123 -3
- package/dist/plugins/approval-ask-store-file.d.ts +2 -1
- package/dist/plugins/approval-ask-store-file.js +3 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
- package/dist/plugins/approval-ask-store-memory.js +7 -1
- package/dist/plugins/approval-ask-store-sql.d.ts +18 -0
- package/dist/plugins/approval-ask-store-sql.js +7 -0
- package/dist/plugins/park-commit-watch.d.ts +48 -0
- package/dist/plugins/park-commit-watch.js +87 -0
- package/dist/request-key-closure.js +1 -1
- package/dist/router/route-orchestration.js +7 -2
- package/dist/run-local.js +2 -3
- package/dist/runs.js +3 -2
- package/dist/runtime-governance.d.ts +3 -3
- package/dist/runtime-governance.js +3 -2
- package/dist/task-settings.js +4 -2
- package/dist/tool-approval.d.ts +99 -15
- package/dist/tool-approval.js +75 -10
- package/dist/tool-rule-names.d.ts +25 -0
- package/dist/tool-rule-names.js +5 -0
- package/dist/trace/core-keyset-guard.d.ts +14 -2
- package/dist/trace/engine-notice-wire.d.ts +3 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/project.d.ts +3 -1
- package/dist/trace/project.js +2 -3
- package/dist/trace/self-minted-wire.d.ts +71 -0
- package/dist/trace/self-minted-wire.js +28 -0
- package/dist/unattended-permission-mode.d.ts +54 -93
- package/dist/unattended-permission-mode.js +8 -61
- package/package.json +3 -3
package/dist/tool-approval.js
CHANGED
|
@@ -8,7 +8,7 @@ import { approvalPayloadFingerprint } from "./plugins/approval-payload-fingerpri
|
|
|
8
8
|
import { createLogger } from "./observability/logger.js";
|
|
9
9
|
import { recordFailOpen } from "./observability/fail-open.js";
|
|
10
10
|
import { deriveAskId, deriveAskScopedBatchId, deriveBatchId, MAX_DECISION_NOTE_CHARS } from "./approval-ask-machine.js";
|
|
11
|
-
import { ApprovalCardEnvelopeSchema, MAX_RULE_OFFERS, buildApprovalCard, buildApprovalCardEnvelope, buildApprovalRequestFrame, buildRevokeFrame, readDenialLimitFallback, readProbeCause, readReadRootCandidate, readRuleEvidence, readRuleOffersAbsence, readRuleOffersAbsenceSeat, readParkRowTrueSeat, readClosedWordSeat, RuleOfferRawSchema, backfillLegacyBatchMemberKind, screenUncoveredDetailSeat, } from "./approval-card.js";
|
|
11
|
+
import { ApprovalCardEnvelopeSchema, MAX_RULE_OFFERS, buildApprovalCard, buildApprovalCardEnvelope, buildApprovalRequestFrame, buildRevokeFrame, readDenialLimitFallback, readProbeCause, readReadRootCandidate, readRuleEvidence, readRuleOffersAbsence, readRuleOffersAbsenceSeat, readParkRowTrueSeat, readAskClassPair, readClosedWordSeat, RuleOfferRawSchema, backfillLegacyBatchMemberKind, screenUncoveredDetailSeat, } from "./approval-card.js";
|
|
12
12
|
import { MAX_SETTLED_BY_CHARS, POLICY_REFUSAL_DECISION, projectAskTerminalClaimTruth, settledByFitsColumn } from "./plugins/approval-ask-store-sql.js";
|
|
13
13
|
import { settleByPolicy } from "./approval-policy-settlement.js";
|
|
14
14
|
import { governanceAskMarksFor, runWithGovernanceAskScope } from "./governance-ask-marks.js";
|
|
@@ -26,6 +26,8 @@ const SUSPENDED_POLL_MAX_PER_TICK = 64;
|
|
|
26
26
|
const SUSPENDED_POLL_BUDGET_MS = 5_000;
|
|
27
27
|
const EDITED_DECISION_MARK_CAP_MS = 10_000;
|
|
28
28
|
const DEFAULT_WINDOW_MARGIN_MS = 10_000;
|
|
29
|
+
const SHUTDOWN_DRAIN_POLL_MS = 50;
|
|
30
|
+
const SHUTDOWN_BEFORE_PARK = "shutdown_before_park";
|
|
29
31
|
const MAX_ALLOW_SESSIONS = 4096;
|
|
30
32
|
const DEFAULT_ADMIT_MAX_PER_TASK = 32;
|
|
31
33
|
const DEFAULT_ADMIT_MAX_PER_OWNER = 256;
|
|
@@ -364,6 +366,10 @@ export class ToolApprovalCoordinator {
|
|
|
364
366
|
parkedRedeem;
|
|
365
367
|
askAudit;
|
|
366
368
|
sessionGrants;
|
|
369
|
+
shutdownDraining = false;
|
|
370
|
+
asksInFlight = 0;
|
|
371
|
+
parkCommits;
|
|
372
|
+
parksAwaitingCommit = new Set();
|
|
367
373
|
constructor(opts) {
|
|
368
374
|
this.ruleConsent = opts?.ruleConsent;
|
|
369
375
|
this.ruleScopeRootFor = opts?.ruleScopeRootFor;
|
|
@@ -381,6 +387,8 @@ export class ToolApprovalCoordinator {
|
|
|
381
387
|
this.parkTombstonePerPrincipalMax = opts?.parkTombstonePerPrincipalMax ?? DEFAULT_PARK_TOMBSTONE_PER_PRINCIPAL_MAX;
|
|
382
388
|
this.askAudit = opts?.askAudit;
|
|
383
389
|
this.sessionGrants = opts?.sessionGrants;
|
|
390
|
+
this.parkCommits = opts?.parkCommits;
|
|
391
|
+
this.parkCommits?.onParkCommitted((calls) => this.noteParkCommitted(calls));
|
|
384
392
|
}
|
|
385
393
|
unattendedOutcome(site) {
|
|
386
394
|
let outcome;
|
|
@@ -644,6 +652,34 @@ export class ToolApprovalCoordinator {
|
|
|
644
652
|
}
|
|
645
653
|
return n;
|
|
646
654
|
}
|
|
655
|
+
async drainForShutdown(deadlineMs) {
|
|
656
|
+
this.shutdownDraining = true;
|
|
657
|
+
for (const e of [...this.pending.values()])
|
|
658
|
+
if (e.settledOutcome === undefined)
|
|
659
|
+
e.forceParkNow();
|
|
660
|
+
while ((this.asksInFlight > 0 || this.pending.size > 0 || this.streams.size > 0 || this.parksAwaitingCommit.size > 0) && Date.now() < deadlineMs) {
|
|
661
|
+
await new Promise((r) => setTimeout(r, SHUTDOWN_DRAIN_POLL_MS));
|
|
662
|
+
}
|
|
663
|
+
await this.parkCommits?.quiesce(deadlineMs);
|
|
664
|
+
this.askAudit?.noteLegsInterruptedByShutdown();
|
|
665
|
+
return { uncommittedParks: [...this.parksAwaitingCommit].map((p) => ({ approvalId: p.approvalId, taskId: p.taskId })) };
|
|
666
|
+
}
|
|
667
|
+
noteParkCommitted(calls) {
|
|
668
|
+
this.settleParksAwaitingCommit((p) => p.executingSessionId === calls.sessionId && calls.toolCallIds.includes(p.toolCallId), "park-committed");
|
|
669
|
+
}
|
|
670
|
+
settleParksAwaitingCommit(match, site) {
|
|
671
|
+
for (const p of [...this.parksAwaitingCommit]) {
|
|
672
|
+
if (!match(p))
|
|
673
|
+
continue;
|
|
674
|
+
this.parksAwaitingCommit.delete(p);
|
|
675
|
+
try {
|
|
676
|
+
this.askAudit?.recordSettle(p.settleRecord());
|
|
677
|
+
}
|
|
678
|
+
catch (err) {
|
|
679
|
+
recordFailOpen("server.approval-ask-audit.append-failed", `kind=settle site=${site} err=${err instanceof Error ? err.message : String(err)}`);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
647
683
|
admittedCount(taskId) {
|
|
648
684
|
return this.admitByTask.get(taskId) ?? 0;
|
|
649
685
|
}
|
|
@@ -740,14 +776,13 @@ export class ToolApprovalCoordinator {
|
|
|
740
776
|
async sessionGrantUncontestedByRow(origin, req) {
|
|
741
777
|
if (!this.askStore)
|
|
742
778
|
return true;
|
|
743
|
-
const
|
|
744
|
-
const askId = deriveAskId(sourceTaskId, origin.taskId, req.toolCallId, origin.legKey, req.delegation?.parentToolCallId);
|
|
779
|
+
const call = { taskId: origin.taskId, legKey: origin.legKey, toolCallId: req.toolCallId, sourceTaskId: req.sourceTaskId ?? origin.taskId };
|
|
745
780
|
try {
|
|
746
|
-
const
|
|
747
|
-
return
|
|
781
|
+
const rows = await this.withStoreDeadline(this.askStore.listByCall(call), "listByCall(session-grant-provenance)", DURABLE_CONVERGE_READ_TIMEOUT_MS);
|
|
782
|
+
return rows.length === 0;
|
|
748
783
|
}
|
|
749
784
|
catch (err) {
|
|
750
|
-
this.noteStoreError(err, "
|
|
785
|
+
this.noteStoreError(err, "listByCall(session-grant-provenance)");
|
|
751
786
|
return false;
|
|
752
787
|
}
|
|
753
788
|
}
|
|
@@ -950,6 +985,7 @@ export class ToolApprovalCoordinator {
|
|
|
950
985
|
if (p.targetCtxs?.has(ctx))
|
|
951
986
|
p.onTargetGone?.(ctx);
|
|
952
987
|
}
|
|
988
|
+
this.settleParksAwaitingCommit((p) => p.carrierLeg === ctx, "leg-closed");
|
|
953
989
|
this.askAudit?.noteLegClosed(ctx.taskId);
|
|
954
990
|
}
|
|
955
991
|
}));
|
|
@@ -983,6 +1019,15 @@ export class ToolApprovalCoordinator {
|
|
|
983
1019
|
};
|
|
984
1020
|
};
|
|
985
1021
|
async askBroadcast(origin, ctxs, req, signal) {
|
|
1022
|
+
this.asksInFlight++;
|
|
1023
|
+
try {
|
|
1024
|
+
return await this.askBroadcastCounted(origin, ctxs, req, signal);
|
|
1025
|
+
}
|
|
1026
|
+
finally {
|
|
1027
|
+
this.asksInFlight--;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
async askBroadcastCounted(origin, ctxs, req, signal) {
|
|
986
1031
|
if (signal?.aborted)
|
|
987
1032
|
return false;
|
|
988
1033
|
const governanceForced = this.governanceForcedOf(origin, req);
|
|
@@ -1008,11 +1053,13 @@ export class ToolApprovalCoordinator {
|
|
|
1008
1053
|
}
|
|
1009
1054
|
const id = uuidv7();
|
|
1010
1055
|
const child = isChildAsk(req);
|
|
1056
|
+
const carrierLeg = child ? undefined : aliveCtxs.find((c) => c.taskId === origin.taskId);
|
|
1011
1057
|
const bounded = boundArgs(req.args);
|
|
1012
1058
|
let effectiveGovernanceForced = governanceForced;
|
|
1013
1059
|
let ruleLaneMaterial = this.buildRuleLaneMaterial(req, origin.owner, governanceForced, origin.sessionId);
|
|
1014
1060
|
const mandateWord = readClosedWordSeat(req, "mandate");
|
|
1015
1061
|
const originWord = typeof req.origin === "string" && req.origin.length > 0 ? req.origin : undefined;
|
|
1062
|
+
const askClassPair = readAskClassPair(req);
|
|
1016
1063
|
const frame = {
|
|
1017
1064
|
type: "tool_approval",
|
|
1018
1065
|
approvalId: id,
|
|
@@ -1040,6 +1087,7 @@ export class ToolApprovalCoordinator {
|
|
|
1040
1087
|
...(req.mandated === true ? { mandated: true } : {}),
|
|
1041
1088
|
...(mandateWord !== undefined ? { mandate: mandateWord } : {}),
|
|
1042
1089
|
...(originWord !== undefined ? { origin: originWord } : {}),
|
|
1090
|
+
...(askClassPair ?? {}),
|
|
1043
1091
|
...(typeof req.persistedRuleShadowed === "string" && req.persistedRuleShadowed !== ""
|
|
1044
1092
|
? { persistedRuleShadowed: redactSecrets(req.persistedRuleShadowed).slice(0, MAX_RULE_TEXT_CHARS) }
|
|
1045
1093
|
: {}),
|
|
@@ -1091,7 +1139,7 @@ export class ToolApprovalCoordinator {
|
|
|
1091
1139
|
const sourceTaskId = req.sourceTaskId ?? origin.taskId;
|
|
1092
1140
|
const runId = origin.taskId;
|
|
1093
1141
|
const legKey = origin.legKey;
|
|
1094
|
-
askId = deriveAskId(sourceTaskId, runId,
|
|
1142
|
+
askId = deriveAskId(sourceTaskId, runId, legKey, req);
|
|
1095
1143
|
batchId = this.batchIdFor(askId, sourceTaskId, runId, legKey);
|
|
1096
1144
|
try {
|
|
1097
1145
|
const existingOrCreated = await this.withStoreDeadline(this.askStore.ensureAsk({
|
|
@@ -1282,13 +1330,28 @@ export class ToolApprovalCoordinator {
|
|
|
1282
1330
|
releaseAdmission();
|
|
1283
1331
|
if (selfEntry)
|
|
1284
1332
|
selfEntry.settledOutcome = outcome;
|
|
1285
|
-
this.
|
|
1333
|
+
const shutdownEnded = this.shutdownDraining && outcome === "expired";
|
|
1334
|
+
const settleRecord = () => ({
|
|
1286
1335
|
approvalId: wireApprovalId,
|
|
1287
1336
|
outcome,
|
|
1288
1337
|
...(windowRouteUnavailable ? { parkRouted: true } : {}),
|
|
1289
1338
|
...(hostSettledBy !== undefined ? { settledBy: hostSettledBy } : {}),
|
|
1339
|
+
...(shutdownEnded ? { cause: SHUTDOWN_BEFORE_PARK } : {}),
|
|
1290
1340
|
settledAtMs: Date.now(),
|
|
1291
1341
|
});
|
|
1342
|
+
if (shutdownEnded && windowRouteUnavailable && this.unattendedRoutesToPark && this.parkCommits !== undefined) {
|
|
1343
|
+
this.parksAwaitingCommit.add({
|
|
1344
|
+
approvalId: wireApprovalId,
|
|
1345
|
+
taskId: origin.taskId,
|
|
1346
|
+
carrierLeg,
|
|
1347
|
+
executingSessionId: req.sourceTaskId,
|
|
1348
|
+
toolCallId: req.toolCallId,
|
|
1349
|
+
settleRecord,
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
else {
|
|
1353
|
+
this.askAudit?.recordSettle(settleRecord());
|
|
1354
|
+
}
|
|
1292
1355
|
resolveAllowed({ allowed, ...(allowed && updatedInput !== undefined ? { updatedInput } : {}), ...(allowed && readRootGrant !== undefined ? { readRootGrant } : {}) });
|
|
1293
1356
|
};
|
|
1294
1357
|
const broadcastClaimTruth = (read) => {
|
|
@@ -1471,7 +1534,7 @@ export class ToolApprovalCoordinator {
|
|
|
1471
1534
|
if (done)
|
|
1472
1535
|
return;
|
|
1473
1536
|
if (!this.askStore || askId === undefined || batchId === undefined) {
|
|
1474
|
-
settleParkRouteIfUnsettled();
|
|
1537
|
+
settleParkRouteIfUnsettled(undefined);
|
|
1475
1538
|
return;
|
|
1476
1539
|
}
|
|
1477
1540
|
windowExpired(undefined);
|
|
@@ -1586,10 +1649,12 @@ export class ToolApprovalCoordinator {
|
|
|
1586
1649
|
owner: origin.owner,
|
|
1587
1650
|
toolName: req.toolName,
|
|
1588
1651
|
toolCallId: req.toolCallId,
|
|
1589
|
-
legTracked:
|
|
1652
|
+
legTracked: carrierLeg !== undefined,
|
|
1590
1653
|
expiresAtMs: persistedExpiresAtMs,
|
|
1591
1654
|
mintedAtMs: Date.now(),
|
|
1592
1655
|
});
|
|
1656
|
+
if (this.shutdownDraining)
|
|
1657
|
+
forceParkNow();
|
|
1593
1658
|
const cardFrame = askId !== undefined && cardForFrame !== undefined
|
|
1594
1659
|
? buildApprovalRequestFrame({ askId, taskId: origin.taskId, approvalId: wireApprovalId, card: cardForFrame, expiresAtMs: persistedExpiresAtMs, nowMs: Date.now() })
|
|
1595
1660
|
: undefined;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S-919(安全轴,八病审计 SG H2-a)—— 本仓**收紧方向**按引擎工具名匹配的策略臂的**唯一**名字读法。
|
|
3
|
+
*
|
|
4
|
+
* ## 规则(一条,与 core 7.36.0 [ref] `NAME_READINGS` 同判)
|
|
5
|
+
* 一个调用可以答好几个名字:嵌入方工具声明别名(`MyShell{aliases:["Bash"]}`)后,模型按哪个名调它、它的 wire 名、
|
|
6
|
+
* 解到同一行的其余别名,都是这次调用的名字。core 把**收紧**方向的名单(`policy.nameLists` / `policy.shellToolsList` /
|
|
7
|
+
* `policy.durableQuestion` / `policy.sensitivePathGuardedByName`)读成 `any` —— 调用答得上的**任何**一个名字在名单里就算
|
|
8
|
+
* 命中;**授权 / 路由**方向的座(会话放行、审批卡分型、停车行)读 `wire`(`req.toolName`)。core 给宿主的读法端口是包根
|
|
9
|
+
* `ruleNamesOf(req)`(`dist/core/tool-name-readings.js`,亲读实现:`face.names` 含调用名时取它,否则只有调用名;拼写在先)。
|
|
10
|
+
*
|
|
11
|
+
* 本仓照此分两边:
|
|
12
|
+
* · **收紧臂**(`APPROVAL_DENY` / `APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO`、commandPolicy 的 ask 表、治理 shell 标、
|
|
13
|
+
* durable 问题门、supervisor 危险门、workflow 问 / 拒)一律经本函数读全集;
|
|
14
|
+
* · **授权 / 路由臂**(会话豁免探针、会话放行键、审批卡分型、停车行的 AskUserQuestion 判别)读 `req.toolName`,不经这里 ——
|
|
15
|
+
* 用户对 `Bash` 说过的「本会话不再询问」不许替一只叫 `MyShell` 的工具放行(放宽臂不因别名放宽)。
|
|
16
|
+
*
|
|
17
|
+
* 修前(≤7.107.0)本仓自写的这些臂只比 `req.toolName`:模型按别名调嵌入方工具时,运维名单一个都不拦(core 同族策略判 deny、
|
|
18
|
+
* 本仓判 allow)。本仓自身不声明带别名的工具,所以只有经 `resolveSpec` 席挂别名工具的嵌入方走得到。
|
|
19
|
+
*
|
|
20
|
+
* 返回**命中的那个名字**(调用答得上的名字里第一个被规则够到的,拼写在先)—— 规则归因(`matchedAskRule`)写运维名单里的那个名,
|
|
21
|
+
* 不写一个名单里查不到的 wire 名;够不到 ⇒ `undefined`。判定式(精确集 / covering 规则)由调用方给,本函数只管「读哪些名字」。
|
|
22
|
+
*/
|
|
23
|
+
import { type ToolCallRequest } from "@sema-agent/core";
|
|
24
|
+
export declare function heldRuleName(req: Pick<ToolCallRequest, "toolName" | "face">, holds: (name: string) => boolean): string | undefined;
|
|
25
|
+
//# sourceMappingURL=tool-rule-names.d.ts.map
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* ⑨⑩([ref],2026-08-31)把两个最大的 wire 面也纳入:TaskSpec 按「server 有无写点」记 Wired/Unwired,
|
|
18
18
|
* TaskResult 按「转发/摘除」记 Forwarded/Stripped —— 谁改 resolve-spec.ts / runs.ts 的发射点谁同步本文件。
|
|
19
19
|
*/
|
|
20
|
-
import type { TaskNotificationPayload, SemaProvenance, BackgroundChildEvent, RosterEntry, AskRequest, CheckpointSummary, PendingAction, TaskEvent, TraceEvent, MailboxMessage, MailboxAppendMessage, TaskSpec, TaskResult, WiringManifest, GateOutcome, GateDisposition, Settlement, PausedCause, WorkflowRun, ReadRootGrantCandidate, McpReconnectResult, McpServerStatus, NodeLspManagerOptions, RunnerDeps } from "@sema-agent/core";
|
|
20
|
+
import type { TaskNotificationPayload, SemaProvenance, BackgroundChildEvent, RosterEntry, AskRequest, CheckpointSummary, PendingAction, TaskEvent, TraceEvent, MailboxMessage, MailboxAppendMessage, TaskSpec, TaskResult, SideQueryResult, WiringManifest, GateOutcome, GateDisposition, Settlement, PausedCause, WorkflowRun, ReadRootGrantCandidate, McpReconnectResult, McpServerStatus, NodeLspManagerOptions, RunnerDeps } from "@sema-agent/core";
|
|
21
21
|
import type { ToolApprovalFrame } from "../tool-approval.js";
|
|
22
22
|
/** 编译期断言:T 必须收敛到 never(有残余键 = tsc 红)。
|
|
23
23
|
* 🔴 **导出**([ref] U1/U2):本仓「词表闭集,未处置成员=编译红」的钉法只许有**一个**形 ——
|
|
@@ -43,7 +43,7 @@ type _GuardBgNotifReverse = AssertAllKeysHandled<Exclude<BgNotifProjected | BgNo
|
|
|
43
43
|
type RosterProjected = "name" | "agentId" | "sessionId" | "toolUseId" | "owner" | "scope" | "sessionScoped" | "rootSessionId" | "model" | "modelFallback" | "createdAt";
|
|
44
44
|
type _GuardRoster = AssertAllKeysHandled<Exclude<keyof RosterEntry, RosterProjected>>;
|
|
45
45
|
type _GuardRosterReverse = AssertAllKeysHandled<Exclude<RosterProjected, keyof RosterEntry>>;
|
|
46
|
-
type AskProjected = "toolName" | "toolCallId" | "args" | "message" | "sourceTaskId" | "fromSubagent" | "sourceAgentName" | "delegation" | "ruleOffers" | "ruleOffersAbsence" | "persistedRuleShadowed" | "probeCause" | "ruleEvidence" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "readRootCandidate" | "mandated" | "mandate";
|
|
46
|
+
type AskProjected = "toolName" | "toolCallId" | "args" | "message" | "sourceTaskId" | "fromSubagent" | "sourceAgentName" | "delegation" | "ruleOffers" | "ruleOffersAbsence" | "persistedRuleShadowed" | "probeCause" | "ruleEvidence" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "readRootCandidate" | "mandated" | "mandate" | "askClass" | "classes";
|
|
47
47
|
type AskExcluded = "preview" | "principal" | "riskAxes" | "boundInputHash" | "isDelegatedChild" | "probeReason" | "hasBidiControls" | "previewWithheld" | "execCwd" | "authoredBy";
|
|
48
48
|
type _GuardAsk = AssertAllKeysHandled<Exclude<keyof AskRequest, AskProjected | AskExcluded>>;
|
|
49
49
|
type _GuardAskReverse = AssertAllKeysHandled<Exclude<AskProjected | AskExcluded, keyof AskRequest>>;
|
|
@@ -157,6 +157,14 @@ type PausedCauseForwarded = "kind" | "gate" | "checkpointId" | "restoreMode";
|
|
|
157
157
|
type PausedCauseStripped = "token";
|
|
158
158
|
type _GuardPausedCause = AssertAllKeysHandled<Exclude<keyof PausedCause, PausedCauseForwarded | PausedCauseStripped>>;
|
|
159
159
|
type _GuardPausedCauseReverse = AssertAllKeysHandled<Exclude<PausedCauseForwarded | PausedCauseStripped, keyof PausedCause>>;
|
|
160
|
+
type SideQueryResultForwarded = "text" | "toolCalls" | "model" | "servedModel" | "degraded" | "responseModel" | "usage" | "usageMissing" | "stopReason" | "errorMessage";
|
|
161
|
+
type SideQueryResultStripped = never;
|
|
162
|
+
type _GuardSideQueryResult = AssertAllKeysHandled<Exclude<keyof SideQueryResult, SideQueryResultForwarded | SideQueryResultStripped>>;
|
|
163
|
+
type _GuardSideQueryResultReverse = AssertAllKeysHandled<Exclude<SideQueryResultForwarded | SideQueryResultStripped, keyof SideQueryResult>>;
|
|
164
|
+
type SideQueryToolCallForwarded = "id" | "wireId" | "name" | "args";
|
|
165
|
+
type SideQueryToolCallStripped = never;
|
|
166
|
+
type _GuardSideQueryToolCall = AssertAllKeysHandled<Exclude<keyof SideQueryResult["toolCalls"][number], SideQueryToolCallForwarded | SideQueryToolCallStripped>>;
|
|
167
|
+
type _GuardSideQueryToolCallReverse = AssertAllKeysHandled<Exclude<SideQueryToolCallForwarded | SideQueryToolCallStripped, keyof SideQueryResult["toolCalls"][number]>>;
|
|
160
168
|
type SettlementKeys = Settlement extends infer S ? (S extends object ? keyof S : never) : never;
|
|
161
169
|
type SettlementWhoKeys = Settlement["who"] extends infer W ? (W extends object ? keyof W : never) : never;
|
|
162
170
|
type GateOutcomeProjected = "disposition" | "settlement" | "origin";
|
|
@@ -289,6 +297,10 @@ export type CoreKeysetGuards = [
|
|
|
289
297
|
_GuardTaskResultReverse,
|
|
290
298
|
_GuardPausedCause,
|
|
291
299
|
_GuardPausedCauseReverse,
|
|
300
|
+
_GuardSideQueryResult,
|
|
301
|
+
_GuardSideQueryResultReverse,
|
|
302
|
+
_GuardSideQueryToolCall,
|
|
303
|
+
_GuardSideQueryToolCallReverse,
|
|
292
304
|
_GuardGateOutcome,
|
|
293
305
|
_GuardGateOutcomeReverse,
|
|
294
306
|
_GuardGateDisposition,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* 同文件 G1 e2e 的全码扇出夹具、以及契约文档附录 D.3 那张表(含**小节标题里的码数** —— 那道门本批
|
|
17
17
|
* 刚立,立完就在下一次加码时自己咬住了)。
|
|
18
18
|
*/
|
|
19
|
-
export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable", "task.interrupt_unconsumed", "approval.read_root_granted", "approval.read_root_grant_rejected", "instructions.source_changed", "session.records_skipped", "classifier.unavailable", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable"];
|
|
19
|
+
export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable", "task.interrupt_unconsumed", "approval.read_root_granted", "approval.read_root_grant_rejected", "instructions.source_changed", "session.records_skipped", "server.model_unreachable", "classifier.unavailable", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable"];
|
|
20
20
|
export type EngineNoticeWireCode = (typeof ENGINE_NOTICE_WIRE_CODES)[number];
|
|
21
21
|
/**
|
|
22
22
|
* S-690 —— **本仓自铸**的通告码与它们的受众(码 / 铸点 / 受众三者的属主都是本仓)。
|
|
@@ -42,6 +42,8 @@ export declare const SERVER_NOTICE_AUDIENCE: {
|
|
|
42
42
|
readonly "memory.layer_locked_legacy": "operator";
|
|
43
43
|
/** S-612 —— 会话存档部分记录被跳过(唯一铸点 `src/session-records-skipped-notice.ts`);受众 user,理由见白名单键注。 */
|
|
44
44
|
readonly "session.records_skipped": "user";
|
|
45
|
+
/** S-925 —— 模型调用因建连失败终态(唯一铸点 `src/model-unreachable-notice.ts`);受众 user,理由见白名单键注。 */
|
|
46
|
+
readonly "server.model_unreachable": "user";
|
|
45
47
|
};
|
|
46
48
|
export type ServerNoticeCode = keyof typeof SERVER_NOTICE_AUDIENCE;
|
|
47
49
|
/** 该码是否本仓自铸(属主判据单点:门与投递面都读这一个)。 */
|
|
@@ -27,6 +27,7 @@ export const ENGINE_NOTICE_WIRE_CODES = [
|
|
|
27
27
|
"approval.read_root_grant_rejected",
|
|
28
28
|
"instructions.source_changed",
|
|
29
29
|
"session.records_skipped",
|
|
30
|
+
"server.model_unreachable",
|
|
30
31
|
"classifier.unavailable",
|
|
31
32
|
"config.permission_mode_unavailable",
|
|
32
33
|
"permission.ask_released_by_mode",
|
|
@@ -37,6 +38,7 @@ export const SERVER_NOTICE_AUDIENCE = {
|
|
|
37
38
|
"instructions.source_changed": "user",
|
|
38
39
|
"memory.layer_locked_legacy": "operator",
|
|
39
40
|
"session.records_skipped": "user",
|
|
41
|
+
"server.model_unreachable": "user",
|
|
40
42
|
};
|
|
41
43
|
export function isServerNoticeCode(code) {
|
|
42
44
|
return Object.hasOwn(SERVER_NOTICE_AUDIENCE, code);
|
package/dist/trace/project.d.ts
CHANGED
|
@@ -298,7 +298,9 @@ export declare function toolEndEventData(ev: {
|
|
|
298
298
|
* ## 信任划线
|
|
299
299
|
* · `toolCallId` / `toolName` —— 调用 id(🔴 S-283 订正:出身是**服务商**在 tool_use / tool_calls 里给的,引擎缺席时自铸兜底、越界时折叠 ——
|
|
300
300
|
* 此前写「引擎铸」不实)与名册里的工具名(与 `tool_start` 逐字同源)⇒ verbatim。调用 id 这一族的形状在**全部面的共同入口**一次施加 ——
|
|
301
|
-
* core 7.36.0(#1207)brain 建调用那一行的准入(在形原样 / 越界单射折叠,原字节只在转录 `ToolCall.wireId`)
|
|
301
|
+
* core 7.36.0(#1207)brain 建调用那一行的准入(在形原样 / 越界单射折叠,原字节只在转录 `ToolCall.wireId`),一方 brain 新铸的调用在逐帧面上
|
|
302
|
+
* 恒是在形的引擎 id(残余两条 S-921:≤7.106.0 写下的存量行 resume 出来的帧是服务商原串逐字;宿主 Brain 不准入 KL-1207-a —— 详见
|
|
303
|
+
* run-terminal `admitProviderEcho` 顶注);
|
|
302
304
|
* 本仓不设第二道闸(见 run-terminal `admitProviderEcho` 顶注;S-890 关)。
|
|
303
305
|
* · `elapsedTimeSeconds` —— 引擎铸的整秒,单调、一 call 一个原点 ⇒ 有限数才铸键。
|
|
304
306
|
* · `output` —— 🔴 **UNTRUSTED RAW**,core 逐字「exactly as `tool_end.output`: process output that may
|
package/dist/trace/project.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { admitProviderEcho, redactErrorMessage, redactModelText } from "../observability/run-terminal.js";
|
|
2
|
-
import { isAskClass, isAskOrigin, isPermissionMode, isPersistedRuleMandate, MCP_DELIVERY_VERDICTS, MCP_LIVENESS_STATES, screenGateOutcome, TEAM_ROLES, ToolRoster, ToolRosterDelta, WRITE_PROTECTION_TARGET_VIEWS } from "@sema-agent/core";
|
|
2
|
+
import { isAskClass, isAskOrigin, isModeReleaseReason, isPermissionMode, isPersistedRuleMandate, MCP_DELIVERY_VERDICTS, MCP_LIVENESS_STATES, screenGateOutcome, TEAM_ROLES, ToolRoster, ToolRosterDelta, WRITE_PROTECTION_TARGET_VIEWS } from "@sema-agent/core";
|
|
3
3
|
import { Value } from "typebox/value";
|
|
4
4
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
5
5
|
import { redactSecrets, redactDeep } from "./redact.js";
|
|
@@ -126,11 +126,10 @@ function modeLedgerDefect(d) {
|
|
|
126
126
|
return "disposition.released.origin is outside the closed set";
|
|
127
127
|
if (o.mandate !== undefined && !isPersistedRuleMandate(o.mandate))
|
|
128
128
|
return "disposition.released.mandate is outside the closed set";
|
|
129
|
-
if (o.reason !== undefined && !(
|
|
129
|
+
if (o.reason !== undefined && !isModeReleaseReason(o.reason))
|
|
130
130
|
return "disposition.released.reason is outside the closed set";
|
|
131
131
|
return false;
|
|
132
132
|
}
|
|
133
|
-
const RELEASE_REASON_WORDS = { rule_unreadable: true };
|
|
134
133
|
function screenedGateOrThrow(v) {
|
|
135
134
|
if (v === null || typeof v !== "object") {
|
|
136
135
|
if (v !== undefined)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** 一个自铸 wire 值成员的登记。 */
|
|
2
|
+
export interface SelfMintedWireMember {
|
|
3
|
+
readonly attr: string | number;
|
|
4
|
+
readonly since: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const SELF_MINTED_WIRE: {
|
|
7
|
+
/** [ref](7.55.0)起的终态成因注;S-929(7.108.0)+`shutdown_before_park`。 */
|
|
8
|
+
readonly crashConvergedCause: {
|
|
9
|
+
readonly at: "GET /v1/approvals crashConverged[].cause";
|
|
10
|
+
readonly members: {
|
|
11
|
+
crashed_before_park: {
|
|
12
|
+
attr: string;
|
|
13
|
+
since: string;
|
|
14
|
+
};
|
|
15
|
+
shutdown_before_park: {
|
|
16
|
+
attr: string;
|
|
17
|
+
since: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 会话所有者自助抹除面的**已分类拒** → HTTP 状态(S-930 起与 operator 面 `POST /v1/memory/erase` 同一只映射;`since` 记的是**本面**
|
|
23
|
+
* 自哪一版起这样答 —— 7.107.0 及以前本面只认前两只,其余落 500 `internal.error`)。
|
|
24
|
+
*/
|
|
25
|
+
readonly sessionMemoryEraseStatus: {
|
|
26
|
+
readonly at: "POST /v1/sessions/:id/memory/erase(已分类拒 errorCode → HTTP 状态)";
|
|
27
|
+
readonly members: {
|
|
28
|
+
readonly "config.memory_erasure_request": {
|
|
29
|
+
readonly attr: 400;
|
|
30
|
+
readonly since: "7.52.0";
|
|
31
|
+
};
|
|
32
|
+
readonly "memory.target_outside_store": {
|
|
33
|
+
readonly attr: 409;
|
|
34
|
+
readonly since: "7.101.0";
|
|
35
|
+
};
|
|
36
|
+
readonly "memory.erasure_evidence_unavailable": {
|
|
37
|
+
readonly attr: 409;
|
|
38
|
+
readonly since: "7.108.0";
|
|
39
|
+
};
|
|
40
|
+
readonly "memory.erasure_selector_mismatch": {
|
|
41
|
+
readonly attr: 409;
|
|
42
|
+
readonly since: "7.108.0";
|
|
43
|
+
};
|
|
44
|
+
readonly "memory.erasure_census_incomplete": {
|
|
45
|
+
readonly attr: 409;
|
|
46
|
+
readonly since: "7.108.0";
|
|
47
|
+
};
|
|
48
|
+
readonly "internal.memory_control_plane_corrupt": {
|
|
49
|
+
readonly attr: 500;
|
|
50
|
+
readonly since: "7.108.0";
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/** 本仓在出口对 core 值做的变换(值变、键不变)。 */
|
|
55
|
+
readonly wireValueRule: {
|
|
56
|
+
readonly at: "出口值变换(<端点>#<键> → 变换)";
|
|
57
|
+
readonly members: {
|
|
58
|
+
/** S-105(7.57.0):run 读面的终态错误文案脱敏(钉 test/run-failure-visibility.test.ts)。 */
|
|
59
|
+
readonly "GET /v1/runs/:id#result.errorMessage": {
|
|
60
|
+
readonly attr: "redactErrorMessage";
|
|
61
|
+
readonly since: "7.57.0";
|
|
62
|
+
};
|
|
63
|
+
/** S-922(7.108.0):side-query 200 体 `errorMessage` 与任务面同一只脱敏口(钉 test/side-query-provider-echo.test.ts)。 */
|
|
64
|
+
readonly "POST /v1/side-query#errorMessage": {
|
|
65
|
+
readonly attr: "redactErrorMessage";
|
|
66
|
+
readonly since: "7.108.0";
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=self-minted-wire.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const SELF_MINTED_WIRE = {
|
|
2
|
+
crashConvergedCause: {
|
|
3
|
+
at: "GET /v1/approvals crashConverged[].cause",
|
|
4
|
+
members: {
|
|
5
|
+
crashed_before_park: { attr: "-", since: "7.55.0" },
|
|
6
|
+
shutdown_before_park: { attr: "-", since: "7.108.0" },
|
|
7
|
+
},
|
|
8
|
+
},
|
|
9
|
+
sessionMemoryEraseStatus: {
|
|
10
|
+
at: "POST /v1/sessions/:id/memory/erase(已分类拒 errorCode → HTTP 状态)",
|
|
11
|
+
members: {
|
|
12
|
+
"config.memory_erasure_request": { attr: 400, since: "7.52.0" },
|
|
13
|
+
"memory.target_outside_store": { attr: 409, since: "7.101.0" },
|
|
14
|
+
"memory.erasure_evidence_unavailable": { attr: 409, since: "7.108.0" },
|
|
15
|
+
"memory.erasure_selector_mismatch": { attr: 409, since: "7.108.0" },
|
|
16
|
+
"memory.erasure_census_incomplete": { attr: 409, since: "7.108.0" },
|
|
17
|
+
"internal.memory_control_plane_corrupt": { attr: 500, since: "7.108.0" },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
wireValueRule: {
|
|
21
|
+
at: "出口值变换(<端点>#<键> → 变换)",
|
|
22
|
+
members: {
|
|
23
|
+
"GET /v1/runs/:id#result.errorMessage": { attr: "redactErrorMessage", since: "7.57.0" },
|
|
24
|
+
"POST /v1/side-query#errorMessage": { attr: "redactErrorMessage", since: "7.108.0" },
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=self-minted-wire.js.map
|