From 05b29a381ce4391bd65efb0e2cee706be2b2e6da Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 26 Oct 2026 23:35:15 -0500 Subject: [PATCH] test(evals): bind one genuine Slack distractor setup exchange --- tests/runner-e2e/chat-catalog-contract.ts | 4 +- tests/runner-e2e/chat-catalog-flow.ts | 7 ++- tests/runner-e2e/chat-slack-ingress.test.ts | 18 +++++-- tests/runner-e2e/chat-slack-ingress.ts | 59 +++++++++++++++------ 4 files changed, 66 insertions(+), 22 deletions(-) diff --git a/tests/runner-e2e/chat-catalog-contract.ts b/tests/runner-e2e/chat-catalog-contract.ts index e52f22aadb4..beb6001c2b9 100644 --- a/tests/runner-e2e/chat-catalog-contract.ts +++ b/tests/runner-e2e/chat-catalog-contract.ts @@ -40,7 +40,7 @@ export interface ChatCompanionResult { messages: Array<{ role: "system" | "user" | "assistant" | "tool"; content: string }>; providerResponseIds: string[]; toolCalls: Array<{ name: string; arguments: unknown; result: unknown }>; links: string[]; } -export interface ChatSlackIngress { kind: "native-slack-thread"; maximumProviderCalls: 20; ingressTimeoutMs: 120000 } +export interface ChatSlackIngress { kind: "native-slack-thread"; maximumProviderCalls: 20; ingressTimeoutMs: 120000; setupThread?: "same-agent-distractor" } export interface ChatSlackIngressReceipt { query: string; endpointId: string; conversationId: string; issueId: string; humanCommentId: string; linkedPaperclipUserId: string; providerCalls: number; provider: { workspaceId: string; channelId: string; threadId: string; canonicalMessageId: string; senderUserId: string }; @@ -56,6 +56,8 @@ export interface ChatCatalogCase { installedSource?: "published-global-npm"; journeyKind?: "agent-chat" | "scoped-external-assistant" | "native-slack-thread"; slackIngress?: ChatSlackIngress; + /** Only reply-in-thread: one real other-source setup exchange, included in total native bounds. */ + dispatchSlackOtherThread?(context: ChatCatalogContext, state: Record, input: { query: string; signal: AbortSignal }): Promise; dispatchSlackQuery?(context: ChatCatalogContext, state: Record, input: { query: string; signal: AbortSignal }): Promise; companionSurface?: ChatCompanionSurface; runCompanionSurface?(context: ChatCatalogContext, state: Record, input: { query: string; signal: AbortSignal }): Promise; diff --git a/tests/runner-e2e/chat-catalog-flow.ts b/tests/runner-e2e/chat-catalog-flow.ts index dacb82dc9da..60d5125d71b 100644 --- a/tests/runner-e2e/chat-catalog-flow.ts +++ b/tests/runner-e2e/chat-catalog-flow.ts @@ -1,4 +1,4 @@ -import { completeNativeSlackFileConditional, dispatchNativeSlackIngress, slackNativeRunCheck } from "./chat-slack-ingress.js"; +import { completeNativeSlackFileConditional, dispatchNativeSlackIngress, prepareNativeSlackOtherThread, slackOtherThreadBoundaryMatches, slackNativeRunCheck } from "./chat-slack-ingress.js"; import { runScopedCompanionSurface } from "./chat-companion-surface.js"; import { chatQueryWithAttachments, resolveChatQueryAttachments, verifyChatQueryAttachments, type ChatQueryAttachmentReceipt } from "./chat-query-attachments.js"; import { chatCatalogAllowedRunStatuses, gradeChatCatalogRuns } from "./chat-catalog-run-policy.js"; @@ -100,6 +100,7 @@ export async function runChatCatalogFlow(context: ChatCatalogContext) { && policy.amount === 500 && policy.hardStopEnabled && policy.isActive && policy.unpricedUsagePolicy === "allow")), "Public funding policy persisted").toBe(true); await input.evidence("chat-catalog-funding.json", { scopes, mode: implementation.setupPolicy?.funding ?? "standard", policies: funding.policies.filter(policy => scopes.some(scope => scope.scopeType === policy.scopeType && scope.scopeId === policy.scopeId)), setupProbeUsage: "unknown; production hello probes are outside heartbeat accounting" }); + if (slack && implementation.slackIngress?.setupThread === "same-agent-distractor") await prepareNativeSlackOtherThread(context,implementation,state,deadlineAt); await input.evidence("chat-catalog-setup.json", { scenario, state, inventoryDigest: chatCatalogInventoryDigest, oracleVersion: implementation.oracleVersion, expectedRunCount: implementation.expectedRunCount, minimumRunCount: implementation.minimumRunCount, turnTimeoutMs: implementation.turnTimeoutMs, @@ -118,7 +119,9 @@ export async function runChatCatalogFlow(context: ChatCatalogContext) { expectedHumanMessageCount: implementation.expectedHumanMessageCount ?? 1, expectedRunCount: implementation.expectedRunCount }); await input.evidence("chat-catalog-query.json", { query: scenario.query, expectedOutcome: implementation.queryOutcome ?? "persisted", journeyKind: implementation.journeyKind ?? "agent-chat" }); if (slack) { - if (setupBoundary.runIds.length || setupBoundary.humanCommentIds.length) throw new Error("Native Slack setup cannot admit canonical or unrelated work"); + const other=state.slackOtherThreadSetupReceipt as (import("./chat-catalog-contract.js").ChatSlackIngressReceipt & {runId:string})|undefined; + const declaredOther=implementation.scenarioId==="chat-channels.reply-in-thread"&&implementation.slackIngress?.setupThread==="same-agent-distractor"; + if (setupBoundary.humanCommentIds.length || (declaredOther ? !other || !slackOtherThreadBoundaryMatches({receipt:other,runs:setupConversation.runs,companyId:input.fixtures.company.id,agentId:input.fixtures.agent.id}) : setupBoundary.runIds.length!==0)) throw new Error("Native Slack setup cannot admit undeclared canonical or unrelated work"); state.slackIngressReceipt = await dispatchNativeSlackIngress(context, implementation, state, deadlineAt); await input.page.goto(new URL(`/${input.fixtures.company.issuePrefix}/issues/${context.issue()!.id}`, input.api.baseURL).href); if (implementation.scenarioId === "chat-channels.channel-file") await completeNativeSlackFileConditional(context, implementation, state, deadlineAt); diff --git a/tests/runner-e2e/chat-slack-ingress.test.ts b/tests/runner-e2e/chat-slack-ingress.test.ts index f5d977e873b..e598f5bdbc9 100644 --- a/tests/runner-e2e/chat-slack-ingress.test.ts +++ b/tests/runner-e2e/chat-slack-ingress.test.ts @@ -1,11 +1,11 @@ import { describe, expect, it } from "vitest"; import { loadChatCatalogImplementation, type ChatCatalogDescriptor } from "./chat-catalog-registry.js"; -import { sameSlackThreadNewMessage, slackIngressReceiptMatches, validSlackIngressDeclaration, slackNativeRunCheck, verifySelectedSlackSender } from "./chat-slack-ingress.js"; +import { sameSlackThreadNewMessage, slackIngressReceiptMatches, validSlackIngressDeclaration, slackNativeRunCheck, verifySelectedSlackSender, slackOtherThreadBoundaryMatches, slackOtherThreadSetupQuery } from "./chat-slack-ingress.js"; import type { ChatCatalogContext, ChatSlackIngressReceipt } from "./chat-catalog-contract.js"; import type { ChatConversation, ChatEndpoint, ExternalChannelBindingSummary } from "../../packages/shared/src/types/chat-channels.js"; import type { IssueComment } from "../../packages/shared/src/types/issue.js"; const query = "What happened in this thread?"; -const metadata = { scenarioId: "chat-channels.reply-in-thread", journeyKind: "native-slack-thread", slackIngress: { kind: "native-slack-thread" as const, maximumProviderCalls: 20 as const, ingressTimeoutMs: 120000 as const }, expectedRunCount: 3, minimumRunCount: 1, expectedHumanMessageCount: 1, turnTimeoutMs: 120000, attemptTimeoutMs: 600000 }; +const metadata = { scenarioId: "chat-channels.reply-in-thread", journeyKind: "native-slack-thread", slackIngress: { kind: "native-slack-thread" as const, maximumProviderCalls: 20 as const, ingressTimeoutMs: 120000 as const, setupThread:"same-agent-distractor" as const }, expectedRunCount: 4, minimumRunCount: 2, expectedHumanMessageCount: 1, turnTimeoutMs: 120000, attemptTimeoutMs: 600000 }; function input() { const receipt: ChatSlackIngressReceipt = { query, endpointId: "endpoint", conversationId: "conversation", issueId: "issue", humanCommentId: "comment", linkedPaperclipUserId: "person", providerCalls: 2, provider: { workspaceId: "T123", channelId: "C123", threadId: "1234567890.123456", canonicalMessageId: "1234567891.123456", senderUserId: "U123" } }; return { receipt, query, companyId: "company", agentId: "agent", endpoint: { id: "endpoint", companyId: "company", assignedAgentId: "agent", provider: "slack", providerAccountId: "T123" } as ChatEndpoint, @@ -60,7 +60,7 @@ describe("only real declared Slack canonical ingress", () => { const actual = { ...implementation, dispatchSlackQuery: async () => input().receipt }; await expect(loadChatCatalogImplementation(descriptor, async () => ({ slackCases: [actual] }))).resolves.toBe(actual); await expect(loadChatCatalogImplementation(descriptor, async () => ({ slackCases: [{ ...actual, act: async () => {} }] }))).rejects.toThrow("actual Slack ingress"); - const fileDescriptor: ChatCatalogDescriptor = { ...descriptor, scenarioId: "chat-channels.channel-file", expectedRunCount: 6, minimumRunCount: 2, expectedHumanMessageCount: 2, attemptTimeoutMs: 900000 }; + const fileDescriptor: ChatCatalogDescriptor = { ...descriptor, scenarioId: "chat-channels.channel-file", slackIngress:{kind:"native-slack-thread" as const,maximumProviderCalls:20 as const,ingressTimeoutMs:120000 as const}, expectedRunCount: 6, minimumRunCount: 2, expectedHumanMessageCount: 2, attemptTimeoutMs: 900000 }; const file = { ...actual, ...fileDescriptor }; await expect(loadChatCatalogImplementation(fileDescriptor, async () => ({ slackCases: [file] }))).rejects.toThrow("supported and unsupported transfer phases"); const completeFile = { ...file, verifySlackSupportedTransfer: async () => ({ passed: true, checks: [{ id: "actual-transfer", passed: true, detail: "Independent phase-specific byte/egress evidence" }] }), dispatchSlackUnsupportedFile: async () => input().receipt }; @@ -68,7 +68,7 @@ describe("only real declared Slack canonical ingress", () => { }); it("requires a separate same-thread canonical upload and declared two-phase bounds for the file conditional", () => { - const file = { ...metadata, scenarioId: "chat-channels.channel-file", expectedRunCount: 6, minimumRunCount: 2, expectedHumanMessageCount: 2, attemptTimeoutMs: 900000 }; + const file = { ...metadata, scenarioId: "chat-channels.channel-file", slackIngress:{kind:"native-slack-thread" as const,maximumProviderCalls:20 as const,ingressTimeoutMs:120000 as const}, expectedRunCount: 6, minimumRunCount: 2, expectedHumanMessageCount: 2, attemptTimeoutMs: 900000 }; expect(validSlackIngressDeclaration(file)).toBe(true); expect(validSlackIngressDeclaration({ ...file, expectedHumanMessageCount: 1 })).toBe(false); expect(validSlackIngressDeclaration({ ...metadata, scenarioId: "chat-channels.channel-file" })).toBe(false); @@ -89,3 +89,13 @@ describe("only real declared Slack canonical ingress", () => { expect(slackNativeRunCheck(ctx, [{ ...run, contextSnapshot: { issueId: "other" } }]).passed).toBe(false); }); }); + +it("binds exactly one other-source setup native without treating that source's human as canonical setup history",()=>{ + const receipt={...input().receipt,query:slackOtherThreadSetupQuery,runId:"setup-native"}; + const run={id:"setup-native",companyId:"company",agentId:"agent",runtimeMode:"native",status:"succeeded",contextSnapshot:{issueId:"issue"}}; + const value={receipt,runs:[run],companyId:"company",agentId:"agent"}; + expect(slackOtherThreadBoundaryMatches(value)).toBe(true); + for(const wrong of [{...value,runs:[]},{...value,runs:[run,{...run,id:"unrelated"}]},{...value,runs:[{...run,contextSnapshot:{issueId:"other-source"}}]},{...value,runs:[{...run,agentId:"other-agent"}]},{...value,runs:[{...run,status:"running"}]},{...value,receipt:{...receipt,query:"Undeclared setup instruction"}},{...value,sourceIssueId:"issue"}])expect(slackOtherThreadBoundaryMatches(wrong)).toBe(false); + expect(validSlackIngressDeclaration({...metadata,slackIngress:{kind:"native-slack-thread",maximumProviderCalls:20,ingressTimeoutMs:120000}})).toBe(false); + expect(validSlackIngressDeclaration({...metadata,expectedRunCount:3})).toBe(false); +}); diff --git a/tests/runner-e2e/chat-slack-ingress.ts b/tests/runner-e2e/chat-slack-ingress.ts index 114c1ac4a5e..e015d03fdb3 100644 --- a/tests/runner-e2e/chat-slack-ingress.ts +++ b/tests/runner-e2e/chat-slack-ingress.ts @@ -24,10 +24,10 @@ export async function verifySelectedSlackSender(ctx:ChatCatalogContext,receipt:C export function validSlackIngressDeclaration(c: Pick & { journeyKind?: string }) { return (nativeSlackScenarioIds as readonly string[]).includes(c.scenarioId) && c.journeyKind === "native-slack-thread" && c.slackIngress?.kind === "native-slack-thread" && c.slackIngress.maximumProviderCalls === 20 && c.slackIngress.ingressTimeoutMs === 120000 - && Object.keys(c.slackIngress).sort().join(",") === "ingressTimeoutMs,kind,maximumProviderCalls" + && Object.keys(c.slackIngress).sort().join(",") === (c.scenarioId === "chat-channels.reply-in-thread" ? "ingressTimeoutMs,kind,maximumProviderCalls,setupThread" : "ingressTimeoutMs,kind,maximumProviderCalls") && c.turnTimeoutMs === 120000 - && (c.scenarioId === "chat-channels.channel-file" ? c.attemptTimeoutMs === 900000 && c.expectedRunCount === 6 && c.minimumRunCount === 2 && c.expectedHumanMessageCount === 2 - : c.attemptTimeoutMs === 600000 && c.expectedRunCount === 3 && c.minimumRunCount === 1 && c.expectedHumanMessageCount === 1) && (c.setupHumanMessageCount ?? 0) === 0 + && (c.scenarioId === "chat-channels.channel-file" ? !c.slackIngress.setupThread && c.attemptTimeoutMs === 900000 && c.expectedRunCount === 6 && c.minimumRunCount === 2 && c.expectedHumanMessageCount === 2 + : c.attemptTimeoutMs === 600000 && c.expectedRunCount === 4 && c.minimumRunCount === 2 && c.expectedHumanMessageCount === 1 && c.slackIngress.setupThread === "same-agent-distractor") && (c.setupHumanMessageCount ?? 0) === 0 && !c.queryBindings?.length && !c.queryAttachments?.length && !c.queryOutcome && !c.companionSurface && !c.runPolicy; } export function slackIngressReceiptMatches(input: { receipt: ChatSlackIngressReceipt; query: string; companyId: string; agentId: string; @@ -52,6 +52,39 @@ export function sameSlackThreadNewMessage(first: ChatSlackIngressReceipt, next: && next.provider.workspaceId === first.provider.workspaceId && next.provider.channelId === first.provider.channelId && next.provider.threadId === first.provider.threadId && next.provider.senderUserId === first.provider.senderUserId && next.provider.canonicalMessageId !== first.provider.canonicalMessageId; } +export const slackOtherThreadSetupQuery = "Please summarize the current company project status in this separate discussion."; +async function independentlyBoundSlackReceipt(ctx:ChatCatalogContext,receipt:ChatSlackIngressReceipt,query:string,signal:AbortSignal){ + for(const id of [receipt?.endpointId,receipt?.conversationId,receipt?.issueId,receipt?.humanCommentId])if(typeof id!=="string"||!/^[a-zA-Z0-9-]{1,100}$/.test(id))throw new Error("Invalid Slack product receipt identity"); + const api = ctx.input.api; + const endpoint = await api.get(`/api/chat-endpoints/${receipt.endpointId}`); + const conversations = await api.get(`/api/chat-endpoints/${receipt.endpointId}/conversations`); + const binding = await api.get(`/api/issues/${receipt.issueId}/chat-binding`); + const comments = await api.get(`/api/issues/${receipt.issueId}/comments?order=asc`); + const links = await api.get(`/api/chat-endpoints/${receipt.endpointId}/principals`); + const senderIdentity=await verifySelectedSlackSender(ctx,receipt,signal); + const matched = slackIngressReceiptMatches({ receipt, query: query, companyId: ctx.input.fixtures.company.id, agentId: ctx.input.fixtures.agent.id, + endpoint, conversation: conversations.find(row => row.id === receipt.conversationId), binding, comment: comments.find(row => row.id === receipt.humanCommentId), links,linksEndpointId:receipt.endpointId,senderIdentity })&&receipt.providerCalls+2<=20; + return matched; +} +export function slackOtherThreadBoundaryMatches(input:{receipt:ChatSlackIngressReceipt & {runId:string};runs:ChatRun[];companyId:string;agentId:string;sourceIssueId?:string}){ + const {receipt:r,runs}=input; + return r.query===slackOtherThreadSetupQuery&&runs.length===1&&runs[0]?.id===r.runId&&runs[0].companyId===input.companyId&&runs[0].agentId===input.agentId&&runs[0].runtimeMode==="native"&&runs[0].status==="succeeded"&&runs[0].contextSnapshot?.issueId===r.issueId&&(!input.sourceIssueId||input.sourceIssueId!==r.issueId); +} +/** One exact precondition exchange on another actual Slack source. Its human + * comment never enters the canonical source's setup-human history. */ +export async function prepareNativeSlackOtherThread(ctx:ChatCatalogContext,c:ChatCatalogCase,state:Record,deadlineAt:number){ + if(c.scenarioId!=="chat-channels.reply-in-thread"||c.slackIngress?.setupThread!=="same-agent-distractor"||!validSlackIngressDeclaration(c)||!c.dispatchSlackOtherThread||ctx.issue()||(await ctx.allRuns()).length)throw new Error("Invalid or nonempty declared Slack other-thread setup"); + const signal=AbortSignal.timeout(Math.min(120000,deadlineAt-Date.now())); + let listener:(()=>void)|undefined; + const timeout=new Promise((_resolve,reject)=>{listener=()=>reject(new Error("Slack other-thread setup exceeded its declared deadline"));signal.addEventListener("abort",listener,{once:true});}); + let receipt:ChatSlackIngressReceipt & {runId:string}; + try{receipt=await Promise.race([c.dispatchSlackOtherThread(ctx,state,{query:slackOtherThreadSetupQuery,signal}),timeout]);}finally{if(listener)signal.removeEventListener("abort",listener);} + + const matched=await independentlyBoundSlackReceipt(ctx,receipt,slackOtherThreadSetupQuery,signal)&&slackOtherThreadBoundaryMatches({receipt,runs:await ctx.allRuns(),companyId:ctx.input.fixtures.company.id,agentId:ctx.input.fixtures.agent.id}); + await ctx.input.evidence("chat-slack-other-thread-setup.json",{receipt,matched,canonicalSourceHumanCount:0,includedInTotalNativeBound:true}); + if(!matched||signal.aborted)throw new Error("Actual Slack other-thread setup did not prove its sole linked-human/company/source/native execution"); + state.slackOtherThreadSetupReceipt=receipt; +} /** Provider transport belongs to the selected domain; public product identity * and exact canonical persistence are independently checked here. */ export async function dispatchNativeSlackIngress(ctx: ChatCatalogContext, c: ChatCatalogCase, state: Record, deadlineAt: number, phase: "canonical" | "unsupported-file" = "canonical") { @@ -67,20 +100,14 @@ export async function dispatchNativeSlackIngress(ctx: ChatCatalogContext, c: Cha finally { if (listener) signal.removeEventListener("abort", listener); } // Fail before interpreting identifiers as API routes. for (const id of [receipt?.endpointId, receipt?.conversationId, receipt?.issueId, receipt?.humanCommentId]) if (typeof id !== "string" || !/^[a-zA-Z0-9-]{1,100}$/.test(id)) throw new Error("Invalid Slack product receipt identity"); - const api = ctx.input.api; - const endpoint = await api.get(`/api/chat-endpoints/${receipt.endpointId}`); - const conversations = await api.get(`/api/chat-endpoints/${receipt.endpointId}/conversations`); - const binding = await api.get(`/api/issues/${receipt.issueId}/chat-binding`); - const comments = await api.get(`/api/issues/${receipt.issueId}/comments?order=asc`); - const links = await api.get(`/api/chat-endpoints/${receipt.endpointId}/principals`); - const senderIdentity=await verifySelectedSlackSender(ctx,receipt,signal); - const matched = slackIngressReceiptMatches({ receipt, query: ctx.scenario.query, companyId: ctx.input.fixtures.company.id, agentId: ctx.input.fixtures.agent.id, - endpoint, conversation: conversations.find(row => row.id === receipt.conversationId), binding, comment: comments.find(row => row.id === receipt.humanCommentId), links,linksEndpointId:receipt.endpointId,senderIdentity })&&receipt.providerCalls+2<=c.slackIngress!.maximumProviderCalls; + const matched = await independentlyBoundSlackReceipt(ctx,receipt,ctx.scenario.query,signal); const first = state.slackIngressReceipt as ChatSlackIngressReceipt | undefined; const sameThreadNewMessage = phase === "canonical" || !!first && sameSlackThreadNewMessage(first, receipt); - await ctx.input.evidence(`chat-slack-ingress-${phase}-binding.json`, { matched, sameThreadNewMessage, phase, canonicalQuery: ctx.scenario.query, receipt, assignedAgentId: endpoint.assignedAgentId, + await ctx.input.evidence(`chat-slack-ingress-${phase}-binding.json`, { matched, sameThreadNewMessage, phase, canonicalQuery: ctx.scenario.query, receipt, assignedAgentId: ctx.input.fixtures.agent.id, linkedIdentityConfirmed: matched, independentProviderIdentityCalls:2,privateProviderConfiguration: "withheld", providerSenderMapping: "private official human token/profile plus scoped public principal and actual comment" }); - if (signal.aborted || !matched || !sameThreadNewMessage) throw new Error("Slack ingress did not independently bind exact canonical human, linked identity, company and provider thread"); + const other=state.slackOtherThreadSetupReceipt as ChatSlackIngressReceipt|undefined; + const otherThreadDistinct=ctx.scenario.id!=="chat-channels.reply-in-thread"||!!other&&other.endpointId===receipt.endpointId&&other.issueId!==receipt.issueId&&other.conversationId!==receipt.conversationId&&other.provider.threadId!==receipt.provider.threadId&&other.provider.workspaceId===receipt.provider.workspaceId&&other.provider.channelId===receipt.provider.channelId&&other.provider.senderUserId===receipt.provider.senderUserId&&other.linkedPaperclipUserId===receipt.linkedPaperclipUserId; + if (signal.aborted || !matched || !sameThreadNewMessage || !otherThreadDistinct) throw new Error("Slack ingress did not independently bind exact canonical human, linked identity, company and provider thread"); await ctx.selectSlackSource(receipt.issueId); return receipt; } @@ -96,7 +123,9 @@ export async function completeNativeSlackFileConditional(ctx: ChatCatalogContext export function slackNativeRunCheck(ctx: ChatCatalogContext, runs: ChatRun[], state?: Record) { const source = ctx.issue(); const sourceRuns = runs.filter(run => run.contextSnapshot?.issueId === source?.id); - return { id: "catalog-real-slack-source-native", passed: !!source && source.companyId === ctx.input.fixtures.company.id && source.assigneeAgentId === ctx.input.fixtures.agent.id + const other=state?.slackOtherThreadSetupReceipt as (ChatSlackIngressReceipt & {runId:string})|undefined; + const otherStillBound=!other||slackOtherThreadBoundaryMatches({receipt:other,runs:runs.filter(run=>run.contextSnapshot?.issueId===other.issueId),companyId:ctx.input.fixtures.company.id,agentId:ctx.input.fixtures.agent.id,sourceIssueId:source?.id}); + return { id: "catalog-real-slack-source-native", passed: otherStillBound && !!source && source.companyId === ctx.input.fixtures.company.id && source.assigneeAgentId === ctx.input.fixtures.agent.id && sourceRuns.length >= 1 && sourceRuns.every(run => run.agentId === ctx.input.fixtures.agent.id && run.runtimeMode === "native" && run.status === "succeeded") && runs.every(run => typeof run.contextSnapshot?.issueId === "string") && (!state?.slackUnsupportedIngressReceipt || Array.isArray(state.slackSupportedTransferRunIds) && sourceRuns.some(run => !(state.slackSupportedTransferRunIds as unknown[]).includes(run.id))),