Split PhiModule from app-grained to capability-grained

Featurekamo-shared-library
Shipped
August 24, 2026 at 9:54 PM UTC
Author
Kamo
Commit
7a2209e

POS mapped to ECOMMERCE_SYNC (BLOCKED_NO_BAA) and the whole commerce surface hangs off POS, so an org with handlesPhi=true could not switch commerce on at all — no market, no /commerce, and no clinical vertical built on it. The ten retail sync adapters are the thing that leaves the boundary, not the commerce spine. POS now maps to COMMERCE_CORE (permitted) and ECOMMERCE_SYNC scopes down to the RETAIL child. Same correction for MEET (live conference vs the summary pipeline that mails transcripts to external inference) and VOIP (telephony vs stored recordings and transcripts). MEETING_RECORDING and VOIP_RECORDING now have no ServiceType at all: they are capabilities reachable only through code, and PhiModule's javadoc now states the rule that such a constant MUST be checked by PhiCapabilityGuard at its call site. Reclassifying an app as permitted without guarding the capability inside it reads as compliant while enforcing nothing. AI_ASSISTANT and RAG_SEARCH deliberately stay blocked: KlusterServices has embeddings, whisper-asr and translation but no generative LLM, and RAG shares one Qdrant collection isolated by a payload filter. Splitting those would be a paper change. Two tests encoded the app-grained model and are updated rather than extended: PhiServiceTypeMappingTest's blocked-app assertion, and FeatureServicePhiGateTest, whose blocked exemplar moves from VOIP to RETAIL — VOIP is no longer refusable at enable time.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing