A MoonBit toolkit for detecting, replacing, and auditing PHI in Chinese and English clinical text.
Dependencies
///|
test {
let result = redact("电话13800138000")
inspect(result.text, content="电话[PHONE]")
inspect(result.offsets.length() > 0, content="true")
}moon run --target wasm-gc cmd/main -- "姓名:张三 电话13800138000" --audit
moon run --target wasm-gc cmd/main -- --mode=preserve "Phone 415-555-1234"
moon run --target wasm-gc cmd/main -- --mode=partial "Email: zhang@example.com"
moon run --target wasm-gc cmd/main -- --mode=hash "电话13800138000"moon run cmd/main -- [options] [text]moon run cmd/main -- --benchmark=100moon fmt --check
moon info
moon check --target all --deny-warn
moon test --target all --deny-warn
moon run --target wasm-gc cmd/main -- --benchmark=10pub(all) suberror DeidError {
DeidError(String)
}pub(all) struct AnalyticsComparison {
left_id : String
right_id : String
finding_delta : Int
risk_delta : Int
length_delta : Int
ratio_delta : Float
} derive(Debug)pub(all) struct BatchConfig {
config : RedactionConfig
stop_on_error : Bool
retain_empty : Bool
max_documents : Int
} derive(Eq, Debug)pub(all) struct BatchOutcome {
results : Array[BatchResult]
diagnostics : Array[BatchDiagnostic]
totals : AuditTotals
} derive(Debug)pub(all) struct ChunkPolicy {
context_window : Int
separator : String
config : RedactionConfig
} derive(Eq, Debug)pub(all) struct ChunkResult {
chunk_id : String
original_length : Int
redacted_length : Int
result : DeidResult
} derive(Debug)impl Show for ConfidenceBandpub(all) struct DeidOptions {
mode : ReplacementMode
min_confidence : Int
include_disabled_rules : Bool
} derive(Eq, Debug)pub(all) struct Diagnostic {
code : String
severity : DiagnosticSeverity
message : String
start : Int
end : Int
} derive(Eq, Debug)pub(all) struct DocumentSection {
title : String
kind : SectionKind
start : Int
end : Int
text : String
} derive(Eq, Debug)pub(all) struct EntityBatch {
source : String
entities : Array[EntityInput]
invalid_count : Int
} derive(Eq, Debug)impl Show for LocaleHintpub(all) struct MappingIndex {
original_length : Int
redacted_length : Int
segments : Array[MappingSegment]
} derive(Debug)fn MappingIndex::original_line_column(self : MappingIndex, original : String, position : Int) -> LineColumnfn MappingIndex::redacted_line_column(self : MappingIndex, redacted : String, position : Int) -> LineColumnpub(all) struct MatchQuality {
finding_id : String
lexical : Int
contextual : Int
structural : Int
checksum : Int
total : Int
band : ConfidenceBand
} derive(Eq, Debug)pub(all) struct PipelineConfig {
policy : RedactionPolicy
rules : Array[Rule]
normalize_input : Bool
include_keyword_diagnostics : Bool
keep_review_findings : Bool
} derive(Eq, Debug)pub(all) struct PipelineResult {
original : String
normalized : String
findings : Array[Finding]
result : DeidResult
statistics : ScanStatistics
diagnostics : Array[Diagnostic]
trace : Array[PipelineTrace]
} derive(Debug)pub(all) struct PolicyDecision {
finding_id : String
action : PolicyAction
reason : String
} derive(Eq, Debug)pub(all) struct RedactionConfig {
policy : RedactionPolicy
salt : String
token_prefix : String
keep_first : Int
keep_last : Int
keep_whitespace : Bool
} derive(Eq, Debug)pub(all) struct RedactionPolicy {
name : String
locale : LocaleHint
action : PolicyAction
mode : ReplacementMode
min_confidence : Int
protected_ranges : Array[ProtectedRange]
allowed_kinds : Array[PhiKind]
denied_rule_ids : Array[String]
context_window : Int
} derive(Eq, Debug)pub(all) struct RulePack {
name : String
version : String
locale : LocaleHint
description : String
rules : Array[Rule]
lifecycle : RuleLifecycle
} derive(Eq, Debug)pub(all) struct SectionSummary {
title : String
kind : SectionKind
finding_count : Int
risk : RiskLevel
} derive(Eq, Debug)pub(all) struct StreamingRedactor {
config : RedactionConfig
context_window : Int
carry : String
closed : Bool
} derive(Debug)fn add_protected_range(policy : RedactionPolicy, start : Int, end : Int, reason : String) -> RedactionPolicyfn analyze_documents(items : Array[BatchItem], config : RedactionConfig) -> Array[DocumentAnalytics] raise DeidErrorfn apply_findings_with_mode(input : String, findings : Array[Finding], mode : ReplacementMode) -> (String, Array[OffsetMap])fn ascii_digit_value(c : Char) -> Intfn benchmark_once(name : String, documents : Array[String], repetitions : Int, config : RedactionConfig) -> BenchmarkResult raise DeidErrorfn build_mapping_index(input_length : Int, output_length : Int, findings : Array[Finding], offsets : Array[OffsetMap]) -> MappingIndexfn document_diagnostics(input : String, policy : RedactionPolicy, rules : Array[Rule]) -> Array[Diagnostic] raise DeidErrorfn entity_input(label~ : String, kind~ : PhiKind, start~ : Int, end~ : Int, confidence~ : Int, source~ : String) -> EntityInputfn evaluate_cases(cases : Array[EvaluationCase], rules? : Array[Rule]) -> EvaluationResult raise DeidErrorfn fields_containing_phi(fields : Array[FieldValue], config : RedactionConfig) -> Array[String] raise DeidErrorfn findings_with_placeholders(findings : Array[Finding], registry : PlaceholderRegistry) -> Array[Finding]fn make_manifest(document_id : String, input : String, result : DeidResult, pack : RulePack, generated_at : String) -> ProcessingManifestfn merge_entity_batch(input : String, findings : Array[Finding], batch : EntityBatch, mode : ReplacementMode) -> Array[Finding]fn merge_external_entities(input : String, findings : Array[Finding], entities : Array[ExternalEntity], mode? : ReplacementMode) -> Array[Finding]fn pipeline_for_profile(input : String, profile : Profile, mode : ReplacementMode) -> PipelineResult raise DeidErrorfn profile_redaction(input : String, profile : Profile, mode : ReplacementMode) -> DeidResult raise DeidErrorfn pseudonym_map(values : Array[String], kind : IdentifierKind, salt : String) -> Map[String, String]fn redact(input : String, rules? : Array[Rule], options? : DeidOptions) -> DeidResult raise DeidErrorfn redact_batch(items : Array[BatchItem], rules? : Array[Rule], options? : DeidOptions) -> Array[BatchResult] raise DeidErrorfn redact_batch_with_config(items : Array[BatchItem], batch_config : BatchConfig, rules? : Array[Rule]) -> BatchOutcome raise DeidErrorfn redact_chunk_results(items : Array[BatchItem], config : RedactionConfig) -> Array[ChunkResult] raise DeidErrorfn redact_delimited_row(text : String, delimiter : Char, config : RedactionConfig) -> String raise DeidErrorfn redact_except_kinds(input : String, excluded : Array[PhiKind], mode : ReplacementMode) -> DeidResult raise DeidErrorfn redact_field_values(fields : Array[FieldValue], config : RedactionConfig) -> Array[FieldValue] raise DeidErrorfn redact_in_fixed_chunks(input : String, width : Int, config : RedactionConfig) -> String raise DeidErrorfn redact_lines_joined(text : String, config : RedactionConfig, separator : String) -> String raise DeidErrorfn redact_named_fields(text : String, names : Array[String], config : RedactionConfig) -> String raise DeidErrorfn redact_only_kinds(input : String, kinds : Array[PhiKind], mode : ReplacementMode) -> DeidResult raise DeidErrorfn redact_prefix(input : String, length : Int, config : RedactionConfig) -> DeidResult raise DeidErrorfn redact_range(input : String, range : Span, config : RedactionConfig) -> DeidResult raise DeidErrorfn redact_suffix(input : String, length : Int, config : RedactionConfig) -> DeidResult raise DeidErrorfn redact_until_stable(input : String, config : RedactionConfig, maximum_rounds : Int) -> DeidResult raise DeidErrorfn redact_windowed(input : String, radius : Int, config : RedactionConfig) -> DeidResult raise DeidErrorfn redact_with_allowlist(input : String, protected_spans : Array[Span], config : RedactionConfig) -> DeidResult raise DeidErrorfn redact_with_config(input : String, config : RedactionConfig, rules? : Array[Rule]) -> DeidResult raise DeidErrorfn redact_with_deny_rules(input : String, denied_rule_ids : Array[String], config : RedactionConfig) -> DeidResult raise DeidErrorfn redact_with_manifest(document_id : String, input : String, config : RedactionConfig, generated_at : String) -> (DeidResult, ProcessingManifest) raise DeidErrorfn redact_with_placeholders(input : String, registry : PlaceholderRegistry) -> DeidResult raise DeidErrorfn redact_with_policy(input : String, policy : RedactionPolicy, rules? : Array[Rule]) -> DeidResult raise DeidErrorfn redact_with_profile(input : String, profile : Profile, mode : ReplacementMode) -> DeidResult raise DeidErrorfn redact_with_protected_fields(input : String, protected_fields : Array[String], config : RedactionConfig) -> String raise DeidErrorfn redact_with_salt(input : String, salt : String, rules? : Array[Rule]) -> DeidResult raise DeidErrorfn registry_placeholders(registry : PlaceholderRegistry, kinds : Array[PhiKind]) -> Map[String, String]fn replacement_boundary_is_safe(text : String, offset : Int) -> Boolfn rule_pack(name~ : String, version~ : String, locale~ : LocaleHint, description~ : String, rules~ : Array[Rule]) -> RulePackfn rule_patch(id~ : String, enabled? : Bool, confidence? : Int, placeholder? : String, label? : String) -> RulePatchfn run_all_benchmarks(repetitions : Int, config : RedactionConfig) -> Array[BenchmarkResult] raise DeidErrorfn run_benchmark_case(item : BenchmarkCase, repetitions : Int, config : RedactionConfig) -> BenchmarkResult raise DeidErrorfn safe_slice_by_code_units(text : String, start : Int, end : Int) -> Stringfn sanitize_log_batch(messages : Array[String], config : RedactionConfig) -> Array[String] raise DeidErrorfn scan_statistics(input : String, rules : Array[Rule], findings : Array[Finding]) -> ScanStatisticsfn section_summaries(_text : String, sections : Array[DocumentSection]) -> Array[SectionSummary] raise DeidErrorfn sections_of_kind(sections : Array[DocumentSection], kind : SectionKind) -> Array[DocumentSection]fn summarize_texts(texts : Array[String], config : RedactionConfig) -> Array[String] raise DeidErrorA MoonBit toolkit for detecting, replacing, and auditing PHI in Chinese and English clinical text.
Dependencies