agentleFS
MiladJoodiMiladJoodi/skills/skills/iran-validation/SKILL.md

iran-validation

Skill24 starsChanged 33 days agoMITView on GitHub

Validate and format Iranian identifiers correctly: national ID (کد ملی) checksum, legal entity ID (شناسه ملی), mobile numbers (۰۹…), landlines with area codes, IBAN / Sheba (شبا) mod-97, bank card numbers with Luhn and BIN lookup, postal code (کد پستی), vehicle plates (پلاک), and Persian/Arabic digit normalization. Use for signup, KYC, checkout, address, payment, profile, contact, or identity forms in Iranian products, or whenever the user mentions اعتبارسنجی، کد ملی، شناسه ملی، شبا، شماره کارت، شماره موبایل، تلفن ثابت، کد پستی، پلاک. Replaces US-style patterns such as SSN, ZIP codes, and US phone numbers with Iranian-specific formats and validation rules.

The file

Show its rules and text

We split this skill into the rules it gives an agent

47 rules. About 0 are common, 41 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈41

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    When building forms for Iranian users, do not automatically apply validation patterns from US or European products.

    line 17
  2. Distinctive:

    Do not treat a regular expression as complete validation when the identifier has a checksum or structural algorithm.

    line 29
  3. Distinctive:

    Before validation, convert Persian and Arabic-Indic digits to ASCII.

    line 42
  4. Distinctive:

    Do not blindly strip every non-digit character from every field.

    line 60
  5. Very specific:

    Never convert identifiers such as national IDs, postal codes, or card numbers to JavaScript number.

    line 78
  6. Very specific:

    If r < 2, the check digit must equal r.

    line 100
  7. Distinctive:

    Do not validate a legal entity's identifier using the personal national ID algorithm.

    line 144
  8. Very specific:

    Do not reuse isNationalId() for companies, organizations, or other legal entities.

    line 153
  9. Distinctive:

    Treat the legal entity identifier as a separate validation rule and keep its algorithm separate from the personal national ID …

    line 156
  10. Distinctive:

    When implementing this field:

    line 159
  11. Distinctive:

    keep it as a string;

    line 161
  12. Very specific:

    use a distinct function such as isLegalEntityId().

    line 165
  13. Distinctive:

    Do not silently assume that every 10-digit identifier is a personal national ID.

    line 167
  14. Distinctive:

    If the application only accepts domestic input, use the stricter form:

    line 220
  15. Distinctive:

    Do not reject a valid mobile number simply because its prefix is not in a hard-coded operator list.

    line 238
  16. Distinctive:

    Do not use the mobile-number validation rule for landlines.

    line 308
  17. Distinctive:

    Use the ISO 13616 IBAN validation process:

    line 350
  18. Very specific:

    Do not convert the entire value to JavaScript Number.

    line 360
  19. Distinctive:

    Keep bank-code mappings in a dedicated data file.

    line 395
  20. Distinctive:

    Do not guess a bank name when a code is unknown.

    line 397
  21. Distinctive:

    Use the Luhn checksum to detect structurally invalid card numbers.

    line 440
  22. Distinctive:

    Use BIN only for:

    line 469
  23. Distinctive:

    Do not scatter bank BINs throughout components.

    line 481
  24. Distinctive:

    Never store complete card numbers in application databases unless there is a specific, compliant reason to do so.

    line 503
  25. Distinctive:

    never log full card numbers.

    line 510
  26. Distinctive:

    never include full card numbers in analytics events.

    line 511
  27. Distinctive:

    never put card numbers in URLs.

    line 512
  28. Distinctive:

    avoid exposing them in client-side error reporting.

    line 513
  29. Distinctive:

    Do not invent checksum or structural rules if the application only needs the standard 10-digit postal-code format.

    line 556
  30. Distinctive:

    Do not use a free-form text field when the plate letter can be selected from the known allowed values.

    line 619
  31. Distinctive:

    If the plate type is unknown, ask or detect the type before applying a strict format.

    line 651
  32. Distinctive:

    Do not confuse it with:

    line 688
  33. Distinctive:

    Do not use locale formatting that unexpectedly changes identifiers into grouped decimal numbers.

    line 718
  34. Distinctive:

    Do not make formatting part of the validation algorithm.

    line 803
  35. Distinctive:

    Use three separate stages:

    line 811
  36. Distinctive:

    Do not validate the prettified display string directly when formatting adds spaces, dashes, or other UI-only characters.

    line 845
  37. Distinctive:

    Avoid technical messages such as:

    line 874
  38. Distinctive:

    Do not show an error on the first keystroke.

    line 888
  39. Distinctive:

    Do not immediately show:

    line 906
  40. Distinctive:

    Wait until the user finishes the field or submits the form.

    line 910
  41. Distinctive:

    Never rely exclusively on client-side validation.

    line 938
  42. Distinctive:

    Never log sensitive identifiers unnecessarily.

    line 943
  43. Very specific:

    Use string-based modulo or BigInt.

    line 983
  44. Distinctive:

    Keep validation logic independent from UI components.

    line 1017
  45. Distinctive:

    Do not duplicate the same validation algorithm across multiple forms.

    line 1044
  46. Distinctive:

    Keep formatting helpers separate:

    line 1070
  47. Distinctive:

    Before shipping an Iranian form:

    line 1089

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Iranian validation (اعتبارسنجی ایرانی)

