Skip to content

guardrails: decide and wire the segment-moderation posture for embeddings/rerank/audio/images/passthrough (semantic + siblings) #1032

Description

@membphis

Context

#1031 ships kind: "semantic" (AISIX-Cloud#1363) wired through the segment-moderation pass: chat, /v1/messages, /v1/responses, legacy completions (all via redact::moderate_body), and /mcp (a new async segment pass over the same byte-splice surface as the sync write-back).

The remaining endpoint families have no segment walker (crates/aisix-proxy/src/redact.rs module doc: "Families without a wire walker (embeddings, rerank, images, audio, passthrough, MCP) keep the plain check_* path") — MCP got its walker in #1031; the rest did not. On those surfaces a semantic guardrail row resolves into the chain but its segment hooks are never driven, so it silently does nothing — the class of gap the handler-family rule requires an explicit tracking issue for.

The product question (decide before wiring)

Semantic redaction is span-level rewriting of natural-language text. Whether that is even meaningful per family needs a decision first:

  • embeddings / rerank input — rewriting the input changes the vectors/scores the caller gets back. Masking may be desired (the sensitive value must not reach the provider) but it is a semantic change to the result, unlike chat where the mask reads as prose. Note kind=pii has the same posture today (sync redactors do run there? verify) — the semantic decision should match whatever pii does, not fork the family.
  • audio (transcription output), images (prompt input) — plausible surfaces; same "mask-alters-the-product" question.
  • passthrough routes — the envelope is detected, not owned; a rewrite channel would need the same byte-splice discipline as /mcp per envelope kind.

Suggested shape

  1. Decide the per-family posture (mask / scan-only / out of scope) alongside the pii/Bedrock segment posture so the kinds do not drift from each other.
  2. For families that should mask: give each a SegmentCollector/SegmentApplier walk (or byte-splice pass) and run the standard check_*_non_segment + moderate_*_segments pair, as chat and /mcp do.
  3. e2e per wired family (the family-lockstep rule: a suite that only drives chat stays green while the siblings misbehave).

Out of scope

Ensemble member-level wiring (experimental-surface backlog, one deliberate design pass); /mcp (done in #1031); the aisix#1027 scan/rewrite text unification.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions