@sema-agent/client-core 0.77.1 → 0.78.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/CHANGELOG.md +42 -1
- package/README.md +6 -5
- package/dist/abortableSleep.d.ts +0 -28
- package/dist/abortableSleep.js +0 -28
- package/dist/adapt/arms.d.ts +0 -46
- package/dist/adapt/arms.js +9 -544
- package/dist/adapt/ids.d.ts +0 -58
- package/dist/adapt/ids.js +0 -63
- package/dist/adapt/instanceLedger.d.ts +0 -25
- package/dist/adapt/instanceLedger.js +0 -20
- package/dist/adapt/panelTasks.d.ts +0 -69
- package/dist/adapt/panelTasks.js +0 -95
- package/dist/adapt/textSegmentAuthority.d.ts +1 -137
- package/dist/adapt/textSegmentAuthority.js +0 -54
- package/dist/adapt/textStream.d.ts +0 -252
- package/dist/adapt/textStream.js +2 -281
- package/dist/adapt/toolCards.d.ts +0 -46
- package/dist/adapt/toolCards.js +0 -23
- package/dist/adapt/turnFlags.d.ts +0 -54
- package/dist/adapt/turnFlags.js +1 -17
- package/dist/adapt/wireShapes.d.ts +0 -92
- package/dist/adapt/wireShapes.js +0 -83
- package/dist/adapt.d.ts +0 -55
- package/dist/adapt.js +1 -120
- package/dist/adapter/activeRunSelfHeal.d.ts +22 -515
- package/dist/adapter/activeRunSelfHeal.js +10 -625
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -305
- package/dist/adapter/downstream/eventToSdkMessage.js +2 -867
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -314
- package/dist/adapter/downstream/terminalToSdkResult.js +13 -560
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +0 -95
- package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -31
- package/dist/adapter/runStream.d.ts +0 -206
- package/dist/adapter/runStream.js +6 -596
- package/dist/adapter/types.d.ts +0 -111
- package/dist/adapter/types.js +0 -29
- package/dist/agentSession/backgroundView.d.ts +0 -106
- package/dist/agentSession/backgroundView.js +3 -49
- package/dist/agentSession/contract.d.ts +0 -98
- package/dist/agentSession/contract.js +0 -12
- package/dist/agentsWireCaps.d.ts +0 -72
- package/dist/agentsWireCaps.js +4 -72
- package/dist/approvalsStreamLiveCapability.d.ts +0 -25
- package/dist/approvalsStreamLiveCapability.js +0 -31
- package/dist/argvFlagValue.d.ts +0 -33
- package/dist/argvFlagValue.js +3 -35
- package/dist/attachmentsWireCaps.d.ts +0 -127
- package/dist/attachmentsWireCaps.js +0 -144
- package/dist/autoModeUnavailable.d.ts +0 -120
- package/dist/autoModeUnavailable.js +0 -144
- package/dist/classifierStatus.d.ts +0 -72
- package/dist/classifierStatus.js +0 -167
- package/dist/classifierVerdictWire.d.ts +0 -54
- package/dist/classifierVerdictWire.js +0 -133
- package/dist/clientContextWireCaps.d.ts +0 -37
- package/dist/clientContextWireCaps.js +0 -36
- package/dist/clientSlice.d.ts +0 -63
- package/dist/clientSlice.js +0 -45
- package/dist/cloudConfigWireCaps.d.ts +0 -86
- package/dist/cloudConfigWireCaps.js +2 -65
- package/dist/compensations.d.ts +0 -52
- package/dist/compensations.js +2 -63
- package/dist/controlRouter.d.ts +2 -208
- package/dist/controlRouter.js +1 -129
- package/dist/coreValuePorts.d.ts +0 -84
- package/dist/coreValuePorts.js +0 -29
- package/dist/decideReceipt.d.ts +0 -110
- package/dist/decideReceipt.js +0 -84
- package/dist/detachWire.d.ts +0 -130
- package/dist/detachWire.js +1 -130
- package/dist/deviceExecutorManagementCapability.d.ts +2 -35
- package/dist/deviceExecutorManagementCapability.js +1 -37
- package/dist/diagnostics.d.ts +0 -8
- package/dist/diagnostics.js +0 -8
- package/dist/diff/patch.d.ts +0 -17
- package/dist/diff/patch.js +0 -19
- package/dist/effectiveFacts.d.ts +0 -40
- package/dist/effectiveFacts.js +0 -22
- package/dist/effortWire.d.ts +0 -11
- package/dist/effortWire.js +0 -12
- package/dist/engineAgentPanelStore.d.ts +0 -169
- package/dist/engineAgentPanelStore.js +13 -293
- package/dist/engineCapReader.d.ts +0 -62
- package/dist/engineCapReader.js +1 -43
- package/dist/engineCapsCache.d.ts +0 -177
- package/dist/engineCapsCache.js +0 -199
- package/dist/engineCapsGenerationGuard.d.ts +0 -2
- package/dist/engineCapsGenerationGuard.js +0 -11
- package/dist/engineErrorCodes.d.ts +1 -316
- package/dist/engineErrorCodes.js +0 -427
- package/dist/engineHttpTools.d.ts +0 -29
- package/dist/engineHttpTools.js +0 -29
- package/dist/engineIdentity.d.ts +0 -83
- package/dist/engineIdentity.js +0 -88
- package/dist/engineInlineTaskStats.d.ts +0 -57
- package/dist/engineInlineTaskStats.js +1 -42
- package/dist/engineNoticeCodes.d.ts +0 -190
- package/dist/engineNoticeCodes.js +0 -182
- package/dist/engineSessionParam.d.ts +0 -30
- package/dist/engineSessionParam.js +0 -52
- package/dist/engineToolLabelStore.d.ts +0 -29
- package/dist/engineToolLabelStore.js +0 -31
- package/dist/engineWireSdk.d.ts +0 -90
- package/dist/engineWireSdk.js +0 -74
- package/dist/engineWireTarget.d.ts +0 -14
- package/dist/engineWireTarget.js +0 -39
- package/dist/env/localeGeo.d.ts +0 -12
- package/dist/env/localeGeo.js +2 -77
- package/dist/env/localeTag.d.ts +0 -34
- package/dist/env/localeTag.js +0 -32
- package/dist/env/uiLanguage.d.ts +0 -13
- package/dist/env/uiLanguage.js +0 -25
- package/dist/envFlag.d.ts +0 -37
- package/dist/envFlag.js +0 -40
- package/dist/executionLaneCapability.d.ts +0 -48
- package/dist/executionLaneCapability.js +0 -54
- package/dist/finalVerifyWire.d.ts +0 -67
- package/dist/finalVerifyWire.js +3 -43
- package/dist/fleet/fleetLedger.d.ts +0 -308
- package/dist/fleet/fleetLedger.js +10 -429
- package/dist/fleet/fleetProjection.d.ts +0 -240
- package/dist/fleet/fleetProjection.js +0 -189
- package/dist/fleet/fleetRowAgentType.d.ts +0 -6
- package/dist/fleet/fleetRowAgentType.js +1 -32
- package/dist/fleet/workflowSizeWarning.d.ts +0 -47
- package/dist/fleet/workflowSizeWarning.js +1 -46
- package/dist/fleetAgentPanelProjection.d.ts +0 -48
- package/dist/fleetAgentPanelProjection.js +8 -173
- package/dist/fleetTaskDesc.d.ts +0 -39
- package/dist/fleetTaskDesc.js +0 -69
- package/dist/forkWireCaps.d.ts +0 -23
- package/dist/forkWireCaps.js +1 -24
- package/dist/gateOutcome.d.ts +0 -140
- package/dist/gateOutcome.js +0 -85
- package/dist/gateVocabulary.d.ts +0 -114
- package/dist/gateVocabulary.js +3 -161
- package/dist/goalStopHook.d.ts +0 -127
- package/dist/goalStopHook.js +0 -178
- package/dist/headlessPermissionModeWire.d.ts +0 -76
- package/dist/headlessPermissionModeWire.js +1 -155
- package/dist/headlessReconnectWire.d.ts +0 -84
- package/dist/headlessReconnectWire.js +13 -67
- package/dist/hitl/approvalDecisionNoteAudit.d.ts +0 -49
- package/dist/hitl/approvalDecisionNoteAudit.js +0 -56
- package/dist/hitl/approvalOutcomeNote.d.ts +0 -2
- package/dist/hitl/approvalOutcomeNote.js +0 -20
- package/dist/hitl/approvalResolution.d.ts +0 -113
- package/dist/hitl/approvalResolution.js +0 -66
- package/dist/hitl/approvalsFeed.d.ts +0 -183
- package/dist/hitl/approvalsFeed.js +12 -243
- package/dist/hitl/armedGateRegistry.d.ts +0 -55
- package/dist/hitl/armedGateRegistry.js +0 -146
- package/dist/hitl/askGateWire.d.ts +0 -86
- package/dist/hitl/askGateWire.js +1 -95
- package/dist/hitl/askParkRowRouting.d.ts +0 -123
- package/dist/hitl/askParkRowRouting.js +1 -89
- package/dist/hitl/crashConverged.d.ts +0 -148
- package/dist/hitl/crashConverged.js +0 -214
- package/dist/hitl/editedRuleTextPrecheck.d.ts +0 -109
- package/dist/hitl/editedRuleTextPrecheck.js +0 -71
- package/dist/hitl/frameRouter.d.ts +0 -134
- package/dist/hitl/frameRouter.js +6 -378
- package/dist/hitl/gateIdentity.d.ts +0 -39
- package/dist/hitl/gateIdentity.js +0 -41
- package/dist/hitl/gateLedger.d.ts +0 -267
- package/dist/hitl/gateLedger.js +0 -121
- package/dist/hitl/hitlBridge.d.ts +7 -431
- package/dist/hitl/hitlBridge.js +7 -476
- package/dist/hitl/hitlHostSurface.d.ts +0 -150
- package/dist/hitl/hitlHostSurface.js +0 -169
- package/dist/hitl/livePendingAsk.d.ts +0 -91
- package/dist/hitl/livePendingAsk.js +0 -74
- package/dist/hitl/localAllowRule.d.ts +0 -62
- package/dist/hitl/localAllowRule.js +1 -33
- package/dist/hitl/parkOwnership.d.ts +0 -56
- package/dist/hitl/parkOwnership.js +0 -22
- package/dist/hitl/parkResolver.d.ts +3 -88
- package/dist/hitl/parkResolver.js +8 -349
- package/dist/hitl/parkRowBirthWait.d.ts +2 -26
- package/dist/hitl/parkRowBirthWait.js +3 -93
- package/dist/hitl/persistedRulesWire.d.ts +23 -371
- package/dist/hitl/persistedRulesWire.js +62 -329
- package/dist/hitl/planReviewWire.d.ts +4 -176
- package/dist/hitl/planReviewWire.js +9 -312
- package/dist/hitl/resumeRunningCard.d.ts +0 -105
- package/dist/hitl/resumeRunningCard.js +0 -105
- package/dist/hitl/sessionPolicyWire.d.ts +11 -191
- package/dist/hitl/sessionPolicyWire.js +0 -149
- package/dist/hitl/suspendedReopen.d.ts +3 -24
- package/dist/hitl/suspendedReopen.js +0 -14
- package/dist/hitl/toolApprovalWire.d.ts +5 -1308
- package/dist/hitl/toolApprovalWire.js +5 -945
- package/dist/hooksWireCaps.d.ts +0 -38
- package/dist/hooksWireCaps.js +0 -190
- package/dist/host.d.ts +0 -105
- package/dist/host.js +0 -33
- package/dist/hostEnv.d.ts +0 -14
- package/dist/hostEnv.js +0 -13
- package/dist/imagesWireCaps.d.ts +0 -21
- package/dist/imagesWireCaps.js +0 -22
- package/dist/index.d.ts +0 -134
- package/dist/index.js +0 -476
- package/dist/interactiveHalt.d.ts +5 -153
- package/dist/interactiveHalt.js +0 -111
- package/dist/interactiveToolsWire.d.ts +0 -62
- package/dist/interactiveToolsWire.js +1 -67
- package/dist/leaderConflict.d.ts +0 -59
- package/dist/leaderConflict.js +0 -48
- package/dist/limitsWire.d.ts +0 -125
- package/dist/limitsWire.js +2 -120
- package/dist/liveInitToolFace.d.ts +0 -77
- package/dist/liveInitToolFace.js +1 -109
- package/dist/liveModelCatalog.d.ts +0 -52
- package/dist/liveModelCatalog.js +0 -48
- package/dist/liveQuestionStore.d.ts +0 -87
- package/dist/liveQuestionStore.js +1 -56
- package/dist/mcpLiveness.d.ts +0 -151
- package/dist/mcpLiveness.js +0 -122
- package/dist/mcpPanel.d.ts +0 -104
- package/dist/mcpPanel.js +0 -49
- package/dist/mcpReconnect.d.ts +0 -58
- package/dist/mcpReconnect.js +0 -69
- package/dist/mcpWireCaps.d.ts +0 -55
- package/dist/mcpWireCaps.js +1 -13
- package/dist/memoryComplianceCapability.d.ts +3 -57
- package/dist/memoryComplianceCapability.js +0 -57
- package/dist/memoryEntriesWire.d.ts +6 -198
- package/dist/memoryEntriesWire.js +0 -144
- package/dist/memoryOriginCapability.d.ts +3 -53
- package/dist/memoryOriginCapability.js +0 -50
- package/dist/memorySpecWire.d.ts +0 -116
- package/dist/memorySpecWire.js +0 -150
- package/dist/model/catalog.d.ts +0 -111
- package/dist/model/catalog.js +0 -87
- package/dist/model/catalogLoader.d.ts +0 -114
- package/dist/model/catalogLoader.js +2 -139
- package/dist/model/modelSupplyRules.d.ts +1 -55
- package/dist/model/modelSupplyRules.js +0 -62
- package/dist/model/providerAuth.d.ts +0 -103
- package/dist/model/providerAuth.js +2 -38
- package/dist/model/providerCatalog.d.ts +0 -45
- package/dist/model/providerCatalog.js +0 -37
- package/dist/model/providerPresets.d.ts +0 -33
- package/dist/model/providerPresets.js +2 -91
- package/dist/model/tierVocabulary.d.ts +0 -31
- package/dist/model/tierVocabulary.js +0 -27
- package/dist/modelBudgetRule.d.ts +0 -39
- package/dist/modelBudgetRule.js +0 -39
- package/dist/modelCapabilityProbe.d.ts +0 -175
- package/dist/modelCapabilityProbe.js +0 -147
- package/dist/modelWireCaps.d.ts +0 -13
- package/dist/modelWireCaps.js +0 -13
- package/dist/notifications.d.ts +0 -233
- package/dist/notifications.js +14 -492
- package/dist/oneShotWireCaps.d.ts +0 -34
- package/dist/oneShotWireCaps.js +0 -35
- package/dist/ownKey.d.ts +0 -33
- package/dist/ownKey.js +0 -33
- package/dist/panelRunningHistory.d.ts +0 -28
- package/dist/panelRunningHistory.js +0 -43
- package/dist/peerFrames.d.ts +0 -71
- package/dist/peerFrames.js +0 -168
- package/dist/peerLaneCapability.d.ts +0 -44
- package/dist/peerLaneCapability.js +0 -52
- package/dist/permissionRuleIssue.d.ts +0 -30
- package/dist/permissionRuleIssue.js +0 -78
- package/dist/permissionRulesWriteCapability.d.ts +0 -46
- package/dist/permissionRulesWriteCapability.js +0 -54
- package/dist/permissionWireCaps.d.ts +0 -37
- package/dist/permissionWireCaps.js +0 -37
- package/dist/postureKnob.d.ts +0 -71
- package/dist/postureKnob.js +0 -86
- package/dist/principalWire.d.ts +0 -17
- package/dist/principalWire.js +0 -17
- package/dist/printToolResultFrame.d.ts +0 -100
- package/dist/printToolResultFrame.js +0 -33
- package/dist/promptProfileWireCaps.d.ts +0 -13
- package/dist/promptProfileWireCaps.js +0 -13
- package/dist/readFacePosture.d.ts +0 -43
- package/dist/readFacePosture.js +0 -46
- package/dist/request/printNotification.d.ts +0 -20
- package/dist/request/printNotification.js +0 -55
- package/dist/request/taskRequest.d.ts +1 -249
- package/dist/request/taskRequest.js +20 -498
- package/dist/resumeRefusalCopy.d.ts +0 -136
- package/dist/resumeRefusalCopy.js +1 -117
- package/dist/retainBackgroundWireCaps.d.ts +0 -48
- package/dist/retainBackgroundWireCaps.js +0 -48
- package/dist/retryStatus.d.ts +2 -221
- package/dist/retryStatus.js +0 -107
- package/dist/rewindWireCaps.d.ts +0 -27
- package/dist/rewindWireCaps.js +0 -24
- package/dist/runCancelContext.d.ts +1 -20
- package/dist/runCancelContext.js +0 -34
- package/dist/runTerminal.d.ts +0 -273
- package/dist/runTerminal.js +0 -177
- package/dist/sandboxWire.d.ts +0 -38
- package/dist/sandboxWire.js +0 -82
- package/dist/scenarioWire.d.ts +0 -60
- package/dist/scenarioWire.js +0 -68
- package/dist/scratchpadWireCaps.d.ts +0 -11
- package/dist/scratchpadWireCaps.js +0 -32
- package/dist/sdkWireTransit.d.ts +0 -38
- package/dist/sdkWireTransit.js +0 -30
- package/dist/seam.d.ts +18 -853
- package/dist/seam.js +0 -52
- package/dist/seatContract.d.ts +0 -555
- package/dist/seatContract.js +5 -304
- package/dist/selfOrchestrationDenial.d.ts +0 -189
- package/dist/selfOrchestrationDenial.js +0 -162
- package/dist/selfOrchestrationWireCaps.d.ts +0 -38
- package/dist/selfOrchestrationWireCaps.js +0 -38
- package/dist/sessionMap.d.ts +0 -60
- package/dist/sessionMap.js +0 -37
- package/dist/sessionMemoryStatus.d.ts +11 -114
- package/dist/sessionMemoryStatus.js +0 -112
- package/dist/sessionModelLatch.d.ts +0 -29
- package/dist/sessionModelLatch.js +0 -40
- package/dist/sessionPolicyCapability.d.ts +3 -53
- package/dist/sessionPolicyCapability.js +0 -52
- package/dist/sessionSlot.d.ts +0 -26
- package/dist/sessionSlot.js +0 -17
- package/dist/skillsWireCaps.d.ts +0 -87
- package/dist/skillsWireCaps.js +0 -38
- package/dist/sqlEngineCapability.d.ts +0 -118
- package/dist/sqlEngineCapability.js +0 -134
- package/dist/sseIdleTriage.d.ts +0 -79
- package/dist/sseIdleTriage.js +1 -80
- package/dist/steering.d.ts +0 -54
- package/dist/steering.js +0 -63
- package/dist/subagent/engineCompactWire.d.ts +0 -34
- package/dist/subagent/engineCompactWire.js +4 -134
- package/dist/subagent/engineDelegatedPrompt.d.ts +0 -31
- package/dist/subagent/engineDelegatedPrompt.js +1 -103
- package/dist/subagent/engineRowStopGate.d.ts +0 -20
- package/dist/subagent/engineRowStopGate.js +0 -49
- package/dist/subagent/engineSubagentOutput.d.ts +0 -7
- package/dist/subagent/engineSubagentOutput.js +1 -51
- package/dist/subagent/engineSubagentResume.d.ts +2 -279
- package/dist/subagent/engineSubagentResume.js +2 -129
- package/dist/subagent/engineSubagentSteer.d.ts +0 -26
- package/dist/subagent/engineSubagentSteer.js +0 -63
- package/dist/subagent/engineSubagentTail.d.ts +0 -38
- package/dist/subagent/engineSubagentTail.js +2 -110
- package/dist/subagent/engineTaskHandleWire.d.ts +6 -67
- package/dist/subagent/engineTaskHandleWire.js +0 -126
- package/dist/subagent/subagentOwnerAbsence.d.ts +0 -2
- package/dist/subagent/subagentOwnerAbsence.js +0 -25
- package/dist/subagentContentStore.d.ts +3 -260
- package/dist/subagentContentStore.js +7 -540
- package/dist/systemReminderTag.d.ts +0 -49
- package/dist/systemReminderTag.js +0 -61
- package/dist/toolResult.d.ts +1 -211
- package/dist/toolResult.js +1 -358
- package/dist/toolRoster.d.ts +0 -140
- package/dist/toolRoster.js +0 -66
- package/dist/typePins.d.ts +0 -46
- package/dist/types/engineState.d.ts +0 -71
- package/dist/types/engineState.js +0 -16
- package/dist/ultracodeWireCaps.d.ts +0 -75
- package/dist/ultracodeWireCaps.js +0 -92
- package/dist/unrefTimer.d.ts +0 -27
- package/dist/webSearchBackendCapability.d.ts +0 -72
- package/dist/webSearchBackendCapability.js +0 -79
- package/dist/webSearchWireCaps.d.ts +0 -37
- package/dist/webSearchWireCaps.js +0 -34
- package/dist/websearch/searchProviderPresets.d.ts +0 -81
- package/dist/websearch/searchProviderPresets.js +0 -27
- package/dist/wireErrorTriage.d.ts +4 -160
- package/dist/wireErrorTriage.js +0 -171
- package/dist/wireRefusalCopy.d.ts +0 -28
- package/dist/wireRefusalCopy.js +0 -28
- package/dist/workflow.d.ts +0 -40
- package/dist/workflow.js +0 -52
- package/dist/workflowClient.d.ts +0 -122
- package/dist/workflowClient.js +8 -360
- package/dist/workflowMonitor.d.ts +2 -72
- package/dist/workflowMonitor.js +0 -26
- package/dist/writeProtectionCapability.d.ts +0 -112
- package/dist/writeProtectionCapability.js +0 -109
- package/docs/INTEGRATION-CLIENTS.md +78 -5
- package/package.json +3 -3
package/dist/peerFrames.js
CHANGED
|
@@ -1,61 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* peerFrames.ts — design/385 的三条**引擎注入帧**在客户端的类型化投影(判定单源在包,端只装配)。
|
|
3
|
-
*
|
|
4
|
-
* ── 这一件守的是什么 ────────────────────────────────────────────────────────────────
|
|
5
|
-
* 引擎把三类东西塞进 **同一条** `task_notification` 车道,而它们在模型面根本不是同一种东西
|
|
6
|
-
* (core `renderTaskNotificationXml` 对这三类**不套** `<task-notification>` 壳):
|
|
7
|
-
* · `agentMessage` 同进程子代 → 父会话的 uplink(`SendMessage("main")`,§1.4 d1);
|
|
8
|
-
* · `crossSessionMessage` 另一个会话的消息,从本会话自己的信箱里 drain 出来(§4.1);
|
|
9
|
-
* · `crossSessionNotice` 关于**本会话自己发出去的**那条消息的回执 / idle 通知(§4.4 / §5.2)。
|
|
10
|
-
* 端如果照 `task_notification` 泛化卡去渲,用户看到的是一张「后台任务完成」卡,而模型读到的是
|
|
11
|
-
* 一条同事发来的话 —— 两个面说的不是同一件事。
|
|
12
|
-
*
|
|
13
|
-
* 🔴 **判别位是类型化载体的在场,永远不是 `summary` 文本**。这三条载体只有引擎的注入腿铸得出
|
|
14
|
-
* (`ExternalNotificationInput` 是 `TaskNotificationPayload` 的**真子集**,外部 `notify()` 一个
|
|
15
|
-
* 都穿不上);而 `summary`/`result` 是任何一条通知都填的字段,拿它做判据 = 任何一个后台任务
|
|
16
|
-
* 只要把 `<agent-message from="…">` 写进 summary 就能冒充一条同事消息。
|
|
17
|
-
*
|
|
18
|
-
* 🔴 **身份三条等式**:`_sema_provenance` 必须在场、`kind` 与车道相符,且 `from`/`taskId`/`seq`
|
|
19
|
-
* 与载体和载荷逐一相等(三条都由 core 铸点直证,见 `provenanceAgrees`)。只核 `kind` 拦得住
|
|
20
|
-
* 半截载荷,拦不住**同 kind 的伪造**——载体署一个可信名字、provenance 三位全不对,屏上照样
|
|
21
|
-
* 出现一条署着那个名字的消息。
|
|
22
|
-
*
|
|
23
|
-
* 🔴 **fail-closed**:载体在场但形不合(`from` 空、`body` 非串、notice 的 `kind` 不在闭集里)⇒
|
|
24
|
-
* 返回 `null` = 退回泛化卡。退回泛化卡是**诚实降级**(用户仍看得见这条通知,只是没有专用形);
|
|
25
|
-
* 而放一个半截形出去,端就会拿 `undefined` 去渲一张署名为空的「来自 @undefined 的消息」卡。
|
|
26
|
-
*
|
|
27
|
-
* 🔴 **优先序照抄 core 的渲染腿**(`agentMessage` → `crossSessionMessage` → `crossSessionNotice`)。
|
|
28
|
-
* 多载体同时在场是矛盾载荷,但**模型那一面已经按 core 的顺序读过了** —— 端按同一个顺序判,
|
|
29
|
-
* 两个面才说同一件事;这里另立一套「矛盾就退泛化」会让屏上那张卡与模型读到的帧对不上。
|
|
30
|
-
*
|
|
31
|
-
* ── 为什么渲染/解析两半都在包里 ─────────────────────────────────────────────────────
|
|
32
|
-
* 端的消息面(CC 血统:`UserTextMessage` 按标签分派)拿到的只有**文本**,没有帧。所以包必须同时
|
|
33
|
-
* 给出「帧 → 文本」与「文本 → 帧」两半,且**同源**(同一组标签常量、同一套属性序),端才可能
|
|
34
|
-
* 做到零字符串判定。两半的往返在常驻门里逐形对拍。
|
|
35
|
-
*
|
|
36
|
-
* ── 与上游的锚 ──────────────────────────────────────────────────────────────────────
|
|
37
|
-
* 两个标签字面量是 core 的铸点镜像(`core/task-notification.js::AGENT_MESSAGE_TAG` /
|
|
38
|
-
* `agents/cross-session-envelope.js::CROSS_SESSION_MESSAGE_TAG`),登记在壳的 wire 锚契约表里
|
|
39
|
-
* (cli `scripts/wire-anchor-registry.mjs`)—— core 改词当天那道门就红,而不是等到用户发现
|
|
40
|
-
* 「同事消息又变回一张后台任务卡了」。
|
|
41
|
-
*/
|
|
42
|
-
// ── wire 键名 / 属性名的单源(**刻意放在本文件第一个 `export` 之前**)────────────────────────
|
|
43
|
-
// 两个作用,第二个是被逼出来的:
|
|
44
|
-
// ① 键名单源 —— 读口与渲染口用同一个字节,不给手抄留缝;
|
|
45
|
-
// ② 绕开 client-core 闭包扫描器的一处误匹配:`run-client-core-portability-test.mjs` 的
|
|
46
|
-
// `import/export … from '…'` 边扫描按 `from` + 引号这个**字节序列**认依赖,于是源码里任何
|
|
47
|
-
// 一个 `'from'` 字面量(本模块读的正是 wire 上那个 `from` 键)都会被当成一条外部包依赖,
|
|
48
|
-
// 把「A 层闭包外部包 === {diff}」判红。扫描器的锚起点是**行首的 `export`**,所以键名收在
|
|
49
|
-
// 首个 export 之前就落在它的射程外。⚠️ 这是绕过一处**扫描器误报**,不是绕过判据本身 ——
|
|
50
|
-
// 本模块真实的外部依赖是零(纯叶,零 import)。
|
|
51
1
|
const WIRE_KEY_FROM = 'from';
|
|
52
2
|
const WIRE_KEY_BODY = 'body';
|
|
53
3
|
const WIRE_KEY_KIND = 'kind';
|
|
54
4
|
const WIRE_KEY_TEXT = 'text';
|
|
55
5
|
const WIRE_KEY_SEQ = 'seq';
|
|
56
6
|
const WIRE_KEY_TASK_ID = 'task_id';
|
|
57
|
-
/** 🔴 载荷那一边是 **snake** `task_id`,provenance 那一边是 **camel** `taskId` —— 同一个量、两个拼法,
|
|
58
|
-
* 写混了等式恒不成立、整条车道静默死掉(本模块首版就写混过一次,当场被门抓住)。 */
|
|
59
7
|
const WIRE_KEY_PROV_TASK_ID = 'taskId';
|
|
60
8
|
const WIRE_KEY_AGENT_TYPE = 'agentType';
|
|
61
9
|
const WIRE_KEY_AGENT_MESSAGE = 'agentMessage';
|
|
@@ -66,22 +14,12 @@ const WIRE_KEY_FROM_SESSION = 'fromSession';
|
|
|
66
14
|
const WIRE_KEY_FROM_NAME = 'fromName';
|
|
67
15
|
const WIRE_KEY_FROM_MODE = 'fromMode';
|
|
68
16
|
const WIRE_KEY_FROM_SCOPE = 'fromScope';
|
|
69
|
-
/** 信封上的 `from` 属性名(与上面的 wire 键同字节,渲染/解析两腿共用)。 */
|
|
70
17
|
const FROM_ATTR = WIRE_KEY_FROM;
|
|
71
|
-
/** core `core/task-notification.ts::AGENT_MESSAGE_TAG` 的镜像(同进程 uplink 的模型面标签)。 */
|
|
72
18
|
export const AGENT_MESSAGE_TAG = 'agent-message';
|
|
73
|
-
/** core `agents/cross-session-envelope.ts::CROSS_SESSION_MESSAGE_TAG` 的镜像(跨会话信封标签)。 */
|
|
74
19
|
export const CROSS_SESSION_MESSAGE_TAG = 'cross-session-message';
|
|
75
|
-
/** core `_sema_provenance.kind` 的闭集(7.4.0 三员;7.2.0 只有第一员 —— 缺员按「上游还没发」处理,
|
|
76
|
-
* 不是「上游改词」:本模块从不要求 provenance 在场,只要求**在场时不自相矛盾**)。 */
|
|
77
20
|
export const PEER_FRAME_LANES = Object.freeze(['agent_message', 'cross_session_message', 'cross_session_notice']);
|
|
78
|
-
/** core `crossSessionNotice.kind` 的闭集(§4.4:投递回执 / idle 回执两形)。 */
|
|
79
21
|
export const CROSS_SESSION_NOTICE_KINDS = Object.freeze(['delivery_notice', 'idle_notice']);
|
|
80
|
-
/** core `PermissionModeClass`(发送方**自述**的权限模式类,不是被证实的事实)。 */
|
|
81
22
|
export const PEER_MODE_CLASSES = Object.freeze(['bypass', 'prompting']);
|
|
82
|
-
// ── 防御式读口 ────────────────────────────────────────────────────────────────────────
|
|
83
|
-
// 载荷是 wire JSON,正常路径上全是数据属性;但读一个 getter = 同步跑别人的代码,而
|
|
84
|
-
// `try/catch` 接得住抛错、接不住「永不返回」。⇒ 只认自有**数据**描述符,访问器一律当缺席。
|
|
85
23
|
function dataProp(o, key) {
|
|
86
24
|
if (o === null || typeof o !== 'object')
|
|
87
25
|
return undefined;
|
|
@@ -90,7 +28,6 @@ function dataProp(o, key) {
|
|
|
90
28
|
d = Object.getOwnPropertyDescriptor(o, key);
|
|
91
29
|
}
|
|
92
30
|
catch {
|
|
93
|
-
// 已撤销的 Proxy / 敌意 trap:当缺席(读不出来 ≠ 有值)
|
|
94
31
|
return undefined;
|
|
95
32
|
}
|
|
96
33
|
if (d === undefined || !('value' in d))
|
|
@@ -103,45 +40,12 @@ function nonEmptyString(v) {
|
|
|
103
40
|
function finiteNumber(v) {
|
|
104
41
|
return typeof v === 'number' && Number.isFinite(v) ? v : undefined;
|
|
105
42
|
}
|
|
106
|
-
/**
|
|
107
|
-
* `_sema_provenance` 的一致性判据 —— **必须在场、且 `kind` 与载体所属车道相符**。
|
|
108
|
-
*
|
|
109
|
-
* 🔴 首版写的是「只否决不认证、缺席放行」,理由是「core 7.2.0 的闭集只有一员,要求在场会让另外
|
|
110
|
-
* 两条车道在老引擎上恒死」。**那条理由是错的**(异源对抗复审 r1 [high] 证伪,当场采纳):
|
|
111
|
-
* 老引擎上另外两条车道**连载体键都不存在**,本函数根本走不到;而 core 契约明写 provenance
|
|
112
|
-
* 「present exactly when the carrier is」——今天在跑的那一版(7.2.0 `agents/send-message-tool.js`
|
|
113
|
-
* 的 uplink 腿)就是**同一处**同时铸载体与 provenance 的。所以要求它在场:
|
|
114
|
-
* · 对**真**载荷零代价(真载荷从来都带着它);
|
|
115
|
-
* · 对畸形/半截注入/版本漂移的载荷则关上了一道门 —— 否则只凭 `from`/`body` 两个字符串就能
|
|
116
|
-
* 让屏上出现一张署着任意名字的「来自某人的消息」卡,而那正是本模块存在的理由的反面。
|
|
117
|
-
*
|
|
118
|
-
* 判据 = **在场 + 四等式**(`kind` 与车道相符;`from`/`taskId`/`seq` 三位必须在场且与载体、载荷逐一相等,
|
|
119
|
-
* 见函数体内三条铸点直证)。首版曾写「判据只到 kind、刻意不比三位」——那一版的顾虑(上游编码差一格
|
|
120
|
-
* ⇒ 车道静默死)由 cli 侧 wire 锚 A-K24 的同址探针接管:铸点一改门先红,不会变成静默死。
|
|
121
|
-
*/
|
|
122
43
|
function provenanceAgrees(n, lane, carrierFrom) {
|
|
123
44
|
const prov = dataProp(n, WIRE_KEY_PROVENANCE);
|
|
124
45
|
if (prov === null || typeof prov !== 'object')
|
|
125
46
|
return false;
|
|
126
47
|
if (dataProp(prov, WIRE_KEY_KIND) !== lane)
|
|
127
48
|
return false;
|
|
128
|
-
// 🔴 三条等式**每一条都有铸点直证**(不是从散文里推的):
|
|
129
|
-
// · uplink 腿(core 7.2.0 `dist/agents/send-message-tool.js`)一个对象字面量里同时写下
|
|
130
|
-
// `task_id: senderId` / `seq: uplinkSeq` / `agentMessage:{from: senderLabel}` 与
|
|
131
|
-
// `_sema_provenance:{from: senderLabel, taskId: senderId, seq: uplinkSeq}`;
|
|
132
|
-
// · 跨会话 drain 腿(core 7.4.0 `agents/peer-session-drain.ts` 的两个 build*Payload)同形:
|
|
133
|
-
// `task_id: boxHandle` / `seq: m.seq` 与 provenance 的 `taskId`/`seq` 同值,
|
|
134
|
-
// 消息臂的 `crossSessionMessage.from` 与 provenance 的 `from` 同为 `fields.from`。
|
|
135
|
-
// ⇒ 三位不一致 = 这不是引擎那条腿铸出来的载荷。只核 `kind` 只拦得住半截载荷,拦不住
|
|
136
|
-
// **同 kind 的伪造**:载体署一个可信的名字、provenance 三位全对不上,屏上照样出现一条
|
|
137
|
-
// 署着那个名字的消息(异源对抗复审 r2 [medium] 实测)。
|
|
138
|
-
// 🔴 铸点一改这三条就该跟着改 —— 由壳的 wire 锚 A-K24 同址探针钉住那一行字面量,
|
|
139
|
-
// 上游改词当天门就红,不会变成一条静默死掉的车道。
|
|
140
|
-
// 🔴 **在场也是判据的一半**(异源对抗复审 r3 [medium] 采纳):`SemaProvenance` 的 `from`/`taskId`/
|
|
141
|
-
// `seq` 在 core 的类型面上**全是必填**,三个铸点也都同址写下它们 —— 所以「两侧都缺」不是一种
|
|
142
|
-
// 合法的兼容形,而是一个半截载荷。首版只写 `a === b`,于是 `undefined === undefined` 把它放行了
|
|
143
|
-
// (实测:去掉两侧 seq、或去掉载荷的 task_id,半截载荷照样投影成一条 agent_message)。
|
|
144
|
-
// ⇒ 先各自核在场与类型,再比值。
|
|
145
49
|
const provFrom = cleanName(dataProp(prov, WIRE_KEY_FROM));
|
|
146
50
|
if (provFrom === undefined || (carrierFrom !== undefined && provFrom !== carrierFrom))
|
|
147
51
|
return false;
|
|
@@ -151,16 +55,8 @@ function provenanceAgrees(n, lane, carrierFrom) {
|
|
|
151
55
|
const seq = finiteNumber(dataProp(n, WIRE_KEY_SEQ));
|
|
152
56
|
return seq !== undefined && finiteNumber(dataProp(prov, WIRE_KEY_SEQ)) === seq;
|
|
153
57
|
}
|
|
154
|
-
/**
|
|
155
|
-
* `task_notification` 原始 wire 载荷 → 三条引擎注入车道之一;认不出 ⇒ `null`(= 泛化通知,
|
|
156
|
-
* 调用方照旧走 `normalizeTaskNotification` / `renderTaskNotificationXml`)。
|
|
157
|
-
*
|
|
158
|
-
* 入参是**原始**载荷(snake_case `task_id` 那一份),不是 `normalizeTaskNotification` 的产物 ——
|
|
159
|
-
* 后者是一张 15 键白名单,这三条载体一个都不在里面。
|
|
160
|
-
*/
|
|
161
58
|
export function classifyPeerNotification(n) {
|
|
162
59
|
const seq = finiteNumber(dataProp(n, WIRE_KEY_SEQ));
|
|
163
|
-
// ① 同进程 uplink(§1.4 d1)
|
|
164
60
|
const agentMessage = dataProp(n, WIRE_KEY_AGENT_MESSAGE);
|
|
165
61
|
if (agentMessage !== undefined) {
|
|
166
62
|
const from = cleanName(dataProp(agentMessage, WIRE_KEY_FROM));
|
|
@@ -177,7 +73,6 @@ export function classifyPeerNotification(n) {
|
|
|
177
73
|
}
|
|
178
74
|
return null;
|
|
179
75
|
}
|
|
180
|
-
// ② 跨会话信封(§4.1)
|
|
181
76
|
const crossSessionMessage = dataProp(n, WIRE_KEY_CROSS_SESSION_MESSAGE);
|
|
182
77
|
if (crossSessionMessage !== undefined) {
|
|
183
78
|
const from = cleanName(dataProp(crossSessionMessage, WIRE_KEY_FROM));
|
|
@@ -189,8 +84,6 @@ export function classifyPeerNotification(n) {
|
|
|
189
84
|
const fromModeRaw = dataProp(crossSessionMessage, WIRE_KEY_FROM_MODE);
|
|
190
85
|
const fromMode = PEER_MODE_CLASSES.find(m => m === fromModeRaw);
|
|
191
86
|
const fromScope = nonEmptyString(dataProp(crossSessionMessage, WIRE_KEY_FROM_SCOPE));
|
|
192
|
-
// 🔴 可选位形不合 ⇒ **只丢那一位**,不丢整帧:少一个 `from-mode` 是少一句注,
|
|
193
|
-
// 丢整帧是把一条同事消息从用户眼前拿走(与必填位的 fail-closed 是两码事)。
|
|
194
87
|
return {
|
|
195
88
|
lane: 'cross_session_message',
|
|
196
89
|
from,
|
|
@@ -202,7 +95,6 @@ export function classifyPeerNotification(n) {
|
|
|
202
95
|
...(seq !== undefined ? { seq } : {}),
|
|
203
96
|
};
|
|
204
97
|
}
|
|
205
|
-
// ③ 跨会话回执 / idle 通知(§4.4 / §5.2)
|
|
206
98
|
const crossSessionNotice = dataProp(n, WIRE_KEY_CROSS_SESSION_NOTICE);
|
|
207
99
|
if (crossSessionNotice !== undefined) {
|
|
208
100
|
const kindRaw = dataProp(crossSessionNotice, WIRE_KEY_KIND);
|
|
@@ -214,17 +106,6 @@ export function classifyPeerNotification(n) {
|
|
|
214
106
|
}
|
|
215
107
|
return null;
|
|
216
108
|
}
|
|
217
|
-
// ── 帧 ⇄ 文本(端的消息面只拿得到文本;两半同源,往返在常驻门里对拍)────────────────────
|
|
218
|
-
/**
|
|
219
|
-
* core `ENGINE_AUTHORITY_ENVELOPE_TAGS` 的镜像(`core/untrusted-text.ts::ENGINE_ENVELOPES` 里 kind="authority" 的标签):
|
|
220
|
-
* 这些信封在模型面/转录面代表**引擎权威**,一段同事正文里出现它们就是伪造。core 的 `neutralizePeerBody`
|
|
221
|
-
* (= `sanitizeUntrustedText(body, PEER_BODY_ENVELOPE_TAGS)`)在渲染信封**之前**先把它们拆火(`<` 后插 ZWSP),
|
|
222
|
-
* 本模块首版只抄了后一步(同名信封拆火)——异源发包扫描 [high] 实证:子代正文里一段
|
|
223
|
-
* `<task-notification><task-id>victim</task-id><status>completed</status>…` 会原样进转录 block,
|
|
224
|
-
* 宿主 resume 时 `parseTranscriptNotificationSeeds` 把它读成真完成通知 ⇒ 去重台账被毒化,受害 run 的
|
|
225
|
-
* 真完成通知随后被跨通道臂整条吞掉。这里补上那一步,并与 core 同形(`<\s*\/?\s*(tag)(\s[^>]*)?>` 全大小写)。
|
|
226
|
-
* 🔴 单向(与 core 一致):端的解析腿**不**还原 ZWSP —— 拆掉的权威标签就该永远是拆掉的。
|
|
227
|
-
*/
|
|
228
109
|
const AUTHORITY_ENVELOPE_TAGS = Object.freeze([
|
|
229
110
|
'system-reminder',
|
|
230
111
|
'task-notification',
|
|
@@ -240,53 +121,25 @@ const AUTHORITY_BREAKOUT_RE = new RegExp(`<\\s*\\/?\\s*(?:${AUTHORITY_ENVELOPE_T
|
|
|
240
121
|
function neutralizeAuthorityTags(text) {
|
|
241
122
|
return text.replace(AUTHORITY_BREAKOUT_RE, m => m.replace('<', '<' + ZWSP));
|
|
242
123
|
}
|
|
243
|
-
/**
|
|
244
|
-
* 署名类属性的呈现规范化(异源发包扫描 [medium]):`from` / `fromName` 是发送方**自述**的串,可含换行与控制符,
|
|
245
|
-
* 折叠行按单行渲会被它撑破。与 core `canonicalPeerDisplayName` 同向:控制符/换行折成单空格、两端去空白;
|
|
246
|
-
* 折空 ⇒ 视同缺席(必填位 ⇒ 整帧退泛化卡;可选位 ⇒ 只丢那一位)。
|
|
247
|
-
*/
|
|
248
124
|
function cleanName(v) {
|
|
249
125
|
if (typeof v !== 'string')
|
|
250
126
|
return undefined;
|
|
251
127
|
const t = v.replace(/[\u0000-\u001f\u007f\u2028\u2029]+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
252
128
|
return t.length > 0 ? t : undefined;
|
|
253
129
|
}
|
|
254
|
-
/**
|
|
255
|
-
* 正文里的同名标签拆火:开括号后插一个反斜杠,于是它不再是一个标签。
|
|
256
|
-
*
|
|
257
|
-
* 🔴 与 core 的 `escapeEnvelopeTag` **有意不同一格**(异源对抗复审 r1 [medium] 采纳):core 那一份是
|
|
258
|
-
* **单向**消毒(模型读到就完了,没有反向腿),所以它不处理正文里**原本就有**的 `<\agent-message>`;
|
|
259
|
-
* 而本模块有反向腿(端的消息面要把正文还原出来),单向消毒在这里就是一个**非单射**映射 ——
|
|
260
|
-
* 一段合法的代码文本 `<\agent-message>` 会在 render→parse 往返之后被改写成 `<agent-message>`,
|
|
261
|
-
* 既损坏正文,又等于给正文一条**注入真标签**的路。
|
|
262
|
-
* ⇒ 这里连**已有的反斜杠**一起数:`<` 后面跟任意多个反斜杠再跟标签名时都插一个。
|
|
263
|
-
* 每次编码恰好加一个、每次解码恰好去一个 ⇒ `unescape(escape(x)) === x` 对一切 x 成立。
|
|
264
|
-
*/
|
|
265
130
|
function escapeEnvelopeTag(tag, text) {
|
|
266
131
|
return text.replace(new RegExp(`<(?=\\\\*/?${tag}(?:[>\\s/]|$))`, 'gi'), '<\\');
|
|
267
132
|
}
|
|
268
133
|
function unescapeEnvelopeTag(tag, text) {
|
|
269
134
|
return text.replace(new RegExp(`<\\\\(?=\\\\*/?${tag}(?:[>\\s/]|$))`, 'gi'), '<');
|
|
270
135
|
}
|
|
271
|
-
/** 属性值转义 —— 属性用双引号包,值里的 `"` 与尖括号一律实体化,不给伪造闭合属性留缝。 */
|
|
272
136
|
function attr(v) {
|
|
273
137
|
return v.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
274
138
|
}
|
|
275
139
|
function unattr(v) {
|
|
276
140
|
return v.replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');
|
|
277
141
|
}
|
|
278
|
-
/**
|
|
279
|
-
* 投影 → 转录行文本(端的消息面按标签分派的那一份)。
|
|
280
|
-
*
|
|
281
|
-
* 🔴 这**不是** core 模型面信封的逐字副本,也不该是:core 那一份是给**模型**读的(带纪律块、
|
|
282
|
-
* 带 CC 逐字属性语法、带 round-trip 拒收);这一份是**端的转录回显**,只需要与本模块的解析腿
|
|
283
|
-
* 往返一致。刻意不复刻 core 的语法契约 —— 复刻一份对不上的副本比不复刻更坏
|
|
284
|
-
* (它会让人以为端这一行是模型读到的那一行)。属性序仍照 core 的规范序排,便于人肉比对。
|
|
285
|
-
*/
|
|
286
142
|
export function renderPeerFrameTranscriptText(p) {
|
|
287
|
-
// 🔴 通知纯行也是引擎按 peerMeta 铸的散文,但它承载的仍是**关于别人消息**的文本:同样过权威标签拆火,
|
|
288
|
-
// 并把两个消息信封标签拆火 —— 否则一条整体形如 `<agent-message …>…</agent-message>` 的通知会被端判成
|
|
289
|
-
// 一条署名消息(异源发包扫描同形存量③)。
|
|
290
143
|
if (p.lane === 'cross_session_notice')
|
|
291
144
|
return escapeEnvelopeTag(CROSS_SESSION_MESSAGE_TAG, escapeEnvelopeTag(AGENT_MESSAGE_TAG, neutralizeAuthorityTags(p.text)));
|
|
292
145
|
if (p.lane === 'agent_message') {
|
|
@@ -305,8 +158,6 @@ export function renderPeerFrameTranscriptText(p) {
|
|
|
305
158
|
const body = escapeEnvelopeTag(CROSS_SESSION_MESSAGE_TAG, neutralizeAuthorityTags(p.body));
|
|
306
159
|
return `<${CROSS_SESSION_MESSAGE_TAG} ${attrs.join(' ')}>\n${body}\n</${CROSS_SESSION_MESSAGE_TAG}>`;
|
|
307
160
|
}
|
|
308
|
-
// 🔴 属性值不设长度上界:渲染腿无界,解析腿封顶就会让包自己铸出的帧解析回 null(异源发包扫描 [high]);
|
|
309
|
-
// `[^"]*` 是线性匹配,无回溯风险。
|
|
310
161
|
const AGENT_MESSAGE_RE = new RegExp(`^<${AGENT_MESSAGE_TAG} ${FROM_ATTR}="([^"]*)">\\n([\\s\\S]*)\\n</${AGENT_MESSAGE_TAG}>$`);
|
|
311
162
|
const CROSS_SESSION_RE = new RegExp(`^<${CROSS_SESSION_MESSAGE_TAG} ${FROM_ATTR}="([^"]*)"` +
|
|
312
163
|
`(?: from-session="([^"]*)")?` +
|
|
@@ -314,18 +165,6 @@ const CROSS_SESSION_RE = new RegExp(`^<${CROSS_SESSION_MESSAGE_TAG} ${FROM_ATTR}
|
|
|
314
165
|
`(?: from-mode="(bypass|prompting)")?` +
|
|
315
166
|
`(?: from-scope="([^"]*)")?` +
|
|
316
167
|
`>\\n([\\s\\S]*)\\n</${CROSS_SESSION_MESSAGE_TAG}>$`);
|
|
317
|
-
/**
|
|
318
|
-
* 转录行文本 → 投影(`renderPeerFrameTranscriptText` 的逆)。认不出 ⇒ `null`。
|
|
319
|
-
*
|
|
320
|
-
* 端唯一该调的字符串判定口:**端自己一条正则都不许写**(cli-191 A-D1/A-D12 那一族的成因就是
|
|
321
|
-
* 消费端各自抄一份判据,上游改词后集体空转而没有一道门响)。
|
|
322
|
-
*
|
|
323
|
-
* 🔴 `ok` 只等于「形是规范的」,**不等于**「这条消息真是引擎注入的」——文本面的身份权威不存在
|
|
324
|
-
* (core §4.2 三层规则同一句话)。端拿它做**呈现**分派,不许拿它做任何授权判断。
|
|
325
|
-
* 🔴 通知车道(`cross_session_notice`)刻意**不进这条腿**:它的转录行是一行没有标签的散文,
|
|
326
|
-
* 要认它只能去锚 `[Cross-session …]` 前缀 —— 那正是本仓禁的那一形(用户随手打一行同样的字
|
|
327
|
-
* 就会被认成引擎通知)。通知按普通文本行渲,本来就是 CC 形。
|
|
328
|
-
*/
|
|
329
168
|
function hasRawTag(tag, body) {
|
|
330
169
|
return new RegExp(`<(?=/?${tag}(?:[>\\s/]|$))`, 'i').test(body);
|
|
331
170
|
}
|
|
@@ -333,9 +172,6 @@ export function parsePeerFrameText(text) {
|
|
|
333
172
|
const a = AGENT_MESSAGE_RE.exec(text);
|
|
334
173
|
if (a !== null) {
|
|
335
174
|
const from = unattr(a[1] ?? '');
|
|
336
|
-
// 🔴 正文里出现**未拆火**的同名标签 ⇒ 这不是本渲染腿产出的字节(它拆火过了),而**贪婪**的
|
|
337
|
-
// `[\s\S]*` 会把「两封拼在一起」读成一封、把两封的正文合并、把两位署名合并成第一位 ——
|
|
338
|
-
// 异源对抗复审 r1 [high] 的第三形。整条退 null:落回普通文本行,一个字节都不丢。
|
|
339
175
|
if (from.length === 0 || hasRawTag(AGENT_MESSAGE_TAG, a[2] ?? ''))
|
|
340
176
|
return null;
|
|
341
177
|
return { lane: 'agent_message', from, body: unescapeEnvelopeTag(AGENT_MESSAGE_TAG, a[2] ?? '') };
|
|
@@ -360,10 +196,6 @@ export function parsePeerFrameText(text) {
|
|
|
360
196
|
...(fromScope !== undefined ? { fromScope } : {}),
|
|
361
197
|
};
|
|
362
198
|
}
|
|
363
|
-
/**
|
|
364
|
-
* 端渲「@谁」时该用的那个名字 —— 判定在包,端不许自己排优先序。
|
|
365
|
-
* 跨会话:`fromName`(人取的名)优先于 `from`(地址);同进程:只有 `from`。
|
|
366
|
-
*/
|
|
367
199
|
export function peerFrameDisplayName(p) {
|
|
368
200
|
return p.lane === 'cross_session_message' && p.fromName !== undefined ? p.fromName : p.from;
|
|
369
201
|
}
|
|
@@ -1,32 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* peerLaneCapability — `GET /v1/capabilities.peerLane`(server ≥7.91.1;sdk 9.8.1 尚未声明该键 ⇒ 结构读)
|
|
3
|
-
* 的三端共用读面(0.76.1 CC-102;与 sql / writeProtection / webSearch.backend / executionLane /
|
|
4
|
-
* approvalsStreamLive / deviceExecutor.management 各只兄弟同一套四态词汇)。
|
|
5
|
-
*
|
|
6
|
-
* ── 这一位答的是哪一个问题 ────────────────────────────────────────────────────────────────
|
|
7
|
-
* 「本部署的会话之间能不能互相发现并投递」——引擎的跨会话目录席是否已挂(会话枚举面 ∧ 耐久
|
|
8
|
-
* mailbox ∧ 该 mailbox 的收件人生命周期面,三缺一即缺席)。位为真时模型侧多出 `ListAgents`
|
|
9
|
-
* (列同一 principal 的其它会话)、`SendMessage` 的 `session.<id>` 地址臂,以及每 turn 边界对本
|
|
10
|
-
* 会话那只会话盒的排水。
|
|
11
|
-
*
|
|
12
|
-
* ── 🔴 本位不是 HTTP 面 ────────────────────────────────────────────────────────────────────
|
|
13
|
-
* 上游没有为这一族能力单开任何新端点 —— 会话清单仍走既有的会话列举口。所以本位的消费方式是
|
|
14
|
-
* **渲染 / 预期**(要不要露出跨会话的入口),不是拿它去 gate 某一个动词的调用。
|
|
15
|
-
* ⚠️ 辖域只到「席」:上游另有一道装配期挂载判据(mailbox 必须显式声明跨进程安全),不齐时会在
|
|
16
|
-
* 装配期响亮拒挂并通告运维;本读面刻意不复判那一道 —— 复判 = 给同一件事立第二个判官。
|
|
17
|
-
*
|
|
18
|
-
* ── 🔴 四态,不是两态([honest-absence-not-fabricated-zero])──────────────────────────────────
|
|
19
|
-
* ① `unobserved` —— 本进程一次 caps 响应都没观测到。
|
|
20
|
-
* ② `not_reported` —— caps 观测到了,而回体上**没有** `peerLane` 这个键 ⇒ 老 worker(比 7.91.1 老)。
|
|
21
|
-
* 这台部署有没有跨会话车道**判不出**,不是「没有」。
|
|
22
|
-
* ③ `absent` —— 键在、值**明确是** `false`:这台部署没有挂跨会话目录席。**正面事实**,
|
|
23
|
-
* 与 `not_reported`(判不出)是两件不同的事,处置也相反。
|
|
24
|
-
* ④ `present` —— 键在、值为 `true`:席已挂。
|
|
25
|
-
* 值既不是 `true` 也不是 `false`(串 / 数 / null / 数组 / 对象)⇒ 畸形 ⇒ 删格(⇒ `unobserved`)。
|
|
26
|
-
* 🔴 三种「没有」(`unobserved` / `not_reported` / `absent`)**不许互折** —— 折起来会把「判不出」
|
|
27
|
-
* 说成「引擎明说没有」,或把「一次都没问过」说成「问过、答案是没有」。
|
|
28
|
-
*/
|
|
29
|
-
/** 四态读数。`unobserved` 由读口在这一格空缺时铸,不由投影铸。 */
|
|
30
1
|
export type PeerLaneReading = {
|
|
31
2
|
kind: 'unobserved';
|
|
32
3
|
} | {
|
|
@@ -36,27 +7,12 @@ export type PeerLaneReading = {
|
|
|
36
7
|
} | {
|
|
37
8
|
kind: 'present';
|
|
38
9
|
};
|
|
39
|
-
/** caps 回体 → 本格读数;畸形一律 `undefined`(= 这一格不写 ⇒ 读口答 `unobserved`)。 */
|
|
40
10
|
export declare function projectPeerLaneCapability(caps: unknown): PeerLaneReading | undefined;
|
|
41
|
-
/** 宿主 caps probe 的读面 tee 落点。绝不 throw;畸形 ⇒ 删格;`opts.generation` 关掉旧探测覆盖新读数的竞态。 */
|
|
42
11
|
export declare function noteEngineCapsForPeerLane(baseUrl: string, caps: unknown, opts?: {
|
|
43
12
|
generation?: number;
|
|
44
13
|
}): void;
|
|
45
|
-
/** 本进程观测到的读数;这一格空缺 ⇒ `{kind:'unobserved'}`。 */
|
|
46
14
|
export declare function observedPeerLane(baseUrl?: string | undefined): PeerLaneReading;
|
|
47
|
-
/**
|
|
48
|
-
* 「要不要在壳上露出跨会话入口(`ListAgents` / `SendMessage` 的 `session.<id>` 地址臂)」的判据
|
|
49
|
-
* 单源(三态):只有引擎明说挂了(`present`)才 `'yes'`;明说没挂(`absent`)⇒ `'no'`;
|
|
50
|
-
* **键缺席(`not_reported`)也是 `'no'`** —— 这一位的在场性本身就是版本信号,上游对缺席的成文语义是
|
|
51
|
-
* 「老 worker:本部署没有跨会话车道,按会话 id 投递按查无此会话拒」,所以缺席**不是**判不出,是一句
|
|
52
|
-
* 有内容的否定(与写键那一位「缺席 ⇒ 藏入口」同一条读法);只有本进程**从没观测过**(`unobserved`)
|
|
53
|
-
* 才是真的判不出 ⇒ `'unknown'`(别预判成有也别预判成没有)。
|
|
54
|
-
*/
|
|
55
15
|
export declare function peerLaneAvailable(reading: PeerLaneReading): 'yes' | 'no' | 'unknown';
|
|
56
|
-
/** doctor 那一行的 detail 串,唯一措辞真源。🔴 `unobserved` 那句不许暗示「有」或「没有」;`not_reported` 那句按上游成文语义说
|
|
57
|
-
* 「老 worker,没有跨会话车道」,并把「为什么缺席就是没有」(在场性即版本信号)说清,不让端把它读成第二种「判不出」。 */
|
|
58
16
|
export declare function peerLaneDoctorDetail(reading: PeerLaneReading): string;
|
|
59
|
-
/** 换代失效口(引擎温切成功后调):清成未观测。空串 ⇒ no-op;绝不 throw。 */
|
|
60
17
|
export declare function forgetPeerLaneReading(baseUrl: string | undefined): void;
|
|
61
|
-
/** 测试钩子。 */
|
|
62
18
|
export declare function __resetPeerLaneReadingsForTests(): void;
|
|
@@ -1,44 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* peerLaneCapability — `GET /v1/capabilities.peerLane`(server ≥7.91.1;sdk 9.8.1 尚未声明该键 ⇒ 结构读)
|
|
3
|
-
* 的三端共用读面(0.76.1 CC-102;与 sql / writeProtection / webSearch.backend / executionLane /
|
|
4
|
-
* approvalsStreamLive / deviceExecutor.management 各只兄弟同一套四态词汇)。
|
|
5
|
-
*
|
|
6
|
-
* ── 这一位答的是哪一个问题 ────────────────────────────────────────────────────────────────
|
|
7
|
-
* 「本部署的会话之间能不能互相发现并投递」——引擎的跨会话目录席是否已挂(会话枚举面 ∧ 耐久
|
|
8
|
-
* mailbox ∧ 该 mailbox 的收件人生命周期面,三缺一即缺席)。位为真时模型侧多出 `ListAgents`
|
|
9
|
-
* (列同一 principal 的其它会话)、`SendMessage` 的 `session.<id>` 地址臂,以及每 turn 边界对本
|
|
10
|
-
* 会话那只会话盒的排水。
|
|
11
|
-
*
|
|
12
|
-
* ── 🔴 本位不是 HTTP 面 ────────────────────────────────────────────────────────────────────
|
|
13
|
-
* 上游没有为这一族能力单开任何新端点 —— 会话清单仍走既有的会话列举口。所以本位的消费方式是
|
|
14
|
-
* **渲染 / 预期**(要不要露出跨会话的入口),不是拿它去 gate 某一个动词的调用。
|
|
15
|
-
* ⚠️ 辖域只到「席」:上游另有一道装配期挂载判据(mailbox 必须显式声明跨进程安全),不齐时会在
|
|
16
|
-
* 装配期响亮拒挂并通告运维;本读面刻意不复判那一道 —— 复判 = 给同一件事立第二个判官。
|
|
17
|
-
*
|
|
18
|
-
* ── 🔴 四态,不是两态([honest-absence-not-fabricated-zero])──────────────────────────────────
|
|
19
|
-
* ① `unobserved` —— 本进程一次 caps 响应都没观测到。
|
|
20
|
-
* ② `not_reported` —— caps 观测到了,而回体上**没有** `peerLane` 这个键 ⇒ 老 worker(比 7.91.1 老)。
|
|
21
|
-
* 这台部署有没有跨会话车道**判不出**,不是「没有」。
|
|
22
|
-
* ③ `absent` —— 键在、值**明确是** `false`:这台部署没有挂跨会话目录席。**正面事实**,
|
|
23
|
-
* 与 `not_reported`(判不出)是两件不同的事,处置也相反。
|
|
24
|
-
* ④ `present` —— 键在、值为 `true`:席已挂。
|
|
25
|
-
* 值既不是 `true` 也不是 `false`(串 / 数 / null / 数组 / 对象)⇒ 畸形 ⇒ 删格(⇒ `unobserved`)。
|
|
26
|
-
* 🔴 三种「没有」(`unobserved` / `not_reported` / `absent`)**不许互折** —— 折起来会把「判不出」
|
|
27
|
-
* 说成「引擎明说没有」,或把「一次都没问过」说成「问过、答案是没有」。
|
|
28
|
-
*/
|
|
29
1
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
30
2
|
import { createEngineCapReader } from './engineCapReader.js';
|
|
31
|
-
/** caps 回体 → 本格读数;畸形一律 `undefined`(= 这一格不写 ⇒ 读口答 `unobserved`)。 */
|
|
32
3
|
export function projectPeerLaneCapability(caps) {
|
|
33
4
|
if (caps === null || typeof caps !== 'object')
|
|
34
5
|
return undefined;
|
|
35
|
-
// 0.77.0 整族改齐:① 非对象 / 数组 caps 不是能力表 ⇒ 畸形(投影答 undefined ⇒ 删格 ⇒ 读口答 unobserved),不再答 not_reported
|
|
36
|
-
// (那是把「取不到」冒充「报了但没提」);② 在场判据改 hasOwn —— 原型链上的同名键永远不会被序列化上 wire,读成在场 = 凭空造一格。
|
|
37
6
|
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
38
7
|
return undefined;
|
|
39
8
|
if (!Object.hasOwn(caps, 'peerLane'))
|
|
40
9
|
return { kind: 'not_reported' };
|
|
41
|
-
// 🔴 只读一次:在场判据与取值同一次读(变化的 getter 不会让两处判断看到两个不同的值)。
|
|
42
10
|
const v = caps.peerLane;
|
|
43
11
|
if (v === undefined)
|
|
44
12
|
return { kind: 'not_reported' };
|
|
@@ -46,33 +14,17 @@ export function projectPeerLaneCapability(caps) {
|
|
|
46
14
|
return undefined;
|
|
47
15
|
return v ? { kind: 'present' } : { kind: 'absent' };
|
|
48
16
|
}
|
|
49
|
-
/**
|
|
50
|
-
* 本格的 per-baseUrl 读账 + tee / 读口 / 失效口 / 测试钩四口 —— 能力位读器**共用同一份实现**
|
|
51
|
-
* ({@link createEngineCapReader});本文件只留这一格真正不同的部分:投影函数
|
|
52
|
-
* {@link projectPeerLaneCapability}、doctor 措辞表,以及本位自己的判据助手。
|
|
53
|
-
* 🔴 Map 在工厂闭包里,**一只读器一张**:收到读不懂的回体只删自己这一格,绝不连坐别的能力面。
|
|
54
|
-
*/
|
|
55
17
|
const reader = createEngineCapReader({
|
|
56
18
|
name: 'peerLane',
|
|
57
19
|
project: projectPeerLaneCapability,
|
|
58
20
|
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
59
21
|
});
|
|
60
|
-
/** 宿主 caps probe 的读面 tee 落点。绝不 throw;畸形 ⇒ 删格;`opts.generation` 关掉旧探测覆盖新读数的竞态。 */
|
|
61
22
|
export function noteEngineCapsForPeerLane(baseUrl, caps, opts) {
|
|
62
23
|
reader.note(baseUrl, caps, opts);
|
|
63
24
|
}
|
|
64
|
-
/** 本进程观测到的读数;这一格空缺 ⇒ `{kind:'unobserved'}`。 */
|
|
65
25
|
export function observedPeerLane(baseUrl = engineWireTarget()?.baseUrl) {
|
|
66
26
|
return reader.observed(baseUrl);
|
|
67
27
|
}
|
|
68
|
-
/**
|
|
69
|
-
* 「要不要在壳上露出跨会话入口(`ListAgents` / `SendMessage` 的 `session.<id>` 地址臂)」的判据
|
|
70
|
-
* 单源(三态):只有引擎明说挂了(`present`)才 `'yes'`;明说没挂(`absent`)⇒ `'no'`;
|
|
71
|
-
* **键缺席(`not_reported`)也是 `'no'`** —— 这一位的在场性本身就是版本信号,上游对缺席的成文语义是
|
|
72
|
-
* 「老 worker:本部署没有跨会话车道,按会话 id 投递按查无此会话拒」,所以缺席**不是**判不出,是一句
|
|
73
|
-
* 有内容的否定(与写键那一位「缺席 ⇒ 藏入口」同一条读法);只有本进程**从没观测过**(`unobserved`)
|
|
74
|
-
* 才是真的判不出 ⇒ `'unknown'`(别预判成有也别预判成没有)。
|
|
75
|
-
*/
|
|
76
28
|
export function peerLaneAvailable(reading) {
|
|
77
29
|
if (reading.kind === 'present')
|
|
78
30
|
return 'yes';
|
|
@@ -80,8 +32,6 @@ export function peerLaneAvailable(reading) {
|
|
|
80
32
|
return 'no';
|
|
81
33
|
return 'unknown';
|
|
82
34
|
}
|
|
83
|
-
/** doctor 那一行的 detail 串,唯一措辞真源。🔴 `unobserved` 那句不许暗示「有」或「没有」;`not_reported` 那句按上游成文语义说
|
|
84
|
-
* 「老 worker,没有跨会话车道」,并把「为什么缺席就是没有」(在场性即版本信号)说清,不让端把它读成第二种「判不出」。 */
|
|
85
35
|
export function peerLaneDoctorDetail(reading) {
|
|
86
36
|
switch (reading.kind) {
|
|
87
37
|
case 'unobserved':
|
|
@@ -94,11 +44,9 @@ export function peerLaneDoctorDetail(reading) {
|
|
|
94
44
|
return 'cross-session lane on — this engine can discover and deliver across sessions for the same caller';
|
|
95
45
|
}
|
|
96
46
|
}
|
|
97
|
-
/** 换代失效口(引擎温切成功后调):清成未观测。空串 ⇒ no-op;绝不 throw。 */
|
|
98
47
|
export function forgetPeerLaneReading(baseUrl) {
|
|
99
48
|
reader.forget(baseUrl);
|
|
100
49
|
}
|
|
101
|
-
/** 测试钩子。 */
|
|
102
50
|
export function __resetPeerLaneReadingsForTests() {
|
|
103
51
|
reader.__resetForTests();
|
|
104
52
|
}
|
|
@@ -1,33 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 引擎**真会铸**的规则 lint 拒因码(core `PermissionRuleIssue.code`,7.9.x = 十五码)。
|
|
3
|
-
* 顺序与 core 声明同源。
|
|
4
|
-
* 🔴 这是一份**抄件**,不是本包的意见 —— 改它必须同 commit 附 core 坐标,且门会先红。
|
|
5
|
-
|
|
6
|
-
* 🔴 形制:`Object.freeze` 的数组,**不是**只在类型面只读的 `readonly T[]` —— 后者一行 `.splice()`
|
|
7
|
-
* 就能改,而公面消费者拿到的正是这个实例(本仓已定谳的病形,同 `RESUME_RETRY_LATER_CODES`)。
|
|
8
|
-
*/
|
|
9
1
|
export declare const PERMISSION_RULE_ISSUE_CODES: readonly string[];
|
|
10
|
-
/**
|
|
11
|
-
* 在 core 的**声明**联合里还留着、但引擎**再也不铸**的码(记账用,不进呈现表)。
|
|
12
|
-
* · `unsupported.unknown_param` —— core 7.8.0(B15)改名成 `unsupported.param_unknown`,
|
|
13
|
-
* 联合里的旧名没删干净。
|
|
14
|
-
* 🔴 这张表**不是**给消费端查的,它是给门的:`表 ∪ 退役表 == 声明联合` 这条等式让「上游删掉那一员」
|
|
15
|
-
* 与「上游又留下一个新的 stale 成员」都当场红。查码一律查 {@link PERMISSION_RULE_ISSUE_CODES}。
|
|
16
|
-
* ⚠️ 另有一个更早的退役名 `unsupported.bash_prefix_rules_store`(sdk README 记的减员)——它在 core
|
|
17
|
-
* 7.9.x 的**声明里已经没有了**,所以不登记在这里(登记一个两个真源都不认的名字,门会红)。
|
|
18
|
-
|
|
19
|
-
* 🔴 形制:`Object.freeze` 的数组,**不是**只在类型面只读的 `readonly T[]` —— 后者一行 `.splice()`
|
|
20
|
-
* 就能改,而公面消费者拿到的正是这个实例(本仓已定谳的病形,同 `RESUME_RETRY_LATER_CODES`)。
|
|
21
|
-
*/
|
|
22
2
|
export declare const RETIRED_PERMISSION_RULE_ISSUE_CODES: readonly string[];
|
|
23
|
-
/**
|
|
24
|
-
* 一个 lint 拒因 → 一句人话(+ 引擎自己那句更具体的散文)。**唯一措辞铸点**(三端共用;端零自拼)。
|
|
25
|
-
*
|
|
26
|
-
* 🔴 表外码的那一句说的是「**这个码比这一端新**」——码表的属主是引擎,加码不该被渲成故障;
|
|
27
|
-
* 原样带上那个码(运维要拿它去问上游),并**照样带上 `message`**:码读不懂不代表引擎那句话
|
|
28
|
-
* 读不懂,而那句话往往才是能动手改的那条信息。
|
|
29
|
-
* 🔴 `message` 是**散文不是码**:只渲染、呈前消毒 + 封长,绝不做等值匹配、绝不当分类位。
|
|
30
|
-
* 🔴 坏码 / 坏 message 一律不抛 —— 这条路径跑在「用户规则写错了」的那一刻,读器自己再抛一次
|
|
31
|
-
* 只会把一个可以说清的错误换成一个说不清的崩。
|
|
32
|
-
*/
|
|
33
3
|
export declare function permissionRuleIssueDetail(code: unknown, message: unknown): string;
|
|
@@ -1,48 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* src/permissionRuleIssue.ts — 权限规则 lint 的**拒因码表 + 唯一措辞铸点**
|
|
3
|
-
* (0.63.0;L-162 ②;engine >=7.67.0 / core 7.9.x)。
|
|
4
|
-
*
|
|
5
|
-
* -- 这张表为什么是**铸**的而不是**取**的(以及它什么时候该被换掉)---------------------------
|
|
6
|
-
* 引擎在装配一份权限规则表时,对每条它不接的规则出一个 `{rule, code, message}`。`code` 是**机读
|
|
7
|
-
* 的处置分类**,`message` 是给人看的**散文**。sdk 8.8.0 **既无 spec schema 也无导出型**(sdk 自己的
|
|
8
|
-
* README 在「如实登记(本版没做的)」一节里写了这一格),所以本包没有可以 `import` 的上游码表。
|
|
9
|
-
* => 按引擎真字节铸一张。
|
|
10
|
-
*
|
|
11
|
-
* 🔴 **候上游导出即换**:sdk 哪天导出 `PermissionRuleIssue` 的码表(型或 `as const` 值表),本表
|
|
12
|
-
* 应当**整只退役**、改成从 sdk 取(与本包对 `RULE_OFFER_MATCHES` 那几张表的处置同形)。
|
|
13
|
-
* 给下游的反漂移锚:`dts-pattern` 盯 sdk 的 `PermissionRuleIssue` 上出现 `code` 声明。
|
|
14
|
-
* 🔴 **镜像的代价用门付,不用「记得同步」付**:`run-permission-rule-issue-codes-test.mjs` 直接读
|
|
15
|
-
* 实装 `@sema-agent/core` 的两份产物做双向对账(见下一段),core 一动这里就先红。
|
|
16
|
-
*
|
|
17
|
-
* -- 两个真源,而且它们**不相等** ------------------------------------------------------------
|
|
18
|
-
* (1) core 的 `permission-rules.js` 里**真被铸出来**的码 —— 这是 wire 上真会到达消费端的集合,
|
|
19
|
-
* {@link PERMISSION_RULE_ISSUE_CODES} 与它逐码等值;
|
|
20
|
-
* (2) core 的 `permission-rules.d.ts` 里 `code` 的**声明**联合 —— 它比 (1) 多一员
|
|
21
|
-
* `unsupported.unknown_param`。core 自己的 CHANGELOG(B15)写着那一员已**改名**成
|
|
22
|
-
* `unsupported.param_unknown`,联合里的旧名只是没删干净。收它进呈现表 = 复活一个引擎再也
|
|
23
|
-
* 不会铸的码(一个永不触发的分支),所以它单列在 {@link RETIRED_PERMISSION_RULE_ISSUE_CODES}
|
|
24
|
-
* 里记账,门按 `表 ∪ 退役表 == 声明联合` 对账。
|
|
25
|
-
*
|
|
26
|
-
* -- 两族码的**处置**不同,措辞必须说得出来 --------------------------------------------------
|
|
27
|
-
* · `invalid.*` = 这条规则**写错了**(语法/语义)—— 下一步是改规则;
|
|
28
|
-
* · `unsupported.*` = 规则本身合法,但**这条车道不接**(CC 里合法而 v1 不支持的 lane,或该去
|
|
29
|
-
* 另一个面落的常驻同意)—— 下一步是换一种写法、或把它落到规则店而不是策略折叠里。
|
|
30
|
-
* 两族绝不共用一句 —— 上游把它们分成两个前缀,正是因为「以为挡住了」比没挡更危险
|
|
31
|
-
* (`Bash(npm run:*)` 被当成 generic 参数规则接受后永不匹配,是这条面上最危险的失败形态)。
|
|
32
|
-
*
|
|
33
|
-
* -- UNTRUSTED --------------------------------------------------------------------------------
|
|
34
|
-
* `message` 是引擎/用户 settings 侧的内容(里面会带用户自己写的规则文本):只渲染,呈前**先转义、
|
|
35
|
-
* 后按转义结果封长**(与本包其余 detail 铸点同一条纪律),绝不当码用、绝不做等值匹配。
|
|
36
|
-
*/
|
|
37
1
|
import { capForDisplay, escapeDisplayControlChars } from './fleetTaskDesc.js';
|
|
38
|
-
/**
|
|
39
|
-
* 引擎**真会铸**的规则 lint 拒因码(core `PermissionRuleIssue.code`,7.9.x = 十五码)。
|
|
40
|
-
* 顺序与 core 声明同源。
|
|
41
|
-
* 🔴 这是一份**抄件**,不是本包的意见 —— 改它必须同 commit 附 core 坐标,且门会先红。
|
|
42
|
-
|
|
43
|
-
* 🔴 形制:`Object.freeze` 的数组,**不是**只在类型面只读的 `readonly T[]` —— 后者一行 `.splice()`
|
|
44
|
-
* 就能改,而公面消费者拿到的正是这个实例(本仓已定谳的病形,同 `RESUME_RETRY_LATER_CODES`)。
|
|
45
|
-
*/
|
|
46
2
|
export const PERMISSION_RULE_ISSUE_CODES = Object.freeze([
|
|
47
3
|
'invalid.empty_tool',
|
|
48
4
|
'invalid.paren',
|
|
@@ -60,26 +16,9 @@ export const PERMISSION_RULE_ISSUE_CODES = Object.freeze([
|
|
|
60
16
|
'unsupported.mcp_paren',
|
|
61
17
|
'unsupported.covering_paren',
|
|
62
18
|
]);
|
|
63
|
-
/**
|
|
64
|
-
* 在 core 的**声明**联合里还留着、但引擎**再也不铸**的码(记账用,不进呈现表)。
|
|
65
|
-
* · `unsupported.unknown_param` —— core 7.8.0(B15)改名成 `unsupported.param_unknown`,
|
|
66
|
-
* 联合里的旧名没删干净。
|
|
67
|
-
* 🔴 这张表**不是**给消费端查的,它是给门的:`表 ∪ 退役表 == 声明联合` 这条等式让「上游删掉那一员」
|
|
68
|
-
* 与「上游又留下一个新的 stale 成员」都当场红。查码一律查 {@link PERMISSION_RULE_ISSUE_CODES}。
|
|
69
|
-
* ⚠️ 另有一个更早的退役名 `unsupported.bash_prefix_rules_store`(sdk README 记的减员)——它在 core
|
|
70
|
-
* 7.9.x 的**声明里已经没有了**,所以不登记在这里(登记一个两个真源都不认的名字,门会红)。
|
|
71
|
-
|
|
72
|
-
* 🔴 形制:`Object.freeze` 的数组,**不是**只在类型面只读的 `readonly T[]` —— 后者一行 `.splice()`
|
|
73
|
-
* 就能改,而公面消费者拿到的正是这个实例(本仓已定谳的病形,同 `RESUME_RETRY_LATER_CODES`)。
|
|
74
|
-
*/
|
|
75
19
|
export const RETIRED_PERMISSION_RULE_ISSUE_CODES = Object.freeze(['unsupported.unknown_param']);
|
|
76
|
-
/** `message` 上屏封长(UTF-16 单元,按**转义后**长度算;它是一句话,给得比词宽)。 */
|
|
77
20
|
const ISSUE_MESSAGE_MAX = 200;
|
|
78
|
-
/**
|
|
79
|
-
* 逐码一句人话。**十五句刻意逐字互异**:每一条对写规则的人是一条不同的下一步。
|
|
80
|
-
*/
|
|
81
21
|
const ISSUE_SENTENCES = Object.freeze({
|
|
82
|
-
// -- invalid.*:规则写错了 ------------------------------------------------------------------
|
|
83
22
|
'invalid.empty_tool': 'this rule is invalid: it names no tool',
|
|
84
23
|
'invalid.paren': 'this rule is invalid: its parentheses do not parse (escape a literal one as \\( or \\))',
|
|
85
24
|
'invalid.param_split': 'this rule is invalid: the part before the colon is not a parameter name',
|
|
@@ -87,7 +26,6 @@ const ISSUE_SENTENCES = Object.freeze({
|
|
|
87
26
|
'invalid.primary_field': "this rule is invalid: it patterns the tool's primary field, which matches the whole trimmed string rather than a prefix",
|
|
88
27
|
'invalid.cap_exceeded': 'this rule set is invalid: it is over one of the deployment caps (rule count, rule length, pattern length, or star count)',
|
|
89
28
|
'invalid.command_rule': 'this rule is invalid: the command pattern was rejected by the command-rule validator',
|
|
90
|
-
// -- unsupported.*:规则合法,但这条车道不接 ------------------------------------------------
|
|
91
29
|
'unsupported.bash_prefix': 'a standing approval for a command belongs in the persisted-rule store, so this allow rule is not supported here (deny and ask rules with the same shape do compile)',
|
|
92
30
|
'unsupported.param_unknown': 'this parameter rule is not supported: the tool carries no such parameter, so it could never match',
|
|
93
31
|
'unsupported.param_non_scalar': 'this parameter rule is not supported: that parameter holds an object or an array, so it could never match',
|
|
@@ -97,27 +35,11 @@ const ISSUE_SENTENCES = Object.freeze({
|
|
|
97
35
|
'unsupported.mcp_paren': 'a parenthesised parameter rule is not supported on an MCP tool name',
|
|
98
36
|
'unsupported.covering_paren': 'a parenthesised parameter rule is not supported on a covering protocol name — the parameter grammar is keyed by an exact tool name, so no mounted tool could ever bear it',
|
|
99
37
|
});
|
|
100
|
-
/**
|
|
101
|
-
* 一个 lint 拒因 → 一句人话(+ 引擎自己那句更具体的散文)。**唯一措辞铸点**(三端共用;端零自拼)。
|
|
102
|
-
*
|
|
103
|
-
* 🔴 表外码的那一句说的是「**这个码比这一端新**」——码表的属主是引擎,加码不该被渲成故障;
|
|
104
|
-
* 原样带上那个码(运维要拿它去问上游),并**照样带上 `message`**:码读不懂不代表引擎那句话
|
|
105
|
-
* 读不懂,而那句话往往才是能动手改的那条信息。
|
|
106
|
-
* 🔴 `message` 是**散文不是码**:只渲染、呈前消毒 + 封长,绝不做等值匹配、绝不当分类位。
|
|
107
|
-
* 🔴 坏码 / 坏 message 一律不抛 —— 这条路径跑在「用户规则写错了」的那一刻,读器自己再抛一次
|
|
108
|
-
* 只会把一个可以说清的错误换成一个说不清的崩。
|
|
109
|
-
*/
|
|
110
38
|
export function permissionRuleIssueDetail(code, message) {
|
|
111
|
-
// 🔴 自有属性判据(异源对抗复审 [medium]):`Object.freeze` 不移除原型,`ISSUE_SENTENCES['toString']`
|
|
112
|
-
// 会命中 `Object.prototype` 上的函数并被当成「一句话」交出去。
|
|
113
39
|
const known = typeof code === 'string' && Object.hasOwn(ISSUE_SENTENCES, code) ? ISSUE_SENTENCES[code] : undefined;
|
|
114
40
|
const text = typeof message === 'string' && message.length > 0
|
|
115
41
|
? capForDisplay(message, ISSUE_MESSAGE_MAX)
|
|
116
42
|
: '';
|
|
117
|
-
// 🔴 **码原样带上,不封长**(0.63.1,G-11):`code` 是**引擎产的标识符**,不是散文 —— 运维要拿它
|
|
118
|
-
// 整只去问上游,截一半的码谁也查不出来,而且长得像一个完整答案。呈前只做**不可见字符消毒**
|
|
119
|
-
// (走本包同一只 {@link escapeDisplayControlChars};不封长 ≠ 不消毒)。`message` 半场的封长
|
|
120
|
-
// 照旧:那半场确实是散文,屏上的列宽预算是给它的。两半场判据分家是刻意的。
|
|
121
43
|
const codeWord = typeof code === 'string' && code.length > 0 ? escapeDisplayControlChars(code) : '(no code)';
|
|
122
44
|
const head = known !== undefined
|
|
123
45
|
? known
|