When building forms for Iranian users, do not automatically apply validation patterns from US or European products. Iranian identifiers have their own formats, check digits, numbering systems, and input conventions.

This skill covers the validation, normalization, formatting, and UI behavior needed for common Iranian fields.

The general rule is:

Normalize the user's input first, validate against the Iranian rules second, and format the value for display separately from the stored value.

Do not treat a regular expression as complete validation when the identifier has a checksum or structural algorithm.


0. Normalize digits first

Iranian users commonly type numbers using:

  • Persian digits: ۰۱۲۳۴۵۶۷۸۹
  • Arabic-Indic digits: ٠١٢٣٤٥٦٧٨٩
  • ASCII digits: 0123456789

Before validation, convert Persian and Arabic-Indic digits to ASCII.

Also remove formatting characters that are intentionally accepted by the field, such as spaces, hyphens, and ZWNJ.

export function normalizeIranianDigits(input: string) {
  return input
    .replace(/[۰-۹]/g, (d) => String(d.charCodeAt(0) - 0x06f0))
    .replace(/[٠-٩]/g, (d) => String(d.charCodeAt(0) - 0x0660));
}

export function normalizeNumericInput(input: string) {
  return normalizeIranianDigits(input)
    .replace(/[\s‌_-]/g, "");
}

Do not blindly strip every non-digit character from every field.

For example:

  • IBAN may contain IR.
  • Vehicle plates contain Persian letters.
  • International mobile numbers may contain +.
  • Card and postal-code fields normally contain digits only.

Normalization should therefore be field-specific.

Display vs storage

Use two representations:

  • Storage: normalized ASCII value.
  • Display: Persian digits and human-friendly grouping.

Never convert identifiers such as national IDs, postal codes, or card numbers to JavaScript number. They are strings because leading zeros are meaningful.


1. National ID (کد ملی)

Iranian personal national IDs contain exactly 10 digits.

Rules

  • Exactly 10 digits.
  • Reject values where all 10 digits are identical.
  • The first nine digits participate in the checksum.
  • The final digit is the check digit.
  • Leading zeros are significant.

Checksum:

  1. Multiply the first nine digits by weights 10 through 2.
  2. Sum the results.
  3. Calculate r = sum % 11.
  4. If r < 2, the check digit must equal r.
  5. Otherwise, the check digit must equal 11 - r.
export function isNationalId(input: string) {
  const s = normalizeNumericInput(input);

  if (!/^\d{10}$/.test(s)) return false;
  if (/^(\d)\1{9}$/.test(s)) return false;

  const check = Number(s[9]);

  const sum = [...s.slice(0, 9)].reduce(
    (acc, digit, index) => acc + Number(digit) * (10 - index),
    0
  );

  const remainder = sum % 11;

  return remainder < 2
    ? check === remainder
    : check === 11 - remainder;
}

UI

<Input
  dir="ltr"
  inputMode="numeric"
  maxLength={10}
/>

Label:

کد ملی

Errors:

  • کد ملی باید ۱۰ رقم باشد.
  • کد ملی معتبر نیست.

Do not validate a legal entity's identifier using the personal national ID algorithm.


2. Legal entity ID (شناسه ملی)

The Iranian legal-entity identifier is different from a personal national ID.

Do not reuse isNationalId() for companies, organizations, or other legal entities.

Treat the legal entity identifier as a separate validation rule and keep its algorithm separate from the personal national ID implementation.

When implementing this field:

  • keep it as a string;
  • normalize Persian and Arabic-Indic digits;
  • validate the exact expected length;
  • implement the official checksum/rules separately;
  • use a distinct function such as isLegalEntityId().

Do not silently assume that every 10-digit identifier is a personal national ID.


3. Mobile numbers (شماره موبایل)

The common Iranian domestic mobile format is:

09xxxxxxxxx

That is 11 digits beginning with 09.

Examples:

09123456789
09351234567

Accepted formats

Support:

09123456789
+989123456789
00989123456789

Normalize the international forms to one consistent storage format.

E.164 is recommended for systems that communicate with external services:

+989123456789

A local 09... representation can be used consistently if the application is entirely domestic.

Validation

After normalization:

export function isIranianMobile(input: string) {
  const value = input.trim();

  return /^(?:\+98|0098|0)?9\d{9}$/.test(value);
}

If the application only accepts domestic input, use the stricter form:

/09\d{9}/

with the appropriate anchors.

Operator prefixes

Operator detection is only a hint.

Common prefixes include:

  • 091x → همراه اول
  • 093x → ایرانسل
  • 092x → رایتل

Do not reject a valid mobile number simply because its prefix is not in a hard-coded operator list. Number ranges can change and additional ranges exist.

UI

<Input
  dir="ltr"
  inputMode="tel"
  autoComplete="tel"
  placeholder="۰۹۱۲۳۴۵۶۷۸۹"
/>

Label:

شماره موبایل

Display grouping:

۰۹۱۲ ۳۴۵ ۶۷۸۹

Error:

شماره موبایل معتبر نیست.


4. Landlines (تلفن ثابت)

Iranian landlines use:

  • 0
  • a 2-digit area code
  • 8 local digits

Total:

11 digits

Examples:

02112345678
02612345678
03112345678
05112345678
07112345678
04112345678

Common area codes include:

  • تهران: 021
  • کرج: 026
  • اصفهان: 031
  • مشهد: 051
  • شیراز: 071
  • تبریز: 041

A basic structural check:

export function isIranianLandline(input: string) {
  const s = normalizeNumericInput(input);
  return /^0[1-9]\d{9}$/.test(s);
}

Do not use the mobile-number validation rule for landlines.

For applications that need strict geographic validation, maintain the area-code list separately rather than embedding a large list inside a UI component.

Display example:

۰۲۱-۱۲۳۴۵۶۷۸


5. IBAN / Sheba (شماره شبا)

Iranian Sheba numbers use the IBAN format:

IR + 2 check digits + 22 BBAN digits

Total:

26 characters

Example structure:

IR12 0170 0000 0000 0000 0000 00

Users may enter the number:

IR...

or sometimes only the 24 digits after IR.

Accepting the latter is a UI decision. If supported, prepend IR before validation.

Mod-97

Use the ISO 13616 IBAN validation process:

  1. Move the first four characters to the end.
  2. Convert letters to numbers:

    • I → 18
    • R → 27
  3. Calculate the resulting number modulo 97.
  4. A valid IBAN has remainder 1.

Do not convert the entire value to JavaScript Number. It is too large.

A chunked modulo implementation is safe:

export function isIranianIban(input: string) {
  let value = normalizeNumericInput(input)
    .toUpperCase()
    .replace(/\s/g, "");

  if (value.startsWith("IR")) {
    value = value.slice(2);
  }

  if (!/^\d{24}$/.test(value)) return false;

  const checkDigits = value.slice(0, 2);
  const bban = value.slice(2);

  const rearranged = `${bban}1827${checkDigits}`;

  let remainder = 0;

  for (const digit of rearranged) {
    remainder = (remainder * 10 + Number(digit)) % 97;
  }

  return remainder === 1;
}

