Skip to content

bug(core): push() does not apply sanitizers to ancestor segment text #247

@vamgan

Description

@vamgan

Summary

When calling ctx.push() with an ancestors option, the sanitizeText callback is not applied to ancestor segment text. This is inconsistent with DOM-derived focus, where ancestor text is always sanitized.

Reproduction

const ctx = createAskableContext({
  sanitizeText: (t) => t.replace(/\d{4,}/g, '[redacted]'),
});

ctx.push(
  { widget: 'deals-table' },
  'Acme Corp',
  {
    ancestors: [
      { meta: { section: 'finance' }, text: 'Revenue 12345678' }, // NOT sanitized
    ],
  }
);

ctx.toPromptContext();
// ancestor text still contains "12345678" — sanitizer was never called

Expected behavior

sanitizeText (and sanitizeMeta) should be applied to every ancestor segment in push(), the same way they are applied when building focus from DOM hierarchy.

Root cause

packages/core/src/context.ts — the push() method sanitizes the top-level meta and text but passes options?.ancestors through to buildFocusFromPush() without running them through applySanitizers.

Fix

Apply sanitizers to each ancestor segment before storing:

const sanitizedAncestors = options?.ancestors?.map((seg) => ({
  ...seg,
  meta: this.sanitizeMetaFn && typeof seg.meta !== 'string'
    ? this.sanitizeMetaFn(seg.meta)
    : seg.meta,
  text: this.sanitizeTextFn ? this.sanitizeTextFn(seg.text) : seg.text,
}));

Impact

Any app using sanitizeText or sanitizeMeta to strip PII/sensitive data will silently leak that data through pushed ancestor segments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreCore package and cross-package runtime behaviorbugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions