fix(team): recognize native bootstrap control envelopes

This commit is contained in:
777genius 2026-05-06 18:59:54 +03:00
parent 2080e86f44
commit ac2b6c9352
6 changed files with 113 additions and 6 deletions

View file

@ -135,7 +135,7 @@ export interface InternalControlMessageDisplay {
}
export function getInternalControlMessageDisplay(
message: Pick<InboxMessage, 'text'> & Partial<Pick<InboxMessage, 'source'>>
message: Pick<InboxMessage, 'text'> & Partial<Pick<InboxMessage, 'from' | 'source'>>
): InternalControlMessageDisplay | null {
if (!isTeamInternalControlMessageEnvelope(message)) {
return null;
@ -237,7 +237,7 @@ export function getBootstrapAcknowledgementDisplay(
}
export function getSanitizedInboxMessageText(
message: Pick<InboxMessage, 'text' | 'to'> & Partial<Pick<InboxMessage, 'source'>>
message: Pick<InboxMessage, 'text' | 'to'> & Partial<Pick<InboxMessage, 'from' | 'source'>>
): string {
return (
getInternalControlMessageDisplay(message)?.body ??

View file

@ -8,6 +8,7 @@ const INTERNAL_CONTROL_MESSAGE_SOURCES = new Set([
'runtime_delivery',
'system_notification',
]);
const INTERNAL_BOOTSTRAP_AUTHORS = new Set(['team-lead', 'lead', 'orchestrator']);
export function stripTranscriptSpeakerPrefix(value: string): string {
let normalized = value.trim();
@ -22,7 +23,7 @@ export function stripTranscriptSpeakerPrefix(value: string): string {
export function isNativeAppManagedBootstrapCheckText(value: unknown): boolean {
return (
typeof value === 'string' &&
stripTranscriptSpeakerPrefix(value).includes(NATIVE_APP_MANAGED_BOOTSTRAP_CHECK_OPEN)
stripTranscriptSpeakerPrefix(value).startsWith(NATIVE_APP_MANAGED_BOOTSTRAP_CHECK_OPEN)
);
}
@ -56,7 +57,17 @@ export function isTeamInternalControlMessageText(value: unknown): boolean {
export function isTeamInternalControlMessageEnvelope(message: {
text?: unknown;
source?: unknown;
from?: unknown;
}): boolean {
if (isNativeAppManagedBootstrapCheckText(message.text)) {
if (typeof message.source === 'string') {
return INTERNAL_CONTROL_MESSAGE_SOURCES.has(message.source);
}
return (
typeof message.from === 'string' &&
INTERNAL_BOOTSTRAP_AUTHORS.has(message.from.trim().toLowerCase())
);
}
if (!isTeamInternalControlMessageText(message.text)) {
return false;
}

View file

@ -79,8 +79,10 @@ describe('TeamMessageFeedService', () => {
getConfig: vi.fn(async () => config),
getInboxMessages: vi.fn(async () => [
makeMessage({
from: 'team-lead',
to: undefined,
messageId: 'native-bootstrap-private-check',
source: 'system_notification',
source: undefined,
text: '<agent_teams_native_app_managed_bootstrap_check>\nprivate\n</agent_teams_native_app_managed_bootstrap_check>',
}),
makeMessage({
@ -123,6 +125,27 @@ Messages:
expect(feed.messages.map((message) => message.messageId)).toEqual(['quoted-control-prompt']);
});
it('does not hide user-authored native bootstrap marker quotes from the feed', async () => {
const service = new TeamMessageFeedService({
getConfig: vi.fn(async () => config),
getInboxMessages: vi.fn(async () => [
makeMessage({
messageId: 'quoted-native-bootstrap-control',
source: 'user_sent',
text: '<agent_teams_native_app_managed_bootstrap_check>\nquoted\n</agent_teams_native_app_managed_bootstrap_check>',
}),
]),
getLeadSessionMessages: vi.fn(async () => []),
getSentMessages: vi.fn(async () => []),
});
const feed = await service.getFeed('signal-ops-4');
expect(feed.messages.map((message) => message.messageId)).toEqual([
'quoted-native-bootstrap-control',
]);
});
it('refreshes the durable feed after cache expiry even when the dirty signal was missed', async () => {
let inboxMessages: InboxMessage[] = [makeMessage()];
const getInboxMessages = vi.fn(async () => inboxMessages);

View file

@ -71,13 +71,32 @@ Do NOT send acknowledgement-only messages such as "ready" or "online".`);
`<agent_teams_native_app_managed_bootstrap_check>
Your Agent Teams startup context was already loaded by the app.
</agent_teams_native_app_managed_bootstrap_check>`,
{ source: 'system_notification' }
{ source: undefined }
);
expect(getInternalControlMessageDisplay(message)?.summary).toBe('Internal bootstrap check');
expect(getSanitizedInboxMessageText(message)).toBe('Internal bootstrap check hidden in the UI.');
});
it('does not sanitize user-authored native bootstrap marker quotes', () => {
const text = `<agent_teams_native_app_managed_bootstrap_check>
Your Agent Teams startup context was already loaded by the app.
</agent_teams_native_app_managed_bootstrap_check>`;
const message = makeMessage(text, { from: 'user', source: 'user_sent' });
expect(getInternalControlMessageDisplay(message)).toBeNull();
expect(getSanitizedInboxMessageText(message)).toBe(text);
});
it('does not sanitize visible lead text that only mentions the native bootstrap marker', () => {
const text =
'Visible note quoting <agent_teams_native_app_managed_bootstrap_check> for diagnostics.';
const message = makeMessage(text, { from: 'team-lead', source: 'lead_process' });
expect(getInternalControlMessageDisplay(message)).toBeNull();
expect(getSanitizedInboxMessageText(message)).toBe(text);
});
it('sanitizes leaked lead inbox relay prompts defensively', () => {
const message = makeMessage(
`Human: You have new inbox messages addressed to you (team lead "team-lead").

View file

@ -41,7 +41,7 @@ describe('filterTeamMessages', () => {
const messages = [
makeMessage({
messageId: 'native-bootstrap-private-check',
source: 'system_notification',
source: undefined,
text: '<agent_teams_native_app_managed_bootstrap_check>\nprivate\n</agent_teams_native_app_managed_bootstrap_check>',
}),
makeMessage({
@ -59,6 +59,25 @@ describe('filterTeamMessages', () => {
expect(result.map((message) => message.messageId)).toEqual(['visible-message']);
});
it('keeps user-authored native bootstrap marker quotes visible', () => {
const messages = [
makeMessage({
from: 'user',
messageId: 'user-native-bootstrap-quote',
source: 'user_sent',
text: '<agent_teams_native_app_managed_bootstrap_check>\nquoted\n</agent_teams_native_app_managed_bootstrap_check>',
}),
];
const result = filterTeamMessages(messages, {
timeWindow: null,
filter: { from: new Set(), to: new Set(), showNoise: true },
searchQuery: '',
});
expect(result.map((message) => message.messageId)).toEqual(['user-native-bootstrap-quote']);
});
it('hides leaked lead inbox relay prompt echoes', () => {
const messages = [
makeMessage({

View file

@ -18,6 +18,9 @@ Messages:
Timestamp: 2026-05-06T15:02:54.853Z
Text:
#f8d7235a done.`;
const nativeBootstrapPrompt = `<agent_teams_native_app_managed_bootstrap_check>
Your Agent Teams startup context was already loaded by the app.
</agent_teams_native_app_managed_bootstrap_check>`;
describe('teamInternalControlMessages', () => {
it('detects lead inbox relay prompts and Human-prefixed echoes', () => {
@ -60,6 +63,38 @@ describe('teamInternalControlMessages', () => {
text: `Human: ${leadRelayPrompt}`,
})
).toBe(false);
expect(
isTeamInternalControlMessageEnvelope({
text: nativeBootstrapPrompt,
from: 'team-lead',
})
).toBe(true);
expect(
isTeamInternalControlMessageEnvelope({
text: nativeBootstrapPrompt,
from: 'orchestrator',
})
).toBe(true);
expect(isTeamInternalControlMessageText(`Human: ${nativeBootstrapPrompt}`)).toBe(true);
expect(
isTeamInternalControlMessageEnvelope({
source: 'lead_process',
text: `Visible note quoting ${nativeBootstrapPrompt}`,
})
).toBe(false);
expect(
isTeamInternalControlMessageEnvelope({
source: 'user_sent',
text: nativeBootstrapPrompt,
from: 'user',
})
).toBe(false);
expect(
isTeamInternalControlMessageEnvelope({
text: nativeBootstrapPrompt,
from: 'user',
})
).toBe(false);
});
it('strips an exact echoed control prefix while preserving visible trailing text', () => {