Bank code

For Iranian Sheba numbers, the bank identifier appears inside the BBAN.

Keep bank-code mappings in a dedicated data file.

Do not guess a bank name when a code is unknown.

For example:

const iranianBankCodes = {
  // "017": "بانک ملی ایران",
  // ...
} as const;

The mapping should be maintained independently from the validation algorithm.

UI

<Input
  dir="ltr"
  inputMode="text"
  autoComplete="off"
/>

Label:

شماره شبا

Helper:

با IR یا بدون آن

Display with groups of four characters:

IR۱۲ ۰۱۷۰ ۰۰۰۰ ...


6. Bank cards (شماره کارت)

Iranian bank cards normally contain:

16 digits

Use the Luhn checksum to detect structurally invalid card numbers.

export function isLuhnValid(input: string) {
  const s = normalizeNumericInput(input);

  if (!/^\d{16}$/.test(s)) return false;

  let sum = 0;

  for (let i = 0; i < s.length; i++) {
    let digit = Number(s[i]);

    if (i % 2 === 0) {
      digit *= 2;
      if (digit > 9) digit -= 9;
    }

    sum += digit;
  }

  return sum % 10 === 0;
}

BIN / bank detection

The first six digits are commonly used as the BIN/IIN.

Use BIN only for:

  • showing the bank name;
  • showing a bank logo;
  • improving UX;
  • selecting a payment flow when explicitly required.

BIN must not be used as proof that a card is valid, active, owned by the user, or usable for payment.

Maintain the complete BIN table in a dedicated data file.

Do not scatter bank BINs throughout components.

Example stable mappings include:

const bankBins = {
  "603799": "بانک ملی ایران",
  "589210": "بانک سپه",
  "627353": "بانک تجارت",
  "610433": "بانک ملت",
  "603769": "بانک صادرات",
  "621986": "بانک سامان",
  "502229": "بانک پاسارگاد",
  "622106": "بانک پارسیان",
} as const;

The list is illustrative and should be maintained from a trusted, up-to-date source.

Security

Never store complete card numbers in application databases unless there is a specific, compliant reason to do so.

For saved cards:

  • store a token/reference when the payment provider supports it;
  • display only the last four digits;
  • never log full card numbers;
  • never include full card numbers in analytics events;
  • never put card numbers in URLs;
  • avoid exposing them in client-side error reporting.

UI

<Input
  dir="ltr"
  inputMode="numeric"
  autoComplete="cc-number"
/>

Display:

۶۰۳۷ ۹۹۱۱ ۲۳۴۵ ۶۷۸۹

Accept Persian and Arabic-Indic digits when pasted.


7. Postal code (کد پستی)

Iranian postal codes contain:

10 digits

They are commonly displayed in two groups:

۱۲۳۴۵-۶۷۸۹۰

Accept:

1234567890
12345-67890

Normalize before storage:

1234567890

Do not invent checksum or structural rules if the application only needs the standard 10-digit postal-code format.

export function isIranianPostalCode(input: string) {
  const s = normalizeNumericInput(input);
  return /^\d{10}$/.test(s);
}

UI:

<Input
  dir="ltr"
  inputMode="numeric"
  maxLength={10}
/>

Label:

کد پستی

Error:

کد پستی باید ۱۰ رقم باشد.


8. Vehicle plates (پلاک خودرو)

Do not confuse:

  • پلاک خودرو → vehicle license plate
  • پلاک in an address → building number

A standard private Iranian vehicle plate has a structure similar to:

۱۲ ب ۳۴۵ ایران ۱۱

The plate contains:

  • 2 digits
  • a Persian letter
  • 3 digits
  • a 2-digit regional code

For storage, a normalized representation can be used:

12ب345-11

Display it with Persian digits and the visual arrangement expected by the application.

Plate letters

The set of permitted Persian letters is restricted.

Do not use a free-form text field when the plate letter can be selected from the known allowed values.

For example:

const plateLetters = [
  "ب",
  "ج",
  "د",
  "س",
  "ص",
  "ط",
  "ع",
  "ق",
  "ل",
  "م",
  "ن",
  "و",
  "هـ",
  "ی",
];

The exact allowed set depends on plate type and should be maintained separately.

Motorcycle, public-service, diplomatic, government, temporary, and other plate types can have different structures.

Do not assume every Iranian plate follows the private-car format.

If the plate type is unknown, ask or detect the type before applying a strict format.


9. Address fields

Iranian addresses should follow a natural geographic hierarchy.

Recommended order:

استان
شهر
خیابان / محله
پلاک
واحد
کد پستی

Province and city should normally come from structured data rather than free text.

Use:

  • Select
  • Combobox
  • Searchable select

for province and city.

Keep:

پلاک

for the building number in an address context.

Do not confuse it with:

پلاک خودرو

for a vehicle plate.


10. Iranian digits in UI

Persian digits should be used for display when the product is Persian-first.

Examples:

۱۲۳۴۵
۰۹۱۲۳۴۵۶۷۸۹
۶۰۳۷ ۹۹۱۱ ۲۳۴۵ ۶۷۸۹

However, storage and algorithms should normally use ASCII digits:

12345
09123456789
6037991123456789

Important

Do not use locale formatting that unexpectedly changes identifiers into grouped decimal numbers.

Identifiers are strings, not numeric quantities.


11. Direction and input behavior

Persian labels and surrounding UI should remain RTL, but identifiers themselves are easier to read and enter as LTR.

Recommended pattern:

<div dir="rtl">
  <Label>کد ملی</Label>

  <Input
    dir="ltr"
    inputMode="numeric"
  />
</div>

Use:

  • RTL for the form and labels.
  • LTR for identifiers.
  • Persian digits for display when appropriate.
  • ASCII digits internally.

For mixed values such as IBAN, card numbers, phone numbers, and plate numbers, avoid letting the browser reorder characters unexpectedly.


12. Formatting while typing

Formatting should improve readability without changing the stored value.

Examples:

Card

Input:

6037991123456789

Display:

6037 9911 2345 6789

Sheba

Input:

IR123456789012345678901234

Display:

IR12 3456 7890 1234 5678 9012 34

Postal code

Input:

1234567890

Display:

12345-67890

Do not make formatting part of the validation algorithm.

A formatted display value should first be normalized and then validated.


13. Validation flow

Use three separate stages:

1. Normalize

Convert Persian/Arabic digits and remove only the formatting characters that the field explicitly allows.

2. Validate

Apply:

  • length checks;
  • character checks;
  • structural rules;
  • checksum algorithms;
  • field-specific rules.

3. Format

Convert the valid normalized value into the display format.

Conceptually:

const normalized = normalizeFieldValue(input);

if (!validateField(normalized)) {
  showError();
  return;
}

const formatted = formatField(normalized);

Do not validate the prettified display string directly when formatting adds spaces, dashes, or other UI-only characters.


14. Error messages

Error messages should be short, specific, and written naturally in Persian.

Examples:

FieldMessage
کد ملیکد ملی معتبر نیست.
موبایلشماره موبایل معتبر نیست.
تلفن ثابتشماره تلفن ثابت معتبر نیست.
شباشماره شبا معتبر نیست.
کارتشماره کارت معتبر نیست.
کد پستیکد پستی باید ۱۰ رقم باشد.
پلاک خودروپلاک خودرو معتبر نیست.

For length errors, explain the expected format:

کد ملی باید ۱۰ رقم باشد.
کد پستی باید ۱۰ رقم باشد.
شماره کارت باید ۱۶ رقم باشد.

Avoid technical messages such as:

Regex validation failed.
Invalid input pattern.
MOD-97 error.

The user does not need to know which algorithm rejected the value.


15. Validation timing

Do not show an error on the first keystroke.

Prefer:

  • validation after blur;
  • validation on submit;
  • or validation after the user has entered enough characters.

For fields with a known fixed length, validate progressively only when it improves UX and does not produce premature errors.

Example:

کد ملی
[۱۲۳]

Do not immediately show:

کد ملی معتبر نیست.

Wait until the user finishes the field or submits the form.


16. Security and privacy

