Check Bidi Safety
localization.bidi_safety_check
Overview
You send text and a context. We count explicit bidi controls, walk embeddings and isolates, and flag a leftover pop, a deprecated LRO or RLO, a control inside an identifier, or a Trojan-Source pattern in source. Arabic and Hebrew letters without controls stay safe. We do not strip, render or call it malware. A successful call costs 1 execution credit.
Trojan Source and unbalanced isolates change what a reviewer sees. A model cannot prove stack balance from a glance at the string.
Reliability
Same text, same context, same ICU version, same answer. Findings always include utf16Offset and codePointOffset. Structural problems return safe false with diagnostics rather than a typed failure.
Context footprint
One string in. A successful call costs 1 execution credit.
When to use it
When you hold a string and need to know whether its bidi controls are safe for that context.
When you want to generate pseudo-RTL copy, or to detect language.
Powered by ICU4J bidirectional analysis (com.ibm.icu:icu4j).
Scope
Non-goals
- Does not render the visual order
- Does not strip or rewrite controls
- Does not issue a malware verdict
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
How we handle your data
What this means
This skill may receive sensitive content, but it does not target sensitive data and returns only a structured non-sensitive result.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response does not contain submitted content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| text | string | Yes | String to scan for explicit bidirectional controls and unbalanced embeddings. |
| context | string | Yes | PLAIN_TEXT, IDENTIFIER or SOURCE_CODE; each applies a different control policy. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| safe | boolean | Yes | True when every diagnostic is a warning or the list is empty; false when an error exists. |
| controlCounts | object | Yes | Closed counts of explicit bidirectional controls: lre rle pdf lro rlo lri rli fsi pdi lrm rlm alm. |
| diagnostics | array | Yes | From 0 through 500 diagnostics sorted by path, offset, severity and code; empty when nothing was flagged. |
| _meta | object | Yes | Closed ICU and CLDR versions used for this answer, with icuVersion and cldrVersion strings. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"localization.bidi_safety_check","input":{"text":"Hello","context":"PLAIN_TEXT"}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("localization.bidi_safety_check", {"context":"PLAIN_TEXT","text":"Hello"});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- Does not render the visual order
- Does not strip or rewrite controls
- Does not issue a malware verdict
- Turning English copy into a pseudo-RTL string
- Detecting the language of a paragraph
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "localization.bidi_safety_check",
"input": {
"context": "PLAIN_TEXT",
"text": "Hello"
}
}Examples
Balanced isolate in plain text
{
"context": "PLAIN_TEXT",
"text": "Hello"
}{
"diagnostics": [],
"safe": true,
"_meta": {
"icuVersion": "76.1",
"cldrVersion": "46.0"
},
"controlCounts": {
"lre": 0,
"rle": 0,
"pdf": 0,
"lro": 0,
"rlo": 0,
"lri": 0,
"rli": 1,
"fsi": 0,
"pdi": 1,
"lrm": 0,
"rlm": 0,
"alm": 0
}
}Right-to-left override in source
{
"context": "SOURCE_CODE",
"text": "if (ok) // {"
}{
"diagnostics": [
{
"code": "DEPRECATED_OVERRIDE",
"severity": "ERROR",
"message": "U+202E RIGHT-TO-LEFT OVERRIDE is deprecated.",
"path": "text",
"location": {
"utf16Offset": 10,
"codePointOffset": 10
},
"source": "squillify"
},
{
"code": "TROJAN_SOURCE",
"severity": "ERROR",
"message": "A bidirectional embedding, override or isolate can disguise source.",
"path": "text",
"location": {
"utf16Offset": 10,
"codePointOffset": 10
},
"source": "squillify"
},
{
"code": "UNBALANCED_EMBEDDING",
"severity": "ERROR",
"message": "A bidirectional embedding or override was never popped.",
"path": "text",
"location": {
"utf16Offset": 10,
"codePointOffset": 10
},
"source": "squillify"
}
],
"safe": false,
"_meta": {
"icuVersion": "76.1",
"cldrVersion": "46.0"
},
"controlCounts": {
"lre": 0,
"rle": 0,
"pdf": 0,
"lro": 0,
"rlo": 1,
"lri": 0,
"rli": 0,
"fsi": 0,
"pdi": 0,
"lrm": 0,
"rlm": 0,
"alm": 0
}
}Recommended use cases
- Rejecting a source file that contains U+202E before it is reviewed
- Allowing Arabic or Hebrew copy that has no bidi controls
Avoid for
- Turning English copy into a pseudo-RTL string
- Detecting the language of a paragraph
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.