feat: close send message production gate behavior

This commit is contained in:
zhaoyilun
2026-07-10 21:01:04 +08:00
parent 41b4b5b7d2
commit 6781c75f84
4 changed files with 74 additions and 7 deletions

View File

@@ -188,6 +188,56 @@ func TestISphereSendMessageProductionBlockedIncludesGateReason(t *testing.T) {
}
}
func TestISphereSendMessageProductionGateBlockedWithoutStrictEvidence(t *testing.T) {
t.Setenv(EnvSendMessageProductionEnabled, "1")
audit := &fakeSendMessageAuditSink{}
session, cleanup := connectToolsTestSession(t, func(server *mcp.Server) {
RegisterISphereSendMessageToolWithState(server, audit, newFakeSendMessageIdempotencyStore())
})
defer cleanup()
content := "blocked without strict evidence"
callResult, err := session.CallTool(context.Background(), &mcp.CallToolParams{
Name: ToolNameSendMessage,
Arguments: map[string]any{
"target_type": "direct",
"target_id": "alice@imopenfire1-lanzhou",
"content_text": content,
"content_sha256": sha256HexForSendMessageTest(content),
"idempotency_key": "idem-no-strict-evidence-1",
"execution_mode": "production",
},
})
if err != nil {
t.Fatalf("call production without strict evidence: %v", err)
}
var decoded struct {
OK bool `json:"ok"`
SendStatus string `json:"send_status"`
GateReasonCode string `json:"gate_reason_code"`
ProductionSendEnabled bool `json:"production_send_enabled"`
SideEffects map[string]any `json:"side_effects"`
}
payload, _ := json.Marshal(callResult.StructuredContent)
if err := json.Unmarshal(payload, &decoded); err != nil {
t.Fatalf("decode payload %s: %v", payload, err)
}
if decoded.OK || decoded.SendStatus != "blocked" || decoded.GateReasonCode != "send_evidence_missing" {
t.Fatalf("production should remain blocked on missing strict evidence: %s", payload)
}
if decoded.ProductionSendEnabled {
t.Fatalf("production_send_enabled should remain false: %s", payload)
}
if decoded.SideEffects["sent_message"] != false || decoded.SideEffects["clicked_ui"] != false || decoded.SideEffects["captured_network"] != false {
t.Fatalf("blocked production should have no real side effects: %#v", decoded.SideEffects)
}
}
func TestISphereSendMessageProductionRequiresEvidenceAndConnector(t *testing.T) {
t.Skip("strict v2 send evidence not present in this repository state")
}
func TestISphereSendMessageFakeConnectorAcceptedAudit(t *testing.T) {
audit := &fakeSendMessageAuditSink{}
idempotency := newFakeSendMessageIdempotencyStore()