@sema-agent/server 7.69.0 → 7.71.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.
Files changed (107) hide show
  1. package/README.md +4 -1
  2. package/README.zh-CN.md +4 -1
  3. package/USAGE.md +109 -10
  4. package/dist/approval-ask-machine.d.ts +1 -1
  5. package/dist/approval-card.d.ts +3 -2
  6. package/dist/approval-content-kind.d.ts +13 -7
  7. package/dist/approval-content-kind.js +3 -1
  8. package/dist/approval-reconciler.d.ts +0 -54
  9. package/dist/approval-reconciler.js +2 -2
  10. package/dist/approval.js +3 -2
  11. package/dist/bench/s1/live-deps.js +2 -0
  12. package/dist/boot/execution-env.js +12 -2
  13. package/dist/boot/memory-consolidation.d.ts +2 -1
  14. package/dist/boot/parked-revive-gate.d.ts +2 -0
  15. package/dist/boot/parked-revive-gate.js +15 -10
  16. package/dist/boot/resolve-spec.js +8 -3
  17. package/dist/boot/runner-deps.d.ts +50 -46
  18. package/dist/boot/runner-deps.js +12 -10
  19. package/dist/brain.d.ts +3 -1
  20. package/dist/brain.js +2 -1
  21. package/dist/budget.js +3 -2
  22. package/dist/config-catalog.d.ts +31 -2
  23. package/dist/config-catalog.js +44 -24
  24. package/dist/config-types.d.ts +31 -1
  25. package/dist/config-types.js +1 -0
  26. package/dist/config.js +15 -3
  27. package/dist/deployment-governance.d.ts +6 -3
  28. package/dist/deployment-governance.js +2 -1
  29. package/dist/execution-lane-caps.d.ts +51 -37
  30. package/dist/execution-lane-caps.js +23 -0
  31. package/dist/fleet/fleet-bus.d.ts +22 -1
  32. package/dist/fleet/fleet-bus.js +2 -1
  33. package/dist/http/routes/approvals-assistant.js +3 -12
  34. package/dist/http/routes/diagnostics.js +4 -0
  35. package/dist/http/routes/runs.js +2 -3
  36. package/dist/http/routes/tasks.js +22 -18
  37. package/dist/http/server.js +21 -7
  38. package/dist/index.d.ts +1 -1
  39. package/dist/leader/wire.js +4 -3
  40. package/dist/main.js +6 -4
  41. package/dist/memory-operator-faces.d.ts +1 -1
  42. package/dist/memory-scope.d.ts +24 -0
  43. package/dist/memory-scope.js +12 -3
  44. package/dist/observability/metrics.d.ts +4 -6
  45. package/dist/observability/metrics.js +5 -1
  46. package/dist/observability/permission-rule-events.d.ts +20 -0
  47. package/dist/observability/permission-rule-events.js +28 -0
  48. package/dist/observability/run-terminal-log.d.ts +13 -22
  49. package/dist/observability/run-terminal-log.js +187 -47
  50. package/dist/observability/tool-trace.d.ts +12 -0
  51. package/dist/observability/tool-trace.js +5 -1
  52. package/dist/orchestration/workflow-agent-session-index.d.ts +85 -2
  53. package/dist/orchestration/workflow-agent-session-index.js +38 -5
  54. package/dist/parked-decide.d.ts +40 -1
  55. package/dist/parked-decide.js +19 -2
  56. package/dist/plugins/checkpoint-store-sql.js +5 -5
  57. package/dist/plugins/local-checkpoint-store.js +3 -3
  58. package/dist/plugins/remote-env-adb.d.ts +11 -0
  59. package/dist/plugins/remote-env-adb.js +2 -0
  60. package/dist/plugins/remote-env-device.d.ts +9 -0
  61. package/dist/plugins/remote-env-device.js +3 -0
  62. package/dist/plugins/remote-env-e2b.d.ts +11 -0
  63. package/dist/plugins/remote-env-e2b.js +2 -0
  64. package/dist/plugins/remote-env-host.d.ts +11 -0
  65. package/dist/plugins/remote-env-host.js +2 -0
  66. package/dist/plugins/remote-env-k8s.d.ts +11 -0
  67. package/dist/plugins/remote-env-k8s.js +2 -0
  68. package/dist/plugins/remote-env-local-docker.d.ts +11 -0
  69. package/dist/plugins/remote-env-local-docker.js +2 -0
  70. package/dist/plugins/remote-env-ssh.d.ts +11 -0
  71. package/dist/plugins/remote-env-ssh.js +2 -0
  72. package/dist/plugins/store-backend.d.ts +36 -13
  73. package/dist/plugins/store-backend.js +12 -3
  74. package/dist/plugins/store-contracts.d.ts +54 -18
  75. package/dist/plugins/store-contracts.js +17 -30
  76. package/dist/plugins/workflow-journal-store-sql.d.ts +1 -1
  77. package/dist/plugins/workflow-journal-store-sql.js +3 -10
  78. package/dist/plugins/workflow-run-store-sql.d.ts +31 -9
  79. package/dist/plugins/workflow-run-store-sql.js +28 -1
  80. package/dist/posture-source.d.ts +23 -3
  81. package/dist/posture-source.js +1 -1
  82. package/dist/read-face-posture.d.ts +8 -1
  83. package/dist/read-face-posture.js +1 -0
  84. package/dist/run-cancel-context.d.ts +50 -1
  85. package/dist/run-cancel-context.js +22 -0
  86. package/dist/run-local.d.ts +14 -6
  87. package/dist/run-local.js +4 -1
  88. package/dist/runs.d.ts +0 -51
  89. package/dist/runs.js +40 -25
  90. package/dist/task-a2a.js +2 -2
  91. package/dist/task-mcp.js +2 -2
  92. package/dist/task-settings.d.ts +21 -8
  93. package/dist/task-settings.js +2 -2
  94. package/dist/tool-approval.d.ts +14 -8
  95. package/dist/tool-approval.js +3 -3
  96. package/dist/trace/core-keyset-guard.d.ts +135 -11
  97. package/dist/trace/engine-notice-wire.d.ts +1 -1
  98. package/dist/trace/engine-notice-wire.js +1 -0
  99. package/dist/trace/ledger-events.d.ts +22 -2
  100. package/dist/trace/ledger-events.js +6 -1
  101. package/dist/trace/ledger-sink.d.ts +10 -8
  102. package/dist/trace/ledger-sink.js +10 -2
  103. package/dist/trace/project.d.ts +24 -6
  104. package/dist/trace/project.js +5 -3
  105. package/dist/trace/redact.d.ts +28 -0
  106. package/dist/trace/redact.js +58 -30
  107. package/package.json +3 -3
