unbroker

Autonomously remove your info from data-broker sites.

  • privacy
  • data-broker
  • opt-out
  • ccpa
  • gdpr
  • security
  • doxxing

Declared platforms: linux · macos · windows

Install
npx skills add 'https://github.com/NousResearch/hermes-agent/tree/main/optional-skills/security/unbroker'
Download bundle ↓
main · 24fd22bScanned 2026-09-15

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗

scripts/legal.py

scripts/legal.pyBrowse 56 files
View on GitHub
← Back to SKILL.md
"""Render opt-out / legal request text from templates/ with safe substitution. Templates use {field} placeholders. Missing fields are left literal (never crash,never inject blanks that look like real data). Field values come from theleast-disclosure selection in dossier.select_disclosure."""from __future__ import annotations from pathlib import Path import paths  class _SafeDict(dict):    def __missing__(self, key):  # leave unknown placeholders untouched        return "{" + key + "}"  def template_path(name: str) -> Path:    return paths.templates_dir() / name  def render(template_name: str, fields: dict) -> str:    text = template_path(template_name).read_text(encoding="utf-8")    return text.format_map(_SafeDict(fields))  def _join_listings(value) -> str:    if isinstance(value, (list, tuple)):        return "\n".join(str(v) for v in value)    return str(value or "")  def _join_identifiers(value) -> str:    """Render the subject's OWN identifiers as a bullet list for an indirect-exposure request."""    if isinstance(value, (list, tuple)):        return "\n".join(f"  - {v}" for v in value if v)    return f"  - {value}" if value else ""  def render_optout_email(broker: dict, fields: dict) -> str:    ctx = dict(fields)    ctx.setdefault("broker_name", broker.get("name", "the data broker"))    ctx["listing_urls"] = _join_listings(fields.get("listing_urls"))    ctx.setdefault("full_name", fields.get("full_name", "[your name]"))    ctx.setdefault("contact_email", fields.get("contact_email", "[your email]"))    return render("emails/generic-optout.txt", ctx)  def render_request(kind: str, broker: dict, fields: dict) -> str:    """kind: generic | ccpa | ccpa_agent | ccpa_indirect | gdpr"""    template = {        "generic": "emails/generic-optout.txt",        "ccpa": "emails/ccpa-deletion.txt",        "ccpa_agent": "emails/ccpa-authorized-agent.txt",        "ccpa_indirect": "emails/ccpa-indirect-deletion.txt",        "gdpr": "emails/gdpr-erasure.txt",    }.get(kind, "emails/generic-optout.txt")    ctx = dict(fields)    ctx.setdefault("broker_name", broker.get("name", "the data broker"))    ctx["listing_urls"] = _join_listings(fields.get("listing_urls"))    ctx["my_identifiers"] = _join_identifiers(fields.get("my_identifiers"))    return render(template, ctx)