Skip to content

Commit 80af42c

Browse files
mhallidaclaude
andcommitted
fix: altimate_core_classify_pii detects credit card columns
The Rust PII classifier doesn't have a CreditCard category. Added TypeScript-level pattern matching for credit_card_number, card_last_four, card_expiry, cvv, cardholder, and similar column names, classified as "Financial" PII with 0.9 confidence. Fixes TICKET-015 in #422. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
1 parent a49661a commit 80af42c

1 file changed

Lines changed: 44 additions & 2 deletions

File tree

‎packages/opencode/src/altimate/native/altimate-core.ts‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,12 +573,54 @@ register("altimate_core.grade", async (params) => {
573573
}
574574
})
575575

576-
// 17. altimate_core.classify_pii
576+
// 17. altimate_core.classify_pii — with credit card pattern augmentation
577577
register("altimate_core.classify_pii", async (params) => {
578578
try {
579579
const schema = schemaOrEmpty(params.schema_path, params.schema_context)
580580
const raw = core.classifyPii(schema)
581-
return ok(true, toData(raw))
581+
const data = toData(raw)
582+
583+
// Augment: add credit card patterns that Rust PII classifier misses
584+
const creditCardPatterns = [
585+
/credit.?card/i, /card.?number/i, /cc.?num/i, /card.?no/i,
586+
/card.?last.?four/i, /last.?four/i, /card.?expir/i, /expiry.?date/i,
587+
/cvv/i, /cvc/i, /card.?holder/i, /cardholder/i, /pan(?:_|\b)/i,
588+
]
589+
590+
const columns = (data.columns as any[]) ?? []
591+
const existingCols = new Set(columns.map((c: any) => `${c.table}.${c.column}`))
592+
593+
// Scan schema tables for credit card column patterns
594+
const schemaJson = schema.toJson()
595+
if (schemaJson?.tables) {
596+
for (const [tableName, tableDef] of Object.entries(schemaJson.tables)) {
597+
const table = tableDef as any
598+
for (const col of table.columns ?? []) {
599+
const colKey = `${tableName}.${col.name}`
600+
if (existingCols.has(colKey)) continue
601+
602+
const isCreditCard = creditCardPatterns.some((p) => p.test(col.name))
603+
if (isCreditCard) {
604+
columns.push({
605+
table: tableName,
606+
column: col.name,
607+
classification: "Financial",
608+
confidence: 0.9,
609+
detection_method: "column_name_pattern",
610+
suggested_masking: "hash",
611+
})
612+
existingCols.add(colKey)
613+
}
614+
}
615+
}
616+
}
617+
618+
data.columns = columns
619+
data.pii_count = columns.filter((c: any) =>
620+
c.classification !== "None" && c.confidence > 0,
621+
).length
622+
623+
return ok(true, data)
582624
} catch (e) {
583625
return fail(e)
584626
}

0 commit comments

Comments
 (0)