@@ -17,28 +17,100 @@
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, BackgroundChildEvent, RosterEntry, AskRequest, CheckpointSummary, TaskEvent, TraceEvent, MailboxMessage, MailboxAppendMessage, TaskSpec, TaskResult, GateOutcome, Settlement, PausedCause } from "@sema-agent/core";
21
- /** 编译期断言:T 必须收敛到 never(有残余键 = tsc 红)。 */
22
- type AssertAllKeysHandled<T extends never> = T;
20
+ import type { TaskNotificationPayload, SemaProvenance, BackgroundChildEvent, RosterEntry, AskRequest, CheckpointSummary, TaskEvent, TraceEvent, MailboxMessage, MailboxAppendMessage, TaskSpec, TaskResult, WiringManifest, GateOutcome, Settlement, PausedCause } from "@sema-agent/core";
21
+ import type { ToolApprovalFrame } from "../tool-approval.js";
22
+ /** 编译期断言:T 必须收敛到 never(有残余键 = tsc 红)。
23
+ * 🔴 **导出**([ref] U1/U2):本仓「词表闭集,未处置成员=编译红」的钉法只许有**一个**形 ——
24
+ * `observability/run-terminal-log.ts` 的三张叶表 + 结果顶层键表用同一只断言,而不是各自再抄一份
25
+ * `type X<T extends never> = T`(抄一份就是第二个写者,两处哪天分岔谁都发现不了)。
26
+ * 本文件只有类型、不产 JS,所以被 `import type` 引用不新增任何运行期边。 */
27
+ export type AssertAllKeysHandled<T extends never> = T;
23
28
  type NotificationProjected = "task_id" | "task_type" | "toolUseId" | "status" | "summary" | "result" | "output_file" | "usage" | "sessionId" | "seq" | "lines" | "stoppedBy" | "source" | "exitCode" | "partial" | "diagnostics" | "recentSteps" | "editedFiles" | "resumable" | "completionId" | "error" | "errorCode" | "apiFailure" | "agentMessage" | "_sema_provenance";
24
29
  type NotificationExcluded = "peer" | "crossSessionMessage" | "crossSessionNotice";
25
30
  type _GuardNotification = AssertAllKeysHandled<Exclude<keyof TaskNotificationPayload, NotificationProjected | NotificationExcluded>>;
31
+ type _GuardNotificationReverse = AssertAllKeysHandled<Exclude<NotificationProjected | NotificationExcluded, keyof TaskNotificationPayload>>;
32
+ type ProvenanceProjected = "kind" | "from" | "taskId" | "seq" | "agentType";
33
+ type ProvenanceExcluded = "peerMeta";
34
+ type _GuardProvenance = AssertAllKeysHandled<Exclude<keyof SemaProvenance, ProvenanceProjected | ProvenanceExcluded>>;
35
+ type _GuardProvenanceReverse = AssertAllKeysHandled<Exclude<ProvenanceProjected | ProvenanceExcluded, keyof SemaProvenance>>;
36
+ type AgentMessageProjected = "from" | "body";
37
+ type _GuardAgentMessage = AssertAllKeysHandled<Exclude<keyof NonNullable<TaskNotificationPayload["agentMessage"]>, AgentMessageProjected>>;
38
+ type _GuardAgentMessageReverse = AssertAllKeysHandled<Exclude<AgentMessageProjected, keyof NonNullable<TaskNotificationPayload["agentMessage"]>>>;
26
39
  type BgNotifProjected = "taskId" | "sessionId" | "seq" | "status" | "summary" | "stoppedBy" | "resumable" | "recentSteps" | "editedFiles" | "usage" | "transcriptId" | "rootSessionId" | "parentTaskId" | "parentToolCallId" | "completionId";
27
40
  type BgNotifExcluded = "kind" | "sessionScoped" | "owner" | "scope" | "description" | "agentType" | "name" | "currentAction" | "currentTool" | "parentSessionId" | "startedAt" | "workflowRunId" | "progressTaskId" | "progressParentTaskId" | "model";
28
41
  type _GuardBgNotif = AssertAllKeysHandled<Exclude<keyof BackgroundChildEvent, BgNotifProjected | BgNotifExcluded>>;
42
+ type _GuardBgNotifReverse = AssertAllKeysHandled<Exclude<BgNotifProjected | BgNotifExcluded, keyof BackgroundChildEvent>>;
29
43
  type RosterProjected = "name" | "agentId" | "sessionId" | "toolUseId" | "owner" | "scope" | "sessionScoped" | "rootSessionId" | "model" | "modelFallback" | "createdAt";
30
44
  type _GuardRoster = AssertAllKeysHandled<Exclude<keyof RosterEntry, RosterProjected>>;
45
+ type _GuardRosterReverse = AssertAllKeysHandled<Exclude<RosterProjected, keyof RosterEntry>>;
31
46
  type AskProjected = "toolName" | "toolCallId" | "args" | "message" | "sourceTaskId" | "fromSubagent" | "sourceAgentName" | "delegation" | "ruleOffers" | "ruleOffersAbsence" | "persistedRuleShadowed" | "probeCause" | "ruleEvidence" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "classifierUnavailable";
32
47
  type AskExcluded = "preview" | "principal" | "riskAxes" | "boundInputHash" | "isDelegatedChild" | "probeReason" | "hasBidiControls" | "previewWithheld" | "execCwd";
33
48
  type _GuardAsk = AssertAllKeysHandled<Exclude<keyof AskRequest, AskProjected | AskExcluded>>;
49
+ type _GuardAskReverse = AssertAllKeysHandled<Exclude<AskProjected | AskExcluded, keyof AskRequest>>;
50
+ type AskFrameServerMinted = "type" | "approvalId" | "argsOmitted" | "outcome" | "governanceForced" | "expiresAtMs" | "expiresInMs" | "serverNowMs" | "parked" | "inputHasBidi";
51
+ type _GuardAskFrame = AssertAllKeysHandled<Exclude<keyof ToolApprovalFrame, AskProjected | AskFrameServerMinted>>;
52
+ type _GuardAskFrameReverse = AssertAllKeysHandled<Exclude<AskProjected | AskFrameServerMinted, keyof ToolApprovalFrame>>;
34
53
  type TaskEventHandled = "text_delta" | "reasoning_delta" | "tool_start" | "tool_end" | "turn_end" | "compacted" | "diagnostics" | "message_committed" | "status" | "task_notification" | "task_progress" | "steering_injected" | "workspace_changed" | "done" | "context_usage" | "compaction_outcome" | "human_input" | "wiring_manifest" | "text_end" | "tool_roster_delta";
35
54
  type _GuardTaskEvent = AssertAllKeysHandled<Exclude<TaskEvent["type"], TaskEventHandled>>;
55
+ type _GuardTaskEventReverse = AssertAllKeysHandled<Exclude<TaskEventHandled, TaskEvent["type"]>>;
36
56
  type MailboxProjected = "seq" | "from" | "content" | "sentAt" | "hopChain" | "peerMeta";
37
57
  type _GuardMailbox = AssertAllKeysHandled<Exclude<keyof MailboxMessage, MailboxProjected>>;
58
+ type _GuardMailboxReverse = AssertAllKeysHandled<Exclude<MailboxProjected, keyof MailboxMessage>>;
38
59
  type MailboxAppendProjected = "from" | "content" | "sentAt" | "hopChain" | "peerMeta";
39
60
  type _GuardMailboxAppend = AssertAllKeysHandled<Exclude<keyof MailboxAppendMessage, MailboxAppendProjected>>;
61
+ type _GuardMailboxAppendReverse = AssertAllKeysHandled<Exclude<MailboxAppendProjected, keyof MailboxAppendMessage>>;
62
+ type WiringSectionProjected = "schemaVersion" | "leg" | "ask" | "question" | "interaction" | "elicit" | "parkLane" | "session" | "fleet" | "permissionRules" | "modelGate" | "autoMode" | "mcp" | "tools";
63
+ type WiringSectionExcluded = "governance" | "configFingerprint";
64
+ type _GuardWiringSections = AssertAllKeysHandled<Exclude<keyof WiringManifest, WiringSectionProjected | WiringSectionExcluded>>;
65
+ type _GuardWiringSectionsReverse = AssertAllKeysHandled<Exclude<WiringSectionProjected | WiringSectionExcluded, keyof WiringManifest>>;
66
+ type WiringSection<K extends keyof WiringManifest> = NonNullable<WiringManifest[K]>;
67
+ type WiringLegHandled = "kind";
68
+ type _GuardWiringLeg = AssertAllKeysHandled<Exclude<keyof WiringSection<"leg">, WiringLegHandled>>;
69
+ type _GuardWiringLegReverse = AssertAllKeysHandled<Exclude<WiringLegHandled, keyof WiringSection<"leg">>>;
70
+ type WiringAskHandled = "form" | "provenance" | "effective";
71
+ type _GuardWiringAsk = AssertAllKeysHandled<Exclude<keyof WiringSection<"ask">, WiringAskHandled>>;
72
+ type _GuardWiringAskReverse = AssertAllKeysHandled<Exclude<WiringAskHandled, keyof WiringSection<"ask">>>;
73
+ type WiringQuestionHandled = "wired" | "provenance" | "interactiveToolsWithoutDeliveryFace";
74
+ type _GuardWiringQuestion = AssertAllKeysHandled<Exclude<keyof WiringSection<"question">, WiringQuestionHandled>>;
75
+ type _GuardWiringQuestionReverse = AssertAllKeysHandled<Exclude<WiringQuestionHandled, keyof WiringSection<"question">>>;
76
+ type WiringInteractionHandled = "posture";
77
+ type _GuardWiringInteraction = AssertAllKeysHandled<Exclude<keyof WiringSection<"interaction">, WiringInteractionHandled>>;
78
+ type _GuardWiringInteractionReverse = AssertAllKeysHandled<Exclude<WiringInteractionHandled, keyof WiringSection<"interaction">>>;
79
+ type WiringElicitHandled = "seamWired" | "serversOptedIn";
80
+ type _GuardWiringElicit = AssertAllKeysHandled<Exclude<keyof WiringSection<"elicit">, WiringElicitHandled>>;
81
+ type _GuardWiringElicitReverse = AssertAllKeysHandled<Exclude<WiringElicitHandled, keyof WiringSection<"elicit">>>;
82
+ type WiringParkLaneHandled = "capable" | "effective" | "reasons" | "checkpointDurability";
83
+ type _GuardWiringParkLane = AssertAllKeysHandled<Exclude<keyof WiringSection<"parkLane">, WiringParkLaneHandled>>;
84
+ type _GuardWiringParkLaneReverse = AssertAllKeysHandled<Exclude<WiringParkLaneHandled, keyof WiringSection<"parkLane">>>;
85
+ type WiringSessionHandled = "store";
86
+ type _GuardWiringSession = AssertAllKeysHandled<Exclude<keyof WiringSection<"session">, WiringSessionHandled>>;
87
+ type _GuardWiringSessionReverse = AssertAllKeysHandled<Exclude<WiringSessionHandled, keyof WiringSection<"session">>>;
88
+ type WiringToolsHandled = "schemaVersion" | "count" | "entries" | "digest";
89
+ type _GuardWiringTools = AssertAllKeysHandled<Exclude<keyof WiringSection<"tools">, WiringToolsHandled>>;
90
+ type _GuardWiringToolsReverse = AssertAllKeysHandled<Exclude<WiringToolsHandled, keyof WiringSection<"tools">>>;
91
+ type FleetExcluded = "subagentTranscripts";
92
+ type WiringFleetHandled = "backgroundAgentStore" | "hostChildEventSink" | FleetExcluded;
93
+ type _GuardWiringFleet = AssertAllKeysHandled<Exclude<keyof WiringSection<"fleet">, WiringFleetHandled>>;
94
+ type _GuardWiringFleetReverse = AssertAllKeysHandled<Exclude<WiringFleetHandled, keyof WiringSection<"fleet">>>;
95
+ type WiringMcpEntry = WiringSection<"mcp">[number];
96
+ type WiringMcpExcluded = "error";
97
+ type WiringMcpHandled = "name" | "source" | "status" | "errorCode" | "delivered" | "httpStatus" | "toolCount" | WiringMcpExcluded;
98
+ type _GuardWiringMcp = AssertAllKeysHandled<Exclude<keyof WiringMcpEntry, WiringMcpHandled>>;
99
+ type _GuardWiringMcpReverse = AssertAllKeysHandled<Exclude<WiringMcpHandled, keyof WiringMcpEntry>>;
100
+ type WiringRulesHandled = "storeWired" | "syncWired" | "orgGoverned";
101
+ type _GuardWiringRules = AssertAllKeysHandled<Exclude<keyof WiringSection<"permissionRules">, WiringRulesHandled>>;
102
+ type _GuardWiringRulesReverse = AssertAllKeysHandled<Exclude<WiringRulesHandled, keyof WiringSection<"permissionRules">>>;
103
+ type WiringModelGateHandled = "class" | "removed" | "restore";
104
+ type _GuardWiringModelGate = AssertAllKeysHandled<Exclude<keyof WiringSection<"modelGate">, WiringModelGateHandled>>;
105
+ type _GuardWiringModelGateReverse = AssertAllKeysHandled<Exclude<WiringModelGateHandled, keyof WiringSection<"modelGate">>>;
106
+ type WiringAutoModeHandled = "armed" | "reason";
107
+ type _GuardWiringAutoMode = AssertAllKeysHandled<Exclude<keyof WiringSection<"autoMode">, WiringAutoModeHandled>>;
108
+ type _GuardWiringAutoModeReverse = AssertAllKeysHandled<Exclude<WiringAutoModeHandled, keyof WiringSection<"autoMode">>>;
109
+ type WiringGovernanceHandled = "audience" | "lockedConfig" | "compliance" | "memoryAdmission" | "retention";
110
+ type _GuardWiringGovernance = AssertAllKeysHandled<Exclude<keyof WiringSection<"governance">, WiringGovernanceHandled>>;
111
+ type _GuardWiringGovernanceReverse = AssertAllKeysHandled<Exclude<WiringGovernanceHandled, keyof WiringSection<"governance">>>;
40
112
  type PermissionTraceKind = Extract<TraceEvent["kind"], `permission.${string}`>;
