Flag high-risk content before MCP tool calls - #448
Conversation
e1b03f7 to
269d7a4
Compare
|
Ready for review. The branch is rebased to current |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 269d7a4b6a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| function hasValidPaymentCard(value: string): boolean { | ||
| const candidates = value.match(/(?<!\d)(?:\d[ -]?){12,18}\d(?!\d)/g) ?? []; |
There was a problem hiding this comment.
Avoid consuming numeric fields after a payment card
When a valid PAN is followed by a space-separated numeric field, such as 4242 4242 4242 4242 12 34, this greedy expression consumes up to 19 digits as one candidate; the Luhn check then runs against the combined value and returns no finding. Card data commonly appears beside an expiry date or ZIP, so the detector should identify bounded PAN candidates rather than treating every adjacent digit group as part of the card.
Useful? React with 👍 / 👎.
| if (category && findings.length < MAX_FINDINGS) { | ||
| findings.push({ category, path }); | ||
| findings.push({ category, path, action: "block" }); |
There was a problem hiding this comment.
Preserve a blocking finding when review findings fill the cap
When 20 earlier values match review-only signals and a credential appears later, mustBlock becomes true but this length guard prevents the credential finding from being added. The resulting rejected-call audit payload contains only action: "review" findings and no category or path explaining what caused the block; reserve or replace a slot for blocking findings so the bounded result remains consistent with the rejection.
Useful? React with 👍 / 👎.
| "mcp.tools_discovered": "Tools offered for one run", | ||
| "mcp.call_succeeded": "Called on this Bot's behalf", | ||
| "mcp.call_rejected": "Blocked", | ||
| "mcp.content_flagged": "Content needs review", |
There was a problem hiding this comment.
Display what caused a content review flag
For every new mcp.content_flagged row, the admin page shows only this generic label: Row never reads payload.contentInspection.findings. Consequently payment-card, SSN, and prompt-injection events are indistinguishable and their audit-safe paths are inaccessible from the review UI, leaving administrators unable to determine what content needs review.
Useful? React with 👍 / 👎.
Summary
mcp.content_flaggedaudit events and an admin audit label without recording matched valuesASIA) and require Luhn-valid payment-card candidatesThis is a focused follow-up to #436 and continues the content-governance slice of #86.
Validation
bun test server/tests/content-governance.test.ts app/tests/audit-outcome.test.ts server/tests/audit.test.ts— 32 passedbun run format:check— passedbun run lint— passedbun run typecheck— passedPostgreSQL-backed integration tests remain delegated to repository CI.