IBEX Harness
DocsBenchmarksBlogChangelogRoadmap
GitHub
IBEX Harness

Documentation

Architecture Decision RecordsADR-0002: Repository foundation bootstrapADR-0003: Branch protection and merge policyADR-0004: Protobuf and code generation policyADR-0005: Postgres migration strategyADR-0006: Auth protobuf contract (`ibex.auth.v1`)ADR-0007: Auth token validation implementationADR-0008: Security scanning and CI quality gatesADR-0009: Permission bitmap layoutADR-0010: Cryptography policyADR-0011: Proxy auth gRPC client and middlewareADR-0012: Proxy request normalization (OpenAI chat)ADR-0013: Proxy input validation and stable error envelopeADR-0014: Core domain migration sequencingADR-0015: Proxy rate limit skeleton (Phase 1)ADR-0016: Proxy agent identity verification (Phase 1)ADR-0017: Request ID and trace context strategy (Phase 1)ADR-0018: Graceful shutdown contract (Phase 1)ADR-0019: OpenTelemetry provider configuration (Phase 1)ADR-0020: Shared package boundaries — `packages/config` and `packages/apierror`ADR-0021: Prometheus Metric Catalog (Phase 1)ADR-0022: Health check contract (Phase 1)ADR-0023: Docs site architecture (Phase 1.5)ADR-0024: Benchmark data publishing modelADR-0025: LLM provider abstractionADR-0026: OpenAI client designADR-0027: Streaming dual-write strategyADR-0028: Auth cache designADR-0029: Token revocation propagation via Redis pub/subADR-0030: Directive versioning strategyADR-0031: System prompt injection strategyADR-0032: Session data model and retentionADR-0033: ClickHouse llm_traces schema and retentionADR-0034: Proxy overhead performance measurement methodologyADR-0035: Chat Idempotency-Key Redis dedupeADR-0038: Context assembly service design and gRPC contractADR-0039: Proxy Postgres ownership for session and directive storesADR-0040: Anthropic provider adapterADR-0041: Model capability registryADR-0042: Self-hosted OpenAI-compatible LLM adapterADR-0043: Tokenizer registry architectureADR-0044: Non-streaming response pipelineADR-0045: Streaming response transformationADR-0046: Embedder interface and profile registryADR-0047: Memory temporal validity foundationADR-0048: Memory multi-label categoriesADR-0049: Memory relationship graph readinessADR-0050: MCP server skeleton (transport, auth, audit)ADR-0051: Local LGTM observability stack (Phase 2.5 exit pull-forward)ADR-0052: Memory schema v2 expand (HNSW, quality columns)ADR-0053: Vector store abstraction and composite scoring v2ADR-0054: In-process Presidio PII detection in memoryADR-0055: Memory write-path exact and near-duplicate dedupADR-0056: Temporal-interval-aware conflict detectionADR-0057: Memory write-path persistence and orchestration
ADRs›ADR-0054: In-process Presidio PII detection in memory
ADRs

ADR-0054: In-process Presidio PII detection in memory

Architecture decision record 0054 — Presidio + spaCy run in-process in services/memory for write-path PII; Semgrep embedding-ML ban unchanged; en_core_web_md default; typed redaction placeholders.

ADR-0054: In-process Presidio PII detection in memory

  • Status: Accepted
  • Date: 2026-08-27
  • Authors: IBEX Harness team
  • Milestone: 3.C.1 PII detection and redaction

Context

Milestone 3.2.1 added Semgrep rule ibex-memory-no-ml-imports so services/memory/ cannot import torch / tensorflow / transformers / sentence_transformers / sklearn — embeddings must go through the Phase 2.5 embedder HTTP API (ADR-0046, ADR-0053).

Milestone 3.C.1 needs Microsoft Presidio with a spaCy NLP model for Tier-2 NER, self-hosted and in-process, to avoid an external PII API. spaCy is an NLP library; this ADR records why that does not conflict with the Semgrep rule and which model/threshold/placeholder policies we adopt.

Options considered

1) Semgrep vs Presidio

  1. Narrow ibex-memory-no-ml-imports path globs (e.g. only app/clients/).
  2. Run Presidio NLP out-of-process (sidecar / remote recognizer) to keep memory import-clean.
  3. Keep the rule as written — path services/memory/, banned packages are embedding/classic ML stacks only; admit Presidio + spaCy CNN models.

Decision: (3). The rule already excludes spaCy/Presidio by pattern list. Narrowing globs would weaken the embedder boundary. A sidecar adds a write-path network hop inside the p95 ≤ 200ms write budget without a Semgrep necessity.

2) spaCy model

  1. Sketch en_core_web_lg (~560 MB).
  2. en_core_web_trf (higher NER accuracy; pulls transformers).
  3. en_core_web_md (~40–50 MB) default; en_core_web_sm allowed for microbench/dev.

Decision: en_core_web_md. NER quality is close to lg for Presidio’s needs while keeping the memory image small. Settings allow-list is en_core_web_sm / en_core_web_md only (bundled wheels). en_core_web_trf is forbidden — it requires transformers, which Semgrep rejects under services/memory/.

3) Quarantine threshold

  1. Reuse IBEX_MEMORY_QUARANTINE_INJECTION_THRESHOLD (prompt-injection risk).
  2. Separate IBEX_MEMORY_PII_REDACT_MIN_CONFIDENCE (default 0.70).

Decision: (2). Same numeric language as SECURITY.md §7.2’s 0.7 example, distinct reason and metric label (reason=pii_low_confidence).

4) Redaction placeholders

  1. Generic [REDACTED].
  2. Typed placeholders ([EMAIL], [PHONE], [PERSON], …) via AnonymizerEngine.

Decision: Typed. Preserves structure for later dedup/classification without leaking values.

Decision

  1. Leave ibex-memory-no-ml-imports patterns and services/memory/ path unchanged.
  2. Ship presidio-analyzer, presidio-anonymizer, spacy, and en-core-web-md in services/memory (pip wheels in uv.lock; no runtime spacy download).
  3. Default model en_core_web_md via IBEX_MEMORY_PII_SPACY_MODEL.
  4. Redact when finding score ≥ IBEX_MEMORY_PII_REDACT_MIN_CONFIDENCE (0.70); any lower-confidence finding quarantines the memory (status=quarantined).
  5. Redaction completes before any embedder call (pipeline stage order + unit test).
  6. Never add transformers / torch / sentence-transformers to the memory service.

Consequences

  • Memory image grows by spaCy + md weights (~tens of MB), not hundreds (lg) or a transformers stack (trf).
  • Operators may override the model name for sm/lg CNN pipelines; trf remains policy-banned.
  • Dependabot pip for /services/memory tracks Presidio/spaCy CVEs.

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0053: Vector store abstraction and composite scoring v2NextADR-0055: Memory write-path exact and near-duplicate dedup

On this page

  • Context
  • Options considered
  • 1) Semgrep vs Presidio
  • 2) spaCy model
  • 3) Quarantine threshold
  • 4) Redaction placeholders
  • Decision
  • Consequences
0%