41
- type PermissionTraceProjected = "permission.persisted_rule_allowed" | "permission.rule_store_unreadable" | "permission.read_only_allowed";
113
+ export type PermissionTraceProjected = "permission.persisted_rule_allowed" | "permission.rule_store_unreadable" | "permission.read_only_allowed";
42
114
  type PermissionTraceDropped = "permission.sandbox_admitted" | "permission.rule_sync_resurrected" | "permission.rule_sync_dropped" | "permission.org_snapshot_unavailable";
43
115
  type _GuardPermissionTrace = AssertAllKeysHandled<Exclude<PermissionTraceKind, PermissionTraceProjected | PermissionTraceDropped>>;
44
116
  type _GuardPermissionTraceReverse = AssertAllKeysHandled<Exclude<PermissionTraceProjected | PermissionTraceDropped, PermissionTraceKind>>;
@@ -48,6 +120,7 @@ type _GuardPermissionTraceNonEmpty = AssertAllKeysHandled<AssertNonEmpty<Permiss
48
120
  type SummaryProjected = "sessionId" | "scope" | "createdAt" | "gateKind" | "severity" | "spentMicroUsd" | "deadline" | "hasBidiControls" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "classifierUnavailable";
49
121
  type SummaryExcluded = "token" | "toolInput" | "toolName" | "toolCallId" | "preview" | "principal" | "sourceTaskId" | "contentKind" | "restoreMode" | "checkpointId" | "previewWithheld";
50
122
  type _GuardInboxSummary = AssertAllKeysHandled<Exclude<keyof CheckpointSummary, SummaryProjected | SummaryExcluded>>;
123
+ type _GuardInboxSummaryReverse = AssertAllKeysHandled<Exclude<SummaryProjected | SummaryExcluded, keyof CheckpointSummary>>;
51
124
  type TaskSpecWired = "objective" | "principal" | "images" | "sessionId" | "requireExistingSession" | "oneShot" | "clientContext" | "resumeAt" | "resumeAtMode" | "model" | "compactionModel" | "thinking" | "systemPrompt" | "appendSystemPrompt" | "promptProvider" | "memory" | "suggestNextPrompts" | "restoreFiles" | "acceptPartialRestore" | "rewindFilesTo" | "tools" | "excludeTools" | "deferTools" | "toolMaterializeStrategy" | "promptProfile" | "toolPolicy" | "onAsk" | "onQuestion" | "hooks" | "durableApproval" | "resourceSuspend" | "resilience" | "finalVerification" | "checkpointStore" | "handsReadOnly" | "memoryPersistenceCapable" | "additionalDirectories" | "additionalReadDirectories" | "enablePlanMode" | "interactiveTools" | "enableFork" | "shellGate" | "mcp" | "a2a" | "skills" | "backgroundScope" | "envFacts" | "limits" | "configOverrides" | "forwardSubagentEvents" | "retainSubagentSessions" | "retainBackgroundProcesses" | "outputSchema" | "outputRetries" | "compaction" | "attachments" | "selfOrchestration" | "getApiKeyAndHeaders" | "interactionPosture" | "agents" | "taskId" | "signal" | "preemptSignal" | "modelRole" | "enableBlockedReport" | "maxSuspends" | "autoModeRequested";
52
125
  type TaskSpecUnwired = "excludeAllTools" | "actor" | "roles" | "lspManager" | "tracer" | "readFace" | "readDenyPatterns" | "interactiveQuestionFallback" | "alwaysLoadTools" | "restoreGatedTools" | "deferSelfResolve" | "basePolicyForResumeEdit" | "lspDiagnostics" | "streamingToolExecution" | "toolResultThresholdChars";
53
126
  type _GuardTaskSpec = AssertAllKeysHandled<Exclude<keyof TaskSpec, TaskSpecWired | TaskSpecUnwired>>;
@@ -59,35 +132,86 @@ type _GuardTaskResultReverse = AssertAllKeysHandled<Exclude<TaskResultForwarded
59
132
  type PausedCauseForwarded = "kind" | "gate" | "checkpointId" | "restoreMode";
60
133
  type PausedCauseStripped = "token";
61
134
  type _GuardPausedCause = AssertAllKeysHandled<Exclude<keyof PausedCause, PausedCauseForwarded | PausedCauseStripped>>;
62
- type _NoDoubleBookPausedCause = AssertAllKeysHandled<Extract<PausedCauseForwarded, PausedCauseStripped>>;
63
135
  type _GuardPausedCauseReverse = AssertAllKeysHandled<Exclude<PausedCauseForwarded | PausedCauseStripped, keyof PausedCause>>;
64
136
  type SettlementKeys = Settlement extends infer S ? (S extends object ? keyof S : never) : never;
65
137
  type SettlementWhoKeys = Settlement["who"] extends infer W ? (W extends object ? keyof W : never) : never;
66
- type _GuardGateOutcome = AssertAllKeysHandled<Exclude<keyof GateOutcome, "disposition" | "settlement" | "origin">>;
67
- type _GuardSettlement = AssertAllKeysHandled<Exclude<SettlementKeys, "kind" | "who" | "when" | "note">>;
68
- type _GuardSettlementWho = AssertAllKeysHandled<Exclude<SettlementWhoKeys, "party" | "approver" | "window">>;
138
+ type GateOutcomeProjected = "disposition" | "settlement" | "origin";
139
+ type _GuardGateOutcome = AssertAllKeysHandled<Exclude<keyof GateOutcome, GateOutcomeProjected>>;
140
+ type _GuardGateOutcomeReverse = AssertAllKeysHandled<Exclude<GateOutcomeProjected, keyof GateOutcome>>;
141
+ type SettlementProjected = "kind" | "who" | "when" | "note";
142
+ type _GuardSettlement = AssertAllKeysHandled<Exclude<SettlementKeys, SettlementProjected>>;
143
+ type _GuardSettlementReverse = AssertAllKeysHandled<Exclude<SettlementProjected, SettlementKeys>>;
144
+ type SettlementWhoProjected = "party" | "approver" | "window";
145
+ type _GuardSettlementWho = AssertAllKeysHandled<Exclude<SettlementWhoKeys, SettlementWhoProjected>>;
146
+ type _GuardSettlementWhoReverse = AssertAllKeysHandled<Exclude<SettlementWhoProjected, SettlementWhoKeys>>;
69
147
  export type CoreKeysetGuards = [
70
148
  _GuardNotification,
149
+ _GuardNotificationReverse,
150
+ _GuardProvenance,
151
+ _GuardProvenanceReverse,
152
+ _GuardAgentMessage,
153
+ _GuardAgentMessageReverse,
71
154
  _GuardBgNotif,
155
+ _GuardBgNotifReverse,
72
156
  _GuardRoster,
157
+ _GuardRosterReverse,
73
158
  _GuardAsk,
159
+ _GuardAskReverse,
160
+ _GuardAskFrame,
161
+ _GuardAskFrameReverse,
74
162
  _GuardTaskEvent,
163
+ _GuardTaskEventReverse,
75
164
  _GuardMailbox,
165
+ _GuardMailboxReverse,
76
166
  _GuardMailboxAppend,
167
+ _GuardMailboxAppendReverse,
168
+ _GuardWiringSections,
169
+ _GuardWiringSectionsReverse,
170
+ _GuardWiringLeg,
171
+ _GuardWiringLegReverse,
172
+ _GuardWiringAsk,
173
+ _GuardWiringAskReverse,
174
+ _GuardWiringQuestion,
175
+ _GuardWiringQuestionReverse,
176
+ _GuardWiringInteraction,
177
+ _GuardWiringInteractionReverse,
178
+ _GuardWiringElicit,
179
+ _GuardWiringElicitReverse,
180
+ _GuardWiringParkLane,
181
+ _GuardWiringParkLaneReverse,
182
+ _GuardWiringSession,
183
+ _GuardWiringSessionReverse,
184
+ _GuardWiringTools,
185
+ _GuardWiringToolsReverse,
186
+ _GuardWiringFleet,
187
+ _GuardWiringFleetReverse,
188
+ _GuardWiringMcp,
189
+ _GuardWiringMcpReverse,
190
+ _GuardWiringRules,
191
+ _GuardWiringRulesReverse,
192
+ _GuardWiringModelGate,
193
+ _GuardWiringModelGateReverse,
194
+ _GuardWiringAutoMode,
195
+ _GuardWiringAutoModeReverse,
196
+ _GuardWiringGovernance,
197
+ _GuardWiringGovernanceReverse,
77
198
  _GuardPermissionTrace,
78
199
  _GuardPermissionTraceReverse,
79
200
  _GuardPermissionTraceNonEmpty,
80
201
  _GuardInboxSummary,
202
+ _GuardInboxSummaryReverse,
81
203
  _GuardTaskSpec,
82
204
  _GuardTaskSpecReverse,
83
205
  _GuardTaskResult,
84
206
  _GuardTaskResultReverse,
207
+ _GuardPausedCause,
208
+ _GuardPausedCauseReverse,
85
209
  _GuardGateOutcome,
210
+ _GuardGateOutcomeReverse,
86
211
  _GuardSettlement,
212
+ _GuardSettlementReverse,
87
213
  _GuardSettlementWho,
88
- _GuardPausedCause,
89
- _NoDoubleBookPausedCause,
90
- _GuardPausedCauseReverse
214
+ _GuardSettlementWhoReverse
91
215
  ];
92
216
  export {};
93
217
  //# sourceMappingURL=core-keyset-guard.d.ts.map
@@ -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"];
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"];
20
20
  export type EngineNoticeWireCode = (typeof ENGINE_NOTICE_WIRE_CODES)[number];
21
21
  /** 白名单谓词(单点):路由与门都读这一个,不许第二处手抄码串。 */
22
22
  export declare function isEngineNoticeWireCode(code: string): code is EngineNoticeWireCode;
@@ -22,6 +22,7 @@ export const ENGINE_NOTICE_WIRE_CODES = [
22
22
  "classifier.denial_limit",
23
23
  "mcp.injection_dropped",
24
24
  "delegation.ask_unresolvable",
25
+ "task.interrupt_unconsumed",
25
26
  ];
26
27
  const WIRE_CODES = new Set(ENGINE_NOTICE_WIRE_CODES);
27
28
  export function isEngineNoticeWireCode(code) {
@@ -31,8 +31,13 @@
31
31
  * 的 `switch (ev.type)` 白名单臂(差集门 `test/durable-append-arm-parity.test.ts` 看守两腿一致);
32
32
  * · **腿自己的带外行**:park/终局/失败/建议/用量/装配自证(不来自流事件)。
33
33
  */
34
- export type LedgerEventType = "reasoning" | "text" | "tool_start" | "tool_end" | "status" | "context_usage" | "compacted" | "diagnostics" | "steering_injected" | "compaction_outcome" | "workspace_changed" | "wiring_manifest" | "human_input" | "task_progress" | "task_notification" | "turn_end"
35
- /** park 行名**两个**(`appendParked(kind)` 逐字取自 `result.status`)。 */
34
+ export type LedgerEventType = "reasoning" | "text" | "tool_start" | "tool_end" | "status" | "context_usage" | "compacted" | "diagnostics" | "steering_injected" | "compaction_outcome" | "workspace_changed" | "wiring_manifest"
35
+ /** S-212(7.71.0):运行期名册变更(core 7.8.0 [ref] ⑪)。**快照语义**——`delta.roster` 是整只
36
+ * 变更后名册,消费端收到即整只替换,所以回放不需要任何合并;它的耐久面因此不是 `wiring_manifest.tools`
37
+ * 的重复,而是那份开腿快照**之后**的每一次改动(修前两条 durable 腿零 case ⇒ 回放只见开头一版)。 */
38
+ | "tool_roster_delta" | "human_input" | "task_progress" | "task_notification" | "turn_end"
39
+ /** park 行名**两个**(`appendParked(kind)` 逐字取自 `result.status`)—— 运行期闭集见
40
+ * {@link PARK_LEDGER_EVENT_TYPES}(本联合是它的类型面,两者由下方的双向断言锁步)。 */
36
41
  | "suspended" | "needs_review" | "done" | "failed" | "suggestions" | "model_usage" | "prompt_assembled" | "config_assembled" | "file_link"
37
42
  /** 人在环三族的 open/close 帧对(投递面 = 本腿的 durable events tail)。 */
38
43
  | "elicitation" | "elicitation_complete" | "question" | "question_complete" | "tool_approval" | "tool_approval_complete"
@@ -59,4 +64,19 @@ export type LedgerEventType = "reasoning" | "text" | "tool_start" | "tool_end" |
59
64
  * 由 `test/engine-notice-wire.test.ts` 的腿覆盖门看守,那才是它的对位门。
60
65
  */
61
66
  | "engine_notice";
67
+ /**
68
+ * 🔴 **park 行名的运行时闭集**(合并重扫 [4])。
69
+ *
70
+ * 此前这两个词在仓里有**三处**并列的字面量:`ledger-sink.ts` 的 `appendParked` 形参与 `onDone` 的分诊、
71
+ * 以及 `observability/run-terminal-log.ts` 的脱敏臂。`LedgerEventType` 只是类型联合、运行期取不到,
72
+ * 所以脱敏臂只能自己再抄一份 —— 而抄的那一份**加词不红**:仓里/引擎加第三个 park 词并登记进
73
+ * `LedgerEventType` 之后,`appendParked` 与 resume 腿的动态首参照写照落,回放时那一行的
74
+ * `gate.riskDescriptor.summary` 明文,脱敏臂一声不吭。
75
+ *
76
+ * ⇒ 词表落成**运行时常量**由消费点派生;下方两条断言把它与类型联合双向锁死(多一词 / 少一词都 tsc 红)。
77
+ */
78
+ export declare const PARK_LEDGER_EVENT_TYPES: readonly ["suspended", "needs_review"];
79
+ export type ParkLedgerEventType = (typeof PARK_LEDGER_EVENT_TYPES)[number];
80
+ /** park 行名的**收窄谓词**(消费点要的是「这个词是不是 park 词」+ 类型收窄,不是一次裸 includes)。 */
81
+ export declare function isParkLedgerEventType(v: string): v is ParkLedgerEventType;
62
82
  //# sourceMappingURL=ledger-events.d.ts.map
@@ -1,2 +1,7 @@
1
- export {};
1
+ export const PARK_LEDGER_EVENT_TYPES = ["suspended", "needs_review"];
2
+ const _parkWordsAreLedgerTypes = true;
3
+ void _parkWordsAreLedgerTypes;
4
+ export function isParkLedgerEventType(v) {
5
+ return PARK_LEDGER_EVENT_TYPES.includes(v);
6
+ }
2
7
  //# sourceMappingURL=ledger-events.js.map
@@ -1,7 +1,7 @@
1
1
  import { type TerminalCause } from "@sema-agent/core";
2
2
  import { brainStatusEventData } from "./project.js";
3
3
  import { NotifiedKeys } from "../orchestration/workflow-completion-inbox.js";
4
- import type { LedgerEventType } from "./ledger-events.js";
4
+ import { type LedgerEventType, type ParkLedgerEventType } from "./ledger-events.js";
5
5
  /**
6
6
  * LedgerSink — the SINGLE "stream event → durable runs-ledger" projection, shared by the background leg
7
7
  * (runs.ts `runInBackground`) and the sync `/v1/tasks/stream` detach lane (server.ts, `x-detach-on-disconnect`).
@@ -61,13 +61,15 @@ export interface LedgerSink {
61
61
  }): void;
62
62
  /** Park event (durable F4 suspend / [ref] D-B review pause): ONLY the `checkpointGate` is persisted —
63
63
  * never the capability `checkpointToken` (search [18] Q1b).
64
- * ⚠️ **"non-secret" was the old wording and it is not true** ([ref] R3, 2026-09-03 — wording only, behaviour
65
- * unchanged; [ref] decides the arm): the gate carries NO capability token, but its `riskDescriptor.summary` /
66
- * `shadowedRule` are model-/human-controlled display text that [ref] measured carrying a PEM private-key
67
- * body verbatim. This durable row replays on every `GET /v1/runs/:id/events` reconnect and is NOT backfilled
68
- * by core [ref]'s mint-point fix — it is the third face of the `checkpointGate` sister item recorded in
69
- * `http/routes/approvals-assistant.ts` (`redactPendingDisclosures` header). */
70
- appendParked(kind: "suspended" | "needs_review", result: unknown): Promise<void>;
64
+ * 🔴 **The gate is redacted, not "non-secret"** ([ref], 2026-09-10 — the arm [ref] R3 left open): it carries no
65
+ * capability token, but its `reason` and the `riskDescriptor` leaf family are model-/human-controlled display
66
+ * text that [ref] measured carrying a PEM private-key body verbatim, and this durable row replays on EVERY
67
+ * `GET /v1/runs/:id/events` reconnect (core [ref]'s mint-point fix does not backfill rows already written).
68
+ * The redaction owner is NOT this writer: it is `redactLedgerEventData` — the one confluence every ledger row
69
+ * crosses at the three store twins' `appendEvent` AND again on the read face (idempotent). Redacting here too
70
+ * would put two writers on one semantic surface; the other park writers (`http/server.ts`'s two resume legs)
71
+ * would still need it, and a per-writer arm is exactly the shape that drifts. */
72
+ appendParked(kind: ParkLedgerEventType, result: unknown): Promise<void>;
71
73
  /** Terminal `done` event. `result` must already be checkpoint-token-stripped (and, on the bg leg,
72
74
  * model-usage-attached) by the caller. */
73
75
  appendDone(result: unknown): Promise<void>;
@@ -1,7 +1,8 @@
1
1
  import { terminalProjection } from "@sema-agent/core";
2
2
  import { redactSecrets } from "./redact.js";
3
- import { toolStartEventData, toolEndEventData, taskProgressEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, workspaceChangedEventData, wiringManifestEventData, humanInputEventData, turnEndEventData, contextUsageEventData } from "./project.js";
3
+ import { toolStartEventData, toolEndEventData, taskProgressEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, humanInputEventData, turnEndEventData, contextUsageEventData } from "./project.js";
4
4
  import { NotifiedKeys, taskNotificationStreamKey } from "../orchestration/workflow-completion-inbox.js";
5
+ import { isParkLedgerEventType } from "./ledger-events.js";
5
6
  export function createSerialLedgerAppend(appendEvent, startSeq) {
6
7
  let seq = startSeq;
7
8
  let chain = Promise.resolve();
@@ -98,6 +99,13 @@ export function createLedgerSink(opts) {
98
99
  await flush();
99
100
  await append("wiring_manifest", wiringManifestEventData(ev));
100
101
  break;
102
+ case "tool_roster_delta": {
103
+ await flush();
104
+ const rosterDelta = toolRosterDeltaEventData(ev);
105
+ if (rosterDelta !== undefined)
106
+ await append("tool_roster_delta", rosterDelta);
107
+ break;
108
+ }
101
109
  case "human_input":
102
110
  await flush();
103
111
  await append("human_input", humanInputEventData(ev));
@@ -156,7 +164,7 @@ export function createLedgerSink(opts) {
156
164
  await flush();
157
165
  if (result.terminal.kind === "paused") {
158
166
  const parkKind = terminalProjection(result.terminal).status;
159
- if (parkKind === "suspended" || parkKind === "needs_review") {
167
+ if (isParkLedgerEventType(parkKind)) {
160
168
  await appendParked(parkKind, result);
161
169
  return;
162
170
  }
@@ -357,11 +357,12 @@ export declare function workspaceChangedEventData(ev: {
357
357
  * ([ref],7.57.0 已发)答的是「**若此刻提交**会不会武装」,本段答的是「**这条真跑起来的腿**武装了吗」;
358
358
  * 同一个主体(调用方自己的 run)、同一条轴,只差事前/事后。剥掉它,壳就只能拿事前预测冒充事后事实;
359
359
  * ② **两个值都是引擎派生的闭形**:`armed` 布尔,`reason` 是 core 的闭集词(`AUTO_MODE_ARM_REASONS`:
360
- * armed / no_intent / no_face / denied / resolver_fault / latch_open)—— 非用户内容,不脱敏、逐字;
360
+ * armed / no_intent / no_face / denied / resolver_fault;core 7.12.0 起 `latch_open` 随熔断/单向闩
361
+ * 整族退役)—— 非用户内容,不脱敏、逐字;
361
362
  * ③ **不是 governance 侧信道**:它描述的是**本腿**的武装结论,与 lockedConfig/compliance/memoryAdmission/
362
363
  * retention 四位无函数关系;而 `denied` 这一词所披露的「组织把这一位关了」在 [ref] 读面上**本就已经**
363
364
  * 对同一租户可见(`org_denied`),本段没有扩大任何受众。
364
- * 🔴 **逐字透传,不映射**:core 的六词与本仓 [ref] 读面的六词(`AUTO_MODE_UNARMED_REASONS`)**刻意不归一**
365
+ * 🔴 **逐字透传,不映射**:core 的五词与本仓 [ref] 读面的六词(`AUTO_MODE_UNARMED_REASONS`)**刻意不归一**
365
366
  * —— 两张表回答的是两个问题、粒度也不同(core 的 `denied` 一词对应本仓的 `org_denied` / `local_denied`
366
367
  * 两词:core 只看合成后的 caps deny 位,本仓分得出这个 false 是 center 下发的还是本地 env 写的)。
367
368
  * ⚠️ **`settings_denied` 不折进 `denied`,它折进 `no_intent`**(codex 车BO r1 [medium] 验真后纠):
@@ -423,6 +424,11 @@ export declare function workspaceChangedEventData(ev: {
423
424
  * 的那一点订阅腿的名册增量座,一次改变名册的 refresh ⇒ **恰一帧**(序在 manifest 之后、那次 refresh 自己的
424
425
  * `tool_end` 之前),`delta.fromDigest` = 消费端手上那份名册的 digest。7.66.0 写下的「前瞻接线」披露随本版
425
426
  * 退役:本臂现在会真的触发,消费端可以依赖它了。
427
+ *
428
+ * 🔴 **三腿共用本构造器(S-212,7.71.0)**:live 腿(`routes/tasks.ts`)+ 两条 durable 腿
429
+ * (`trace/ledger-sink.ts` 的 `onEvent` / `http/server.ts` 的 resume switch)。返回 `undefined` 的那一格在
430
+ * 三腿上是同一件事 ——**整帧不发 / 整帧不落账**,绝不半张名册上 wire 或落库。落账的正当性(旧裁定
431
+ * 「不落账」为何在 7.71.0 撤销)逐字记在 `core-keyset-guard.ts` ⑪ 段。
426
432
  */
427
433
  export declare function toolRosterDeltaEventData(ev: {
428
434
  delta?: unknown;
@@ -548,10 +554,17 @@ export interface TraceTurn {
548
554
  * verbatim 转发——`in` 刻意保持它历史上的「总量」语义不变(旧帧/新帧读端零伤),不随 core 的
549
555
  * `promptTokens`/`turn_end.usage.inputTokens` 翻转为 cache-MISS。新增 `uncachedIn` 承接 core 3.0.0 才有的
550
556
  * cache-MISS 分量(命名取自 core `uncachedInputTokensOf`),只在能确认自己踩在新契约帧上时才发
551
- * (见 {@link toContractTokens})。 */
557
+ * (见 {@link toContractTokens})。
558
+ *
559
+ * 🔴 **S-213⑥:五个子键**全部按同族 OMIT 契约走 —— 引擎那一侧报了才铸,没报就**缺席**,恒不折 `0`。
560
+ * `in`/`out` 此前是必填座、缺一键时写 `?? 0`:读端拿到的 `in:0` 与「这一轮真的零输入」逐字节同形,
561
+ * 于是一次 usage 半缺(某些 provider 只回 output 侧)在面板上显示成一个可核对的真数字。
562
+ * 0 是一个数,未知不是 —— 两者同形正是本仓 `boundCallId`/`gateKind`/`contentKind` 一族一直在防的事。
563
+ * ⚠️ wire 面(`GET /v1/tasks/:id/turns` 与 trace SSE 的 `turn` 事件)因此可能给出**只有一侧**的
564
+ * `tokens`;做算术的消费端要按「键可能缺席」读(`tokens` 整只可缺席早就是契约的一部分)。 */
552
565
  tokens?: {
553
- in: number;
554
- out: number;
566
+ in?: number;
567
+ out?: number;
555
568
  uncachedIn?: number;
556
569
  cacheRead?: number;
557
570
  cacheWrite?: number;
@@ -600,7 +613,12 @@ export declare function turnEndEventData(ev: {
600
613
  * 的投影契约,不是 wire verbatim——`in` 保持它一直以来的**总量**语义,3.0.0 起改取 `totalInputTokens`
601
614
  * (归一化总输入含 cache)优先,`inputTokens` 回落(旧帧/尚未升级的 core 下 `totalInputTokens` 缺席时,
602
615
  * `in` 落回旧值,读端零伤)。`uncachedIn` 只在**能确认自己踩在新契约帧上**(`totalInputTokens` 在场)时
603
- * 才发——旧帧的 `inputTokens` 是族依赖的旧语义,标成「uncachedIn(cache-MISS)」会是谎言。 */
616
+ * 才发——旧帧的 `inputTokens` 是族依赖的旧语义,标成「uncachedIn(cache-MISS)」会是谎言。
617
+ *
618
+ * 🔴 S-213⑥:**一条规则管五个子键** —— 源侧在场就铸、缺席就不铸,没有 `?? 0`。此前 `in`/`out` 两座
619
+ * 各带一个默认 0,于是 usage 半缺(provider 只回 output 侧)被投影成 `in:0` = 一个看起来可核对的真
620
+ * 数字;`uncachedIn`/`cacheRead`/`cacheWrite` 三键从第一天起就是缺席制,`in`/`out` 只是漏进了默认值。
621
+ * 早退分支语义不变:输入两键(择一)与 `outputTokens` 全缺 ⇒ 整只 `tokens` 缺席(不铸空对象)。 */
604
622
  export declare function toContractTokens(usage: unknown): TraceTurn["tokens"] | undefined;
605
623
  /** [ref]C-13:tool_start/tool_end 的**共享挑键**——`projectEvents`(turns 面)与 `mapTraceEvent`
606
624
  * (trace SSE 面)对同一账本行的字段选择逐字同构,此前两处独立手写,structured/totalChars/label
@@ -493,11 +493,12 @@ export function toContractTokens(usage) {
493
493
  if (!usage || typeof usage !== "object")
494
494
  return undefined;
495
495
  const u = usage;
496
- if (u.inputTokens == null && u.totalInputTokens == null && u.outputTokens == null)
496
+ const inTokens = u.totalInputTokens ?? u.inputTokens;
497
+ if (inTokens == null && u.outputTokens == null)
497
498
  return undefined;
498
499
  return {
499
- in: u.totalInputTokens ?? u.inputTokens ?? 0,
500
- out: u.outputTokens ?? 0,
500
+ ...(inTokens != null ? { in: inTokens } : {}),
501
+ ...(u.outputTokens != null ? { out: u.outputTokens } : {}),
501
502
  ...(u.totalInputTokens != null && u.inputTokens != null ? { uncachedIn: u.inputTokens } : {}),
502
503
  ...(u.cacheReadTokens != null ? { cacheRead: u.cacheReadTokens } : {}),
503
504
  ...(u.cacheWriteTokens != null ? { cacheWrite: u.cacheWriteTokens } : {}),
@@ -650,6 +651,7 @@ function mapTraceEventInner(type, seq, data) {
650
651
  case "compaction_outcome":
651
652
  case "wiring_manifest":
652
653
  case "human_input":
654
+ case "tool_roster_delta":
653
655
  return null;
654
656
  default:
655
657
  return null;
@@ -1,3 +1,31 @@
1
+ /**
2
+ * Trace thinking-block redaction (service-side). Per core [R57]: the agent's reasoning/CoT is emitted on the
3
+ * live TaskEvent stream but DELIBERATELY kept out of the metadata Tracer because CoT may contain reasoned-about
4
+ * secrets (and is large / ToS-sensitive for some providers). Persisting it for the trace UI is the deployment's
5
+ * call — so when we DO persist it, redact unambiguous secret formats first. Conservative on purpose: only clear
6
+ * key/token shapes are redacted. ⚠️ It is NOT exhaustive: unrecognised secret formats (a free-text password,
7
+ * a JWT) pass through, and the broad `Bearer <20+ chars>` rule can over-match legitimate CoT (false positives
8
+ * tolerated — over-redacting trace text is safe). For sensitive deployments, disable thinking capture entirely
9
+ * via TRACE_THINKING=false. This is a seam — deployments can extend the patterns.
10
+ *
11
+ * 两组臂,顺序即优先序:{@link FULL_SECRET_PATTERNS}(完整形)在前,{@link FRAGMENT_SECRET_PATTERNS}
12
+ * ([ref] 前缀残片,上游先截后脱的产物 ⇒ 带 `:partial` 后缀的 token)在后。
13
+ */
14
+ /** 本模块替换 token 的**闭形**正则源(`«redacted»` / `«redacted:aws-key»` / `«redacted:gh-token:partial»` …):
15
+ * URL-userinfo 臂用它把「用户名位上已经是本模块 token」整个当一个用户名单元吃掉。模块加载时对
16
+ * {@link REDACTION_TOKENS} 逐个校验闭形(表加了新 token 形而这里没跟 ⇒ 加载即抛,fail-closed)。 */
17
+ import { stripFormatCharacters } from "@sema-agent/core";
18
+ /**
19
+ * `redactSecrets` 的**归一化前置**(S-103 ①):把全部 `\p{Cf}`(零宽空格 / 词连接符 / BOM / 软连字符 / ZWJ / ZWNJ …)
20
+ * 剥掉。实现单一属主是 core 的 `stripFormatCharacters`(`@sema-agent/core`,7.3.1 起导出,正是为「先扫描后渲染」这一序
21
+ * 开的口),本模块只**转出**它,不抄第二份 —— 两份实现漂了就等于两个「什么是格式字符」的定义。
22
+ *
23
+ * 🔴 **需要判断「这次脱敏到底有没有认出凭据形」的调用方,比较基准是它、不是原文**:
24
+ * `redactSecrets(x) !== x` 在本版里对**任何**含 Cf 的文本都为真(输出是剥后文本),拿它当谓词会把一条带 emoji ZWJ
25
+ * 的普通 `git commit` 判成「含凭据形」;正确的谓词是 `redactSecrets(x) !== normalizeForRedaction(x)`。
26
+ * 现役消费方:`src/tool-approval.ts` 的 `durableRuleMaterial`(规则车道素材闸)与语料的 FP=0 格。
27
+ */
28
+ export declare const normalizeForRedaction: typeof stripFormatCharacters;
1
29
  /** 测试可见:扫描器 indexOf 实际扫过的字节数(摊还线性 ⇒ ≤ 常数 × 输入长)。 */
2
30
  export declare function ppkScanBytesForTest(): number;
3
31
  export declare function resetPpkScanBytesForTest(): void;