Validation is not verification.

A valid checksum only means that an identifier has the correct mathematical structure.

It does not prove:

  • the identifier exists;
  • the identifier belongs to the user;
  • the bank account is active;
  • the card is usable;
  • the phone number belongs to the user.

For identity or payment flows, use a separate verification mechanism.

Examples:

  • OTP for mobile ownership;
  • payment-provider verification;
  • official identity-verification services;
  • server-side account checks.

Never rely exclusively on client-side validation.

Client-side validation is for UX. Important validation must also run on the server.

Never log sensitive identifiers unnecessarily.

Avoid logging:

  • complete national IDs;
  • complete card numbers;
  • complete IBANs;
  • authentication codes;
  • personal address information.

17. Common mistakes

Mistake: using US validation

/^\d{9}$/

for an Iranian national ID is not sufficient.

Mistake: treating national ID as a number

const nationalId = Number(input);

This can remove leading zeros.

Use:

const nationalId = input;

Mistake: using Number() for IBAN

IBAN values are strings and can exceed JavaScript's safe integer range.

Use string-based modulo or BigInt.

Mistake: using mobile validation for landlines

These are different identifiers.

Mistake: rejecting unknown mobile prefixes

Operator prefix lists should not be treated as the complete definition of a valid Iranian mobile number.

Mistake: using BIN as card validation

BIN identifies the issuing bank range. It does not prove that the card number is valid.

Mistake: validating formatted values

Spaces and dashes belong to presentation, not the canonical stored value.

Mistake: assuming all vehicle plates have one format

Iranian plate types differ.

Mistake: confusing address plate and vehicle plate

پلاک in an address means building number.

پلاک خودرو means vehicle license plate.


18. Recommended helper structure

Keep validation logic independent from UI components.

A practical structure is:

lib/
  iran/
    digits.ts
    national-id.ts
    legal-entity-id.ts
    mobile.ts
    landline.ts
    iban.ts
    card.ts
    postal-code.ts
    plate.ts
    banks.ts
    index.ts

Or, for a smaller project:

lib/
  iranian-validation.ts

Do not duplicate the same validation algorithm across multiple forms.

For example, every national-ID field should use the same isNationalId() implementation.


19. Example API

A shared validation API can look like:

export {
  normalizeIranianDigits,
  normalizeNumericInput,
  isNationalId,
  isLegalEntityId,
  isIranianMobile,
  isIranianLandline,
  isIranianIban,
  isLuhnValid,
  isIranianPostalCode,
  isIranianPlate,
};

Keep formatting helpers separate:

export {
  formatIranianDigits,
  formatCardNumber,
  formatSheba,
  formatPostalCode,
  formatMobileNumber,
  formatPlate,
};

Validation and formatting should not be coupled.


20. Checklist

Before shipping an Iranian form:

  1. Persian digits are accepted.
  2. Arabic-Indic digits are accepted where appropriate.
  3. Digits are normalized before validation.
  4. Identifiers are stored as strings.
  5. National ID uses the Iranian checksum algorithm.
  6. Legal entity ID is not validated as a personal national ID.
  7. Mobile numbers use Iranian 09... rules.
  8. International mobile numbers are normalized consistently.
  9. Operator detection is treated as a hint, not a validation gate.
  10. Landlines use area-code rules rather than mobile rules.
  11. Sheba uses the correct IR + 24 digits structure.
  12. Sheba validation uses mod-97 without unsafe numeric conversion.
  13. Bank codes are maintained separately from validation logic.
  14. Card numbers use 16-digit structural validation and Luhn.
  15. BIN is used for bank identification, not card acceptance.
  16. Full card numbers are never unnecessarily stored or logged.
  17. Postal codes use 10 digits.
  18. Vehicle plates are validated according to their plate type.
  19. Address پلاک is not confused with vehicle پلاک.
  20. Inputs containing identifiers use dir="ltr" inside RTL forms.
  21. Persian labels and error messages remain RTL.
  22. Display formatting is separate from canonical storage.
  23. Client-side validation is backed by server-side validation.
  24. Validation errors are not shown prematurely.
  25. Checksum validity is never presented as identity or ownership verification.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.