Skip to content

feat(runtime): enable privacy-safe hosted-redacted Memory write-gate egress #1973

Closed

Description

@AlexStocks

Scope

Implement a reviewed, deterministic DecisionRequest projection sanitizer that permits the existing memory_write_gate to use DecisionPrivacyBoundary.HOSTED_REDACTED for one bounded DecisionModel evaluation.

Today RuntimeConfig rejects hosted_redacted, and DecisionMemoryWriteGate evaluates only when its boundary is local_only and the configured model is explicitly local. This issue changes only the projection sent from the Memory write evidence-sufficiency gate to its decision backend. It does not make raw hosted egress acceptable and it does not make a sanitizer a new source of Memory authority.

Design decisions

Model classification and routing

  • Preserve the current local_only path: a model explicitly classified as local receives the existing bounded DecisionRequest and has unchanged behavior.
  • For hosted_redacted, require an explicit sanitizer before a model that is not local can be invoked. A custom model with no explicit local-only capability is treated conservatively as non-local; do not infer locality from a class name, provider id, endpoint, or configuration string.
  • references_only and no_external_call retain their current no-hosted-content-call behavior. This issue does not enable them.

Sanitizer contract

  • Define one Runtime-owned, deterministic contract over a DecisionRequest projection. Its result is exactly one of:
    1. permitted: a replacement DecisionRequest containing only the sanitized subject/evidence values plus bounded, content-free redaction facts; or
    2. withheld: no request, with one stable bounded reason code.
  • The contract may be a reusable internal helper for later DecisionModel consumers, but this issue wires it into Memory write-gate only. No other consumer is migrated here.
  • Sanitization must not consult an LLM, mutate a Source/Memory/Artifact/Revision, fetch another Scope, or reconstruct omitted raw text from an identifier. It operates on the already bounded gate request only.
  • If sanitization would remove material required for an honest decision, it must return withheld; it must not send a semantically misleading partial request.

Configuration and startup validation

  • Do not enable hosted behavior merely because the hosted_redacted enum parses. Resolve capability at Runtime composition/build time, where both the DecisionModel and sanitizer are available.
  • A configuration selecting hosted_redacted without an installed sanitizer must fail Runtime construction with a named configuration error. A disabled gate remains disabled without requiring either component.
  • A sanitizer failure, invalid result, or withheld result is a per-assessment no-call outcome, not a startup crash.

Assessment and observation semantics

  • Invoke the sanitizer immediately before any hosted model/generator call. The backend must receive only the permitted replacement request; raw candidate and evidence values must have no alternate egress path.
  • For a no-call privacy outcome, preserve the Memory write gate's fail-open behavior, but record used_fallback=true, coverage=unadjudicated, and one bounded privacy/fallback reason. It must never be reported as a clean allow.
  • A successful hosted-redacted call remains an ordinary model assessment; redaction does not itself prove that the model had sufficient evidence.
  • DecisionObservation and log fields contain only existing references/counts plus bounded redaction or privacy outcome facts. They must not retain candidate/evidence bodies, raw redacted values, prompts, model rationales, or exception details.

Why this is separate

RFC #1770 permits hosted-redacted calls only after PowerContext redaction/sanitization and requires an insufficient projection to remain unadjudicated. PR #1921 intentionally rejects hosted_redacted pending this separately reviewed boundary. The closed hook-side capture scrubbing work in #1047 is different: it protects integration capture before PowerContext storage, not Runtime-to-DecisionModel egress.

Related, but not duplicated:

Acceptance criteria

  • A hosted spy backend receives only permitted sanitized candidate/evidence values and never receives raw sentinels through its request, exception, DecisionObservation, or structured log fields.
  • A missing sanitizer at Runtime composition fails with the named configuration error; a disabled gate does not require a sanitizer.
  • A sanitizer that withholds, raises, or returns invalid data makes zero hosted calls and yields an unadjudicated, fail-open assessment with a stable bounded reason.
  • A successful hosted-redacted call is attributable in DecisionObservation without persisting candidate/evidence bodies, raw redacted values, prompts, rationales, or exception details.
  • Existing local-only gate tests retain their outcomes and backend-call behavior. references_only and no_external_call remain no-hosted-content-call paths.
  • Focused tests cover model classification defaults, composition/configuration validation, permitted and withheld projections, sanitizer failures, observations/log redaction, scope isolation, and both SQLite/OceanBase Runtime composition where applicable.

Non-goals

  • No generic migration of every provider, integration capture path, PreparedContext host injection, query rewrite, or future decision-policy consumer.
  • No public HTTP/OpenAPI API, durable raw-prompt ledger, dashboard, provider SDK dependency, automatic promotion to enforcing, or changes to Memory write authority.
  • No claim that a redacted request is semantically sufficient; stripped material may require withholding.

Validation

Run the focused decision-policy, Runtime configuration/composition, and Memory write-gate suites, then the repository checks warranted by the changed Runtime contract. Include sentinel assertions that raw content cannot reach a hosted backend, logs, or observations.

References

Activity

  1. beatenevo commented on Oct 13, 2026

    @beatenevo
    Contributor

    plz assign it for me

  2. moved this from Todo to In progress in PowerContexton Oct 13, 2026
  3. moved this from In progress to Done in PowerContexton Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions