@@ -37,13 +37,18 @@ function sanitizeEntityTypes(value: unknown): string[] {
3737 return Array . isArray ( value ) ? value . filter ( ( t ) : t is string => typeof t === 'string' ) : [ ]
3838}
3939
40- /** A stage redacts nothing unless it is enabled AND has at least one entity type. */
40+ /**
41+ * Expand a stored stage policy into its effective form. A disabled stage redacts
42+ * nothing. An ENABLED stage with no entity types redacts ALL detected PII — the
43+ * masking layer omits `entities` from the Presidio request — so it stays active;
44+ * treating enabled-but-empty as disabled would let an explicit "redact all" save
45+ * silently skip masking (fail-open).
46+ */
4147function toEffectiveStage ( policy : PiiStagePolicy | undefined ) : EffectivePiiStage {
42- const types = sanitizeEntityTypes ( policy ?. entityTypes )
43- if ( ! policy ?. enabled || types . length === 0 ) return DISABLED_STAGE
48+ if ( ! policy ?. enabled ) return DISABLED_STAGE
4449 return {
4550 enabled : true ,
46- entityTypes : types ,
51+ entityTypes : sanitizeEntityTypes ( policy . entityTypes ) ,
4752 language : coercePiiLanguage ( policy . language ) ?? DEFAULT_PII_LANGUAGE ,
4853 }
4954}
@@ -55,9 +60,10 @@ function toEffectiveStage(policy: PiiStagePolicy | undefined): EffectivePiiStage
5560 * selection is whole-rule; the selected rule is then expanded into three stages.
5661 *
5762 * Back-compat: a legacy rule with no `stages` is treated exactly as it was before
58- * — logs-only, masking its flat `entityTypes` (input/blockOutputs disabled). A
59- * resolved stage with no entity types redacts nothing. Defensive about the
60- * loosely-typed JSON column.
63+ * — logs-only, masking its flat `entityTypes` (input/blockOutputs disabled); an
64+ * empty flat `entityTypes` redacts nothing (the workspace-exemption shape). For
65+ * per-stage rules an enabled stage with no entity types redacts ALL detected PII
66+ * (see {@link toEffectiveStage}). Defensive about the loosely-typed JSON column.
6167 */
6268export function resolveEffectivePiiRedaction ( params : {
6369 orgSettings : DataRetentionSettings | null | undefined
0 commit comments