agentleFS
OpenLinkSoftwareOpenLinkSoftware/ai-agent-skills/openlink-request-broker-configurator/SKILL.md

openlink-request-broker-configurator

Skill42 starsChanged 50 days agoMITView on GitHub

Configure and manage the OpenLink Request Broker (oplrqb) rule book

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 10 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈10

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    → Full parameter reference: Read references/rulebook-structure.md

    line 25
  2. Very specific:

    → www_sv endpoint reference: Read references/broker-www_sv-endpoints.md

    line 26
  3. Very specific:

    → JDBC driver registry: Read references/jdbc-driver-registry.md

    line 27
  4. Very specific:

    → ODBC DSN examples and token naming: Read references/odbc-dsn-examples.md

    line 28
  5. Distinctive:

    If the user names a specific mode or protocol, follow that preference instead.

    line 41
  6. Very specific:

    Every DB agent binary reports its own version banner, same pattern as oplrqb +version.

    line 201
  7. Very specific:

    Always run inicheck before attempting a broker reinit:

    line 278
  8. Distinctive:

    Use the Read tool to read the rulebook, then the Edit tool to make targeted replacements.

    line 293
  9. Distinctive:

    When the user asks to configure ODBC agents:

    line 323
  10. Very specific:

    Mode A: Use list_dsns() Python snippet above.

    line 333
  11. Distinctive:

    Ensure this rule exists (it is in the default rulebook already):

    line 366
  12. Distinctive:

    After all changes: reinitialize the broker (see Step 6 below).

    line 382
  13. Distinctive:

    When the user asks to configure JDBC agents:

    line 388
  14. Very specific:

    → Full registry with URL templates: Read references/jdbc-driver-registry.md

    line 408
  15. Distinctive:

    Always confirm with the user before executing privileged commands.

    line 471
  16. Very specific:

    Sudo note: If oplshut requires sudo and Claude Code has no TTY, configure passwordless sudo (same pattern as openlink-license-manager …

    line 506
  17. Distinctive:

    Run Step 0 — detect OS, check www_sv, resolve rulebook path

    line 560
  18. Distinctive:

    If www_sv binary found but not running: offer to start it

    line 561
  19. Distinctive:

    Ask what to do:

    line 564

≈ “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

OpenLink Request Broker Configurator Skill

Purpose

Configure and manage the OpenLink Request Broker (oplrqb) rule book (oplrqb.ini). The rule book controls:

  • Mapping Rules — which DB agent handles each incoming connection request
  • [generic_<name>] sections — per-agent program, environment, and connection defaults
  • [Environment <type>]sections — OS environment variables injected into each agent process
  • Broker global settings — port, timeouts, security, protocol parameters

Primary use cases: configure ODBC Agent rules from host-installed DSNs and JDBC Agent rules from discovered JDBC driver JARs.

→ Full parameter reference: Read references/rulebook-structure.md → www_sv endpoint reference: Read references/broker-www_sv-endpoints.md → JDBC driver registry: Read references/jdbc-driver-registry.md → ODBC DSN examples and token naming: Read references/odbc-dsn-examples.md


Execution Routing

Default execution order:

  1. Mode C (www_sv) — HTTP Admin Assistant at http://localhost:8000 (preferred when available)
  2. Mode A (direct file edit + CLI) — edit oplrqb.ini directly and use oplrqb CLI commands
  3. Terminal-owned OAuth flow — when a REST endpoint requires OAuth 2.0 authentication, execute the OAuth flow from the terminal (authorization code, client credentials, or device flow), capture the Bearer token, and inject it into subsequent REST/OpenAPI calls via Authorization: Bearer {token} headers
  4. MCP — if a remote MCP-enabled Virtuoso instance exposes broker management tools

If the user names a specific mode or protocol, follow that preference instead.


Step 0 — Mode Detection

Always run first.

# 1. Is www_sv responding? (Mode C)
curl -s http://localhost:8000/ | grep -i "openlink\|admin" | head -3

# 2. Is www_sv binary present but not running?
ls "/Library/Application Support/openlink/bin/www_sv" 2>/dev/null   # macOS
ls /opt/openlink/bin/www_sv 2>/dev/null                              # Linux

# 3. Is the rulebook directly accessible? (Mode A)
ls "/Library/Application Support/openlink/bin/oplrqb.ini" 2>/dev/null  # macOS
ls /opt/openlink/bin/oplrqb.ini 2>/dev/null                             # Linux

Decision:

  • www_sv responds at port 8000 → Mode C
  • www_sv binary found but not running → ask user "www_sv is installed but not running — start it?" → if yes, start it (see below) → Mode C
  • Rulebook file accessible but www_sv unavailable → Mode A
  • Neither → ask user which path to take

Starting www_sv (macOS):

nohup "/Library/Application Support/openlink/bin/www_sv" > /tmp/www_sv.log 2>&1 &
sleep 2 && curl -s http://localhost:8000/ | grep -i openlink

Credentials: www_sv uses HTTP Basic Authentication. Prompt for uid and pwd once at session start. Never write credentials to disk.


Platform Paths

ResourcemacOSLinux
Rule book/Library/Application Support/openlink/bin/oplrqb.ini/opt/openlink/bin/oplrqb.ini
Broker binary/Library/Application Support/openlink/bin/oplrqb/opt/openlink/bin/oplrqb
Shutdown util/Library/Application Support/openlink/bin/oplshut/opt/openlink/bin/oplshut
inicheck util/Library/Application Support/openlink/bin/inicheck/opt/openlink/bin/inicheck
Log (default)/Library/Application Support/openlink/bin/oplrqb.log/opt/openlink/bin/oplrqb.log
www_sv binary/Library/Application Support/openlink/bin/www_sv/opt/openlink/bin/www_sv
ODBC config (system)/Library/ODBC/odbc.ini/etc/odbc.ini
ODBC config (user)~/Library/ODBC/odbc.ini~/.odbc.ini

Mode C — www_sv HTTP Admin Assistant (Preferred)

Base URL: http://localhost:8000 Auth: -u <uid>:<pwd> on every curl call.

C1. Discover Host DSNs (for ODBC Agent wizard)

curl -s -u <uid>:<pwd> http://localhost:8000/scripts/odbcdsn

Parse the HTML response to extract DSN names, or use Mode A's configparser approach for a clean list.

C2. View Full Rulebook (plain text)

curl -s -u <uid>:<pwd> "http://localhost:8000/scripts/brkbook?mode=plain"

Parse with Python configparser.RawConfigParser(strict=False, delimiters=('=',)).

Download as file:

curl -s -u <uid>:<pwd> "http://localhost:8000/scripts/brkbook?mode=save" -o /tmp/oplrqb_backup.ini

C3. View / Edit Broker Global Settings

# View
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brksetup

# Edit — POST changed keys
curl -s -u <uid>:<pwd> -X POST http://localhost:8000/scripts/brksetup \
  -d "BinaryDirectory=%2FLibrary%2FApplication+Support%2Fopenlink%2Fbin&Listen=5001&MaxAgents=0&HostNameResolver=Yes"

POST fields: BinaryDirectory, Listen, MaxAgents, MaxConnections, HostNameResolver, LingerTimeout, PingWatchdog, PingInterval, SendSize, ReceiveSize, BrokerTimeout, StartupBy, ShutdownBy, ShutdownFrom

C4. View / Edit DB Agent Sections

# List all agent sections
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brkagents

# View one agent
curl -s -u <uid>:<pwd> "http://localhost:8000/scripts/brkagents?agent=generic_odbc"

# Edit an agent — POST
curl -s -u <uid>:<pwd> -X POST http://localhost:8000/scripts/brkagents \
  -d "agent=generic_odbc_MyDSN&Program=odbc_mv&Environment=ODBC&ReUse=always&Database=MyDSN&Description=ODBC+agent+for+MyDSN"

POST fields: agent, Program, Description, CommandLine, Directory, Database, UserID, Password, ConnectOptions, ReadOnly, ServerOptions, OpsysLogin, ReUse, Environment, SSLKeyFile, SSLRequired

C5. View / Edit Mapping Rules

# View
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brkmaped

# Add a rule
curl -s -u <uid>:<pwd> -X POST http://localhost:8000/scripts/brkmaped \
  -d "action=add&domain=odbc&db=MyDSN&uid=*&opsys=*&machine=*&appl=*&mode=*&target=generic_odbc_MyDSN"

# Delete a rule (by 1-based index)
curl -s -u <uid>:<pwd> -X POST http://localhost:8000/scripts/brkmaped \
  -d "action=delete&rule=<index>"

Rule fields: domain, db, uid, opsys, machine, appl, mode; target = generic_<name> for accept or a message for reject.

C6. View / Edit Alias Sections

# View Domain Aliases
curl -s -u <uid>:<pwd> "http://localhost:8000/scripts/brkalias?atype=Domain+Aliases"

# Add a Domain Alias
curl -s -u <uid>:<pwd> -X POST http://localhost:8000/scripts/brkalias \
  -d "atype=Domain+Aliases&action=add&key=MyDB+JDBC&value=myjdbc"

Valid atype values: Domain Aliases, Database Aliases, Opsys Aliases, Machine Aliases, Application Aliases, User Aliases

C7. Utility Endpoints

# Reinitialize broker (reload rulebook — preferred after edits)
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brkinit

# View broker log
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brklog

# Broker version
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brkver

# Active connections
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brkconn

# License info
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brklic

Success detection: POST responses contain "Configuration Updated" on success, "Sorry, this operation failed" on error.

C8. Agent Binary Versions

Every DB agent binary reports its own version banner, same pattern as oplrqb +version. Resolve <agent> from the Program value in the relevant [generic_<name>] rulebook section (e.g. odbc_mv, sqlite_mv, jdbc90_mv):

# macOS (Linux: /opt/openlink/bin/<agent>)
"/Library/Application Support/openlink/bin/<agent>" +version 2>&1 | head -4

# Equivalents — all emit the same banner:
"/Library/Application Support/openlink/bin/<agent>" "-?" 2>&1 | head -4
"/Library/Application Support/openlink/bin/<agent>" --version 2>&1 | head -4

Verified examples:

  • odbc_mv +version → ODBC Database Agent, Version 1.25 as of Wed Sep 09 2026 (Release 10.0, g04357c896)
  • sqlite_mv +version → SQLite Database Agent (multi threaded), Version 1.0 as of Wed Sep 02 2026
  • jdbc90_mv +version → JDBC Database Agent (JDK 90)(multi threaded), Version 1.46 as of Wed Aug 19 2026

There is no www_sv endpoint for agent versions — always query the binary directly. Compare the Release / git-hash segment against the broker banner to confirm a consistent build train.


Mode A — Direct File Operations (Fallback)

A1. Read Rulebook

import configparser, os

RULEBOOK_PATHS = [
    '/Library/Application Support/openlink/bin/oplrqb.ini',  # macOS
    '/opt/openlink/bin/oplrqb.ini',                          # Linux
    '/etc/openlink/oplrqb.ini',                              # Linux alt
]

def read_rulebook():
    cfg = configparser.RawConfigParser(strict=False, delimiters=('=',))
    for path in RULEBOOK_PATHS:
        if os.path.exists(path):
            cfg.read(path)
            return cfg, path
    return None, None

cfg, path = read_rulebook()
for section in cfg.sections():
    print(f'\n[{section}]')
    for k, v in cfg.items(section):
        print(f'  {k} = {v}')

Important: Use RawConfigParser(strict=False, delimiters=('=',)). The [Mapping Rules] section contains keys like odbc:*:*:*:*:*:* — colons in keys will confuse the default parser if colon is treated as a delimiter.

A2. Discover Host DSNs (for ODBC Agent wizard)

import configparser, os

def list_dsns():
    dsns = []
    paths = [
        '/Library/ODBC/odbc.ini',            # macOS system
        os.path.expanduser('~/Library/ODBC/odbc.ini'),  # macOS user
        '/etc/odbc.ini',                      # Linux system
        os.path.expanduser('~/.odbc.ini'),    # Linux user
    ]
    for p in paths:
        if os.path.exists(p):
            cfg = configparser.RawConfigParser(strict=False)
            cfg.read(p)
            for sec in cfg.sections():
                if sec.lower() not in ('odbc data sources',):
                    dsns.append(sec)
    return sorted(set(dsns))

print('\n'.join(list_dsns()))

A3. Validate After Edits

Always run inicheck before attempting a broker reinit:

# macOS
"/Library/Application Support/openlink/bin/inicheck" \
  "/Library/Application Support/openlink/bin/oplrqb.ini"

# Linux
/opt/openlink/bin/inicheck /opt/openlink/bin/oplrqb.ini

Exit code 0 = valid. Any error output must be fixed before proceeding.

A4. Editing Sections

Use the Read tool to read the rulebook, then the Edit tool to make targeted replacements. Prefer line-precise edits to preserve existing comments.

Appending a new agent section — add after the last [generic_odbc*] block:

[generic_odbc_MyDSN]
Description     = ODBC agent for MyDSN
Program         = odbc_mv
Environment     = ODBC
ReUse           = always
Database        = MyDSN
;Userid         =
;Password       =
;ReadOnly       = Yes

Appending a new Environment section — add after [Environment ODBC]:

[Environment JDBC_MyDriver]
CLASSPATH       = /path/to/mydriver.jar

Adding a Mapping Rule — insert before the odbc:*:*:*:*:*:* catch-all in [Mapping Rules]:

odbc:MyDSN:*:*:*:*:*         = accept generic_odbc_MyDSN

ODBC Agent Configuration Wizard

When the user asks to configure ODBC agents:

Step ODBC-1: Discover DSNs

Mode C:

curl -s -u <uid>:<pwd> http://localhost:8000/scripts/odbcdsn

Parse HTML for DSN names, or parse odbc.ini directly (Mode A method above).

Mode A: Use list_dsns() Python snippet above.

Step ODBC-2: Present List

Display discovered DSNs and ask: "Which DSNs should have dedicated ODBC Agent rules? Enter DSN names (comma-separated) or 'all' for a single catch-all rule."

Step ODBC-3: Generate for Each Selected DSN

For each DSN <dsnname> (URL-encode spaces as + for POST, or use underscore-normalized names for section keys):

Domain Alias — add to [Domain Aliases] if not already present:

<dsnname>   = odbc_<normalized_name>

Where <normalized_name> is the DSN name lowercased with spaces replaced by underscores.

Agent section [generic_odbc_<normalized_name>]:

[generic_odbc_<normalized_name>]
Description     = ODBC agent for <dsnname>
Program         = odbc_mv
Environment     = ODBC
ReUse           = always
Database        = <dsnname>

Mapping Rule in [Mapping Rules] — insert before the existing odbc:*:*:*:*:*:* catch-all:

odbc:<dsnname>:*:*:*:*:*     = accept generic_odbc_<normalized_name>

Step ODBC-4: Catch-all Fallback (if user selects "all")

Ensure this rule exists (it is in the default rulebook already):

odbc:*:*:*:*:*:*             = accept generic_odbc

And the stock [generic_odbc] section is present:

[generic_odbc]
Description     = Default settings for ODBC agent
Program         = odbc_mv
Environment     = ODBC
ReUse           = always

Step ODBC-5: Reinitialize

After all changes: reinitialize the broker (see Step 6 below).


JDBC Agent Configuration Wizard

When the user asks to configure JDBC agents:

Step JDBC-1: Discover JDBC Driver JARs

# 1. Scan $CLASSPATH entries for JAR files
echo $CLASSPATH | tr ':' '\n' | grep '\.jar$'

# 2. Check common JAR directories if $CLASSPATH is unset or empty
for d in /usr/local/lib ~/lib /opt/jdbc /Library/Java/Extensions /usr/share/java; do
  ls "$d"/*.jar 2>/dev/null
done

# 3. Peek inside each JAR for JDBC SPI registration
# (run for each discovered JAR)
unzip -p <jar-path> META-INF/services/java.sql.Driver 2>/dev/null

Step JDBC-2: Match JARs to Driver Registry

→ Full registry with URL templates: Read references/jdbc-driver-registry.md

Quick reference:

JAR PatternDriver ClassDefault JDBC Version
virtuoso-jdbc*.jarvirtuoso.jdbc4.DriverJDBC 4
ojdbc*.jaroracle.jdbc.OracleDriverJDBC 4
postgresql-*.jarorg.postgresql.DriverJDBC 4
mssql-jdbc-*.jarcom.microsoft.sqlserver.jdbc.SQLServerDriverJDBC 4
mysql-connector*.jarcom.mysql.cj.jdbc.DriverJDBC 4
ifxjdbc.jarcom.informix.jdbc.IfxDriverJDBC 4
openlink-jdbc*.jaropenlink.jdbc4.DriverJDBC 4

Step JDBC-3: Present Discovered Drivers

List matched drivers and ask: "Which JDBC drivers should have agent rules? Enter numbers (comma-separated) or 'all'."

Step JDBC-4: Prompt for URL Parameters

For each selected driver, display the URL template from the registry and prompt:

  • Host (default: localhost)
  • Port (default: driver-specific)
  • Database/SID/Schema name

Step JDBC-5: Generate for Each Selected Driver

Select the appropriate JDBC version slot. The rulebook has pre-defined slots jdbc11 through jdbc18. Use the first unused slot, or create a new labeled slot.

[Environment JDBC<n>] — update or create:

[Environment JDBC<n>]
CLASSPATH       = <jar-path>

[generic_jdbc<n>] — agent section:

[generic_jdbc<n>]
Description     = <Driver display name> JDBC agent
Program         = jdbc<n>_sv
Environment     = JDBC<n>
ReUse           = never
;Database       = <jdbc-url-with-filled-params>

Domain Alias in [Domain Aliases]:

<DbType> JDBC   = jdbc<n>

Mapping Rule in [Mapping Rules]:

jdbc<n>:*:*:*:*:*:*           = accept generic_jdbc<n>

Step JDBC-6: Reinitialize

After all changes: reinitialize the broker (see Step 6 below).


Step 6 — Broker Restart / Reinitialize

Always confirm with the user before executing privileged commands.

Reinitialize (preferred after rulebook edits — reloads config, keeps connections alive):

# Via www_sv (Mode C)
curl -s -u <uid>:<pwd> http://localhost:8000/scripts/brkinit

# Via CLI (Mode A) — macOS
"/Library/Application Support/openlink/bin/oplshut" +reinit

# Via CLI (Mode A) — Linux (systemd)
sudo systemctl reload oplrqb

# Via CLI (Mode A) — Linux (direct)
/opt/openlink/bin/oplshut +reinit

Full restart:

# macOS
"/Library/Application Support/openlink/bin/oplshut" +yes
nohup "/Library/Application Support/openlink/bin/oplrqb" > /tmp/oplrqb_start.log 2>&1 &
sleep 3 && curl -s http://localhost:8000/scripts/brkver

# Linux (systemd)
sudo systemctl restart oplrqb
sudo systemctl status oplrqb

# Linux (direct)
/opt/openlink/bin/oplshut +yes
nohup /opt/openlink/bin/oplrqb > /tmp/oplrqb_start.log 2>&1 &

Sudo note: If oplshut requires sudo and Claude Code has no TTY, configure passwordless sudo (same pattern as openlink-license-manager skill):

echo 'USERNAME ALL=(ALL) NOPASSWD: /path/to/oplshut' | sudo tee /etc/sudoers.d/oplshut && sudo chmod 440 /etc/sudoers.d/oplshut

Quick Reference Table

TaskMode C (www_sv)Mode A (Direct file)
View full rulebookcurl .../brkbook?mode=plainconfigparser.read(oplrqb.ini)
Discover host DSNscurl .../odbcdsnParse odbc.ini with configparser
Configure ODBC agentsODBC wizard (Steps ODBC-1–5)ODBC wizard (Steps ODBC-1–5)
Configure JDBC agentsJDBC wizard (Steps JDBC-1–6)JDBC wizard (Steps JDBC-1–6)
Edit broker globalsPOST to brksetupEdit [Request Broker] section
View mapping rulescurl .../brkmapedRead [Mapping Rules] section
Add mapping rulePOST to brkmaped action=addAppend line to [Mapping Rules]
View agent settingscurl .../brkagents?agent=<name>Read [generic_<name>] section
Edit agent settingsPOST to brkagentsEdit [generic_<name>] section
View broker logcurl .../brklogtail the log file
Versioncurl .../brkveroplrqb +version
Agent versionn/a — query binary directly (C8)<agent>_mv +version (also -?, --version)
Reload rulebookcurl .../brkinitoplshut +reinit
Full restartStop + startoplshut +yes → oplrqb &
Validate editsAutomatic (www_sv)inicheck oplrqb.ini

Troubleshooting

SymptomCauseFix
www_sv not respondingNot started or port conflictStart binary; check port 8000 not taken
www_sv auth failsWrong admin passwordCheck www_sv.ini [User admin] Password
brkbook?mode=plain emptyRulebook path wrong in www_svVerify oplrqb.ini path
Edit not taking effectBroker not reinitializedoplshut +reinit or brkinit
inicheck errorsBad ini syntaxFix syntax; re-run inicheck
Mapping rule not matchingWrong rule order or alias mismatchPut specific rules above catch-all; verify [Domain Aliases] token for the domain
Agent not found / rejectedMissing [generic_x] sectionAdd agent section; verify Program binary path
+reinit failsBroker not currently runningStart broker first
No DSNs foundODBC config not at default pathSpecify path explicitly or check $ODBCINI
JAR not matchedNon-standard JAR filenamePeek inside JAR: unzip -p <jar> META-INF/services/java.sql.Driver
JDBC agent rejectedCLASSPATH not set in [Environment JDBC<n>]Add CLASSPATH = <jar-path> to the environment section
oplshut sudo: terminal requiredNo TTY in Claude Code shellConfigure passwordless sudo for oplshut

Initialization Sequence

When invoked:

⛔ PRE-BUILD CHECK: Before producing output, re-read the relevant workflow section above and re-read any checklists or verification gates defined in this skill. Confirm each checklist item before writing output. Build to pass — do not retro-fit. Apply the CLAUDE.md Anti-Drift Protocol: re-read spec section before build, gate-first validation, section-by-section delivery.

  1. Run Step 0 — detect OS, check www_sv, resolve rulebook path
  2. If www_sv binary found but not running: offer to start it
  3. Report: mode, OS, rulebook path, broker version, listen port (plus agent binary versions via C8 on request)
  4. Prompt www_sv credentials if Mode C (session only)
  5. Ask what to do:
    • Configure ODBC Agents → run ODBC wizard (Steps ODBC-1 through ODBC-5)
    • Configure JDBC Agents → run JDBC wizard (Steps JDBC-1 through JDBC-6)
    • View rulebook → full plain-text dump
    • Edit mapping rules → show current rules; offer add/delete
    • Edit agent settings → list agents; offer edit
    • Edit broker global settings → show current; offer edit
    • View broker log → tail last 50 lines
    • Reinitialize / restart broker → confirm then execute
    • Validate → run inicheck and report result

Version

1.1.0 — Added agent binary version detection (C8: <agent>_mv +version / -? / --version, verified against odbc_mv, sqlite_mv, jdbc90_mv).

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.