{
  "schemaVersion": "1.0",
  "item": {
    "slug": "identity-resolver",
    "name": "Identity Resolver",
    "source": "tencent",
    "type": "skill",
    "category": "通讯协作",
    "sourceUrl": "https://clawhub.ai/bowen31337/identity-resolver",
    "canonicalUrl": "https://clawhub.ai/bowen31337/identity-resolver",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/identity-resolver",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=identity-resolver",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md",
      "package.json",
      "pyproject.toml",
      "scripts/identity.py",
      "scripts/identity_cli.py"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/identity-resolver"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/identity-resolver",
    "agentPageUrl": "https://openagent3.xyz/skills/identity-resolver/agent",
    "manifestUrl": "https://openagent3.xyz/skills/identity-resolver/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/identity-resolver/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "identity-resolver",
        "body": "Canonical user identity resolution across messaging channels"
      },
      {
        "title": "Description",
        "body": "Resolves multi-channel user identities (Telegram, WhatsApp, Discord, web, etc.) to canonical user IDs, preventing state fragmentation when users interact via multiple channels.\n\nProblem it solves: Without identity resolution, a user messaging via Telegram and WhatsApp appears as two different users, causing fragmented memory, access control, and per-user state across skills.\n\nSolution: Maps all channel identities to one canonical user ID automatically."
      },
      {
        "title": "Installation",
        "body": "Prerequisites: Install uv if not already installed:\n\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\nInstall the skill:\n\ncd /path/to/openclaw/workspace\n\n# Via ClawHub (recommended)\nclawhub install identity-resolver\n\n# Or via Git\ngit clone https://github.com/clawinfra/identity-resolver skills/identity-resolver"
      },
      {
        "title": "For End Users",
        "body": "# Initialize identity map (auto-detects owner from USER.md)\ncd /path/to/workspace\nuv run python skills/identity-resolver/scripts/identity_cli.py init\n\n# Verify your identity\nuv run python skills/identity-resolver/scripts/identity_cli.py resolve \\\n  --channel telegram --user-id YOUR_TELEGRAM_ID\n# Output: your-canonical-id\n\n# List all registered identities\nuv run python skills/identity-resolver/scripts/identity_cli.py list"
      },
      {
        "title": "For Skill Developers",
        "body": "Add to your skill's Python code:\n\nimport sys\nfrom pathlib import Path\n\n# Import identity resolver\nsys.path.insert(0, str(Path.cwd() / \"skills\" / \"identity-resolver\" / \"scripts\"))\nfrom identity import resolve_canonical_id\n\n# Get canonical user ID from session context\nimport os\nchannel = os.getenv(\"OPENCLAW_CHANNEL\")  # e.g., \"telegram\"\nuser_id = os.getenv(\"OPENCLAW_USER_ID\")   # e.g., \"123456789\"\n\ncanonical_id = resolve_canonical_id(channel, user_id)\n# Use canonical_id for all user-specific operations\n\n# Example: User-specific memory file\nmemory_file = f\"data/users/{canonical_id}/memory.json\""
      },
      {
        "title": "Features",
        "body": "✅ Auto-registers owner from workspace USER.md\n✅ Thread-safe identity map storage with fcntl locking\n✅ CLI + Python API for both users and developers\n✅ Path traversal protection — sanitizes all canonical IDs\n✅ Zero dependencies — pure Python stdlib\n✅ Multi-channel support — Telegram, WhatsApp, Discord, web, and future channels"
      },
      {
        "title": "Multi-User Memory Systems",
        "body": "# tiered-memory skill integration\ncanonical_id = resolve_canonical_id(channel, user_id)\nmemory_tree = f\"memory/users/{canonical_id}/tree.json\""
      },
      {
        "title": "Access Control",
        "body": "# agent-access-control skill integration\ncanonical_id = resolve_canonical_id(channel, user_id)\nif is_owner(canonical_id):\n    # Full access\nelse:\n    # Limited access"
      },
      {
        "title": "Cross-Platform User Tracking",
        "body": "# Same user across Discord + Telegram\ndiscord_id = resolve_canonical_id(\"discord\", \"user#1234\")\ntelegram_id = resolve_canonical_id(\"telegram\", \"987654321\")\n# Both resolve to same canonical ID if registered"
      },
      {
        "title": "Core Functions",
        "body": "resolve_canonical_id(channel, provider_user_id, workspace=None, owner_numbers=None) -> str\n\nResolve channel identity to canonical user ID.\n\nAuto-registers owner numbers from USER.md\nReturns canonical ID (e.g., \"alice\") or \"stranger:{channel}:{user_id}\" for unmapped users\n\nadd_channel(canonical_id, channel, provider_user_id, workspace=None, display_name=None)\n\nAdd channel mapping to a canonical user (creates user if doesn't exist).\n\nremove_channel(canonical_id, channel, provider_user_id, workspace=None)\n\nRemove channel mapping from canonical user.\n\nlist_identities(workspace=None) -> dict\n\nReturn all identity mappings.\n\nget_channels(canonical_id, workspace=None) -> list\n\nGet all channels for a canonical user.\n\nis_owner(canonical_id, workspace=None) -> bool\n\nCheck if canonical ID is the owner."
      },
      {
        "title": "CLI Commands",
        "body": "# Initialize\nidentity init [--force]\n\n# Resolve (auto-detect from env or explicit params)\nidentity resolve [--channel CH] [--user-id ID]\n\n# Add mapping\nidentity add --canonical ID --channel CH --user-id ID [--display-name NAME]\n\n# Remove mapping\nidentity remove --canonical ID --channel CH --user-id ID\n\n# List all\nidentity list [--json]\n\n# Get channels\nidentity channels --canonical ID [--json]\n\n# Check owner\nidentity is-owner --canonical ID [--json]"
      },
      {
        "title": "Identity Map Format",
        "body": "Location: data/identity-map.json or memory/identity-map.json\n\n{\n  \"version\": \"1.0\",\n  \"identities\": {\n{\n  \"version\": \"1.0\",\n  \"identities\": {\n    \"alice\": {\n      \"canonical_id\": \"alice\",\n      \"is_owner\": true,\n      \"display_name\": \"Alice Johnson\",\n      \"channels\": [\n        \"telegram:123456789\",\n        \"whatsapp:+1234567890\",\n        \"whatsapp:+9876543210\",\n        \"whatsapp:+5555555555\"\n      ],\n      \"created_at\": \"2026-01-15T10:00:00Z\",\n      \"updated_at\": \"2026-01-15T10:05:00Z\"\n    },\n    \"bob\": {\n      \"canonical_id\": \"bob\",\n      \"is_owner\": false,\n      \"display_name\": \"Bob Smith\",\n      \"channels\": [\n        \"discord:bob#1234\",\n        \"telegram:987654321\"\n      ],\n      \"created_at\": \"2026-01-15T10:10:00Z\",\n      \"updated_at\": \"2026-01-15T10:10:00Z\"\n    }\n  }\n}\n    }\n  }\n}"
      },
      {
        "title": "Security",
        "body": "Path traversal protection: Canonical IDs sanitized to [a-z0-9-_] only\nThread-safe operations: fcntl file locking on all reads/writes\nInput validation: All user inputs validated and sanitized\nOwner auto-registration: Only numbers from USER.md auto-register as owner"
      },
      {
        "title": "Integration Examples",
        "body": "See docs/TIERED_MEMORY_INTEGRATION_EXAMPLE.md for complete working example."
      },
      {
        "title": "License",
        "body": "MIT - See LICENSE file"
      },
      {
        "title": "Author",
        "body": "OpenClaw Agent agent@openclaw.local"
      },
      {
        "title": "Links",
        "body": "GitHub: https://github.com/clawinfra/identity-resolver\nIssues: https://github.com/clawinfra/identity-resolver/issues\nClawHub: https://clawhub.com/skills/identity-resolver"
      }
    ],
    "body": "identity-resolver\n\nCanonical user identity resolution across messaging channels\n\nDescription\n\nResolves multi-channel user identities (Telegram, WhatsApp, Discord, web, etc.) to canonical user IDs, preventing state fragmentation when users interact via multiple channels.\n\nProblem it solves: Without identity resolution, a user messaging via Telegram and WhatsApp appears as two different users, causing fragmented memory, access control, and per-user state across skills.\n\nSolution: Maps all channel identities to one canonical user ID automatically.\n\nInstallation\n\nPrerequisites: Install uv if not already installed:\n\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n\nInstall the skill:\n\ncd /path/to/openclaw/workspace\n\n# Via ClawHub (recommended)\nclawhub install identity-resolver\n\n# Or via Git\ngit clone https://github.com/clawinfra/identity-resolver skills/identity-resolver\n\nQuick Start\nFor End Users\n# Initialize identity map (auto-detects owner from USER.md)\ncd /path/to/workspace\nuv run python skills/identity-resolver/scripts/identity_cli.py init\n\n# Verify your identity\nuv run python skills/identity-resolver/scripts/identity_cli.py resolve \\\n  --channel telegram --user-id YOUR_TELEGRAM_ID\n# Output: your-canonical-id\n\n# List all registered identities\nuv run python skills/identity-resolver/scripts/identity_cli.py list\n\nFor Skill Developers\n\nAdd to your skill's Python code:\n\nimport sys\nfrom pathlib import Path\n\n# Import identity resolver\nsys.path.insert(0, str(Path.cwd() / \"skills\" / \"identity-resolver\" / \"scripts\"))\nfrom identity import resolve_canonical_id\n\n# Get canonical user ID from session context\nimport os\nchannel = os.getenv(\"OPENCLAW_CHANNEL\")  # e.g., \"telegram\"\nuser_id = os.getenv(\"OPENCLAW_USER_ID\")   # e.g., \"123456789\"\n\ncanonical_id = resolve_canonical_id(channel, user_id)\n# Use canonical_id for all user-specific operations\n\n# Example: User-specific memory file\nmemory_file = f\"data/users/{canonical_id}/memory.json\"\n\nFeatures\n\n✅ Auto-registers owner from workspace USER.md\n✅ Thread-safe identity map storage with fcntl locking\n✅ CLI + Python API for both users and developers\n✅ Path traversal protection — sanitizes all canonical IDs\n✅ Zero dependencies — pure Python stdlib\n✅ Multi-channel support — Telegram, WhatsApp, Discord, web, and future channels\n\nUse Cases\nMulti-User Memory Systems\n# tiered-memory skill integration\ncanonical_id = resolve_canonical_id(channel, user_id)\nmemory_tree = f\"memory/users/{canonical_id}/tree.json\"\n\nAccess Control\n# agent-access-control skill integration\ncanonical_id = resolve_canonical_id(channel, user_id)\nif is_owner(canonical_id):\n    # Full access\nelse:\n    # Limited access\n\nCross-Platform User Tracking\n# Same user across Discord + Telegram\ndiscord_id = resolve_canonical_id(\"discord\", \"user#1234\")\ntelegram_id = resolve_canonical_id(\"telegram\", \"987654321\")\n# Both resolve to same canonical ID if registered\n\nAPI Reference\nCore Functions\n\nresolve_canonical_id(channel, provider_user_id, workspace=None, owner_numbers=None) -> str\n\nResolve channel identity to canonical user ID.\n\nAuto-registers owner numbers from USER.md\nReturns canonical ID (e.g., \"alice\") or \"stranger:{channel}:{user_id}\" for unmapped users\n\nadd_channel(canonical_id, channel, provider_user_id, workspace=None, display_name=None)\n\nAdd channel mapping to a canonical user (creates user if doesn't exist).\n\nremove_channel(canonical_id, channel, provider_user_id, workspace=None)\n\nRemove channel mapping from canonical user.\n\nlist_identities(workspace=None) -> dict\n\nReturn all identity mappings.\n\nget_channels(canonical_id, workspace=None) -> list\n\nGet all channels for a canonical user.\n\nis_owner(canonical_id, workspace=None) -> bool\n\nCheck if canonical ID is the owner.\n\nCLI Commands\n# Initialize\nidentity init [--force]\n\n# Resolve (auto-detect from env or explicit params)\nidentity resolve [--channel CH] [--user-id ID]\n\n# Add mapping\nidentity add --canonical ID --channel CH --user-id ID [--display-name NAME]\n\n# Remove mapping\nidentity remove --canonical ID --channel CH --user-id ID\n\n# List all\nidentity list [--json]\n\n# Get channels\nidentity channels --canonical ID [--json]\n\n# Check owner\nidentity is-owner --canonical ID [--json]\n\nIdentity Map Format\n\nLocation: data/identity-map.json or memory/identity-map.json\n\n{\n  \"version\": \"1.0\",\n  \"identities\": {\n{\n  \"version\": \"1.0\",\n  \"identities\": {\n    \"alice\": {\n      \"canonical_id\": \"alice\",\n      \"is_owner\": true,\n      \"display_name\": \"Alice Johnson\",\n      \"channels\": [\n        \"telegram:123456789\",\n        \"whatsapp:+1234567890\",\n        \"whatsapp:+9876543210\",\n        \"whatsapp:+5555555555\"\n      ],\n      \"created_at\": \"2026-01-15T10:00:00Z\",\n      \"updated_at\": \"2026-01-15T10:05:00Z\"\n    },\n    \"bob\": {\n      \"canonical_id\": \"bob\",\n      \"is_owner\": false,\n      \"display_name\": \"Bob Smith\",\n      \"channels\": [\n        \"discord:bob#1234\",\n        \"telegram:987654321\"\n      ],\n      \"created_at\": \"2026-01-15T10:10:00Z\",\n      \"updated_at\": \"2026-01-15T10:10:00Z\"\n    }\n  }\n}\n    }\n  }\n}\n\nSecurity\nPath traversal protection: Canonical IDs sanitized to [a-z0-9-_] only\nThread-safe operations: fcntl file locking on all reads/writes\nInput validation: All user inputs validated and sanitized\nOwner auto-registration: Only numbers from USER.md auto-register as owner\nIntegration Examples\n\nSee docs/TIERED_MEMORY_INTEGRATION_EXAMPLE.md for complete working example.\n\nLicense\n\nMIT - See LICENSE file\n\nAuthor\n\nOpenClaw Agent agent@openclaw.local\n\nLinks\nGitHub: https://github.com/clawinfra/identity-resolver\nIssues: https://github.com/clawinfra/identity-resolver/issues\nClawHub: https://clawhub.com/skills/identity-resolver"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/bowen31337/identity-resolver",
    "publisherUrl": "https://clawhub.ai/bowen31337/identity-resolver",
    "owner": "bowen31337",
    "version": "1.0.6",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/identity-resolver",
    "downloadUrl": "https://openagent3.xyz/downloads/identity-resolver",
    "agentUrl": "https://openagent3.xyz/skills/identity-resolver/agent",
    "manifestUrl": "https://openagent3.xyz/skills/identity-resolver/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/identity-resolver/agent.md"
  }
}