{
  "feature": "private-contact-discovery",
  "version": "1.0.0",
  "description": "Issue short-lived HMAC-derived credentials that authenticate clients with an external privacy-preserving contact discovery service without exposing plaintext contact lists to the server",
  "category": "auth",
  "tags": [
    "privacy",
    "contacts",
    "discovery",
    "phone-number",
    "credentials",
    "psi"
  ],
  "fields": [
    {
      "name": "account_identifier",
      "type": "token",
      "required": true,
      "label": "Account Identifier"
    },
    {
      "name": "discovery_username",
      "type": "token",
      "required": false,
      "label": "Discovery Username"
    },
    {
      "name": "discovery_password",
      "type": "token",
      "required": false,
      "label": "Discovery Password"
    },
    {
      "name": "token_expiry_seconds",
      "type": "number",
      "required": false,
      "label": "Token TTL (seconds)"
    }
  ],
  "rules": {
    "authentication": {
      "require_active_session": true
    },
    "credential_derivation": {
      "algorithm": "HMAC",
      "user_derivation_key": true,
      "prepend_username": false,
      "expiry_controlled_by": "server",
      "default_ttl_seconds": 86400
    },
    "privacy": {
      "plaintext_numbers_never_reach_server": true,
      "contact_list_not_stored": true
    },
    "rate_limiting": {
      "scope": "per_account"
    }
  },
  "outcomes": {
    "credentials_issued": {
      "priority": 10,
      "given": [
        {
          "field": "account_identifier",
          "source": "session",
          "operator": "exists",
          "description": "Caller holds a valid authenticated session"
        }
      ],
      "then": [
        {
          "action": "create_record",
          "type": "discovery_credentials",
          "target": "credentials",
          "description": "Generate a time-limited HMAC credential pair bound to the account identifier"
        },
        {
          "action": "emit_event",
          "event": "contact_discovery.credentials_issued",
          "payload": [
            "account_identifier",
            "token_expiry_seconds"
          ]
        }
      ],
      "result": "Returns a JSON object with username and password credentials valid for the external contact discovery service"
    },
    "unauthenticated": {
      "priority": 1,
      "error": "CONTACT_DISCOVERY_UNAUTHENTICATED",
      "given": [
        {
          "field": "account_identifier",
          "source": "session",
          "operator": "not_exists",
          "description": "No valid session present"
        }
      ],
      "then": [],
      "result": "Request rejected with 401 Unauthorized"
    },
    "rate_limited": {
      "priority": 2,
      "error": "CONTACT_DISCOVERY_RATE_LIMITED",
      "given": [
        "per-account credential issuance rate limit is exhausted"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "contact_discovery.rate_limited",
          "payload": [
            "account_identifier"
          ]
        }
      ],
      "result": "Request rejected with 429 Too Many Requests and Retry-After header"
    }
  },
  "errors": [
    {
      "code": "CONTACT_DISCOVERY_UNAUTHENTICATED",
      "status": 401,
      "message": "Authentication required to access contact discovery.",
      "retry": false
    },
    {
      "code": "CONTACT_DISCOVERY_RATE_LIMITED",
      "status": 429,
      "message": "Too many contact discovery requests. Please wait before trying again.",
      "retry": true
    }
  ],
  "events": [
    {
      "name": "contact_discovery.credentials_issued",
      "description": "Short-lived contact discovery credentials were successfully generated for an account",
      "payload": [
        "account_identifier",
        "token_expiry_seconds"
      ]
    },
    {
      "name": "contact_discovery.rate_limited",
      "description": "A contact discovery credential request was rejected due to rate limiting",
      "payload": [
        "account_identifier"
      ]
    }
  ],
  "related": [
    {
      "feature": "login",
      "type": "required",
      "reason": "User must hold a valid authenticated session before requesting discovery credentials"
    },
    {
      "feature": "rate-limiting-abuse-prevention",
      "type": "required",
      "reason": "Credential issuance endpoints are protected by leaky-bucket rate limiting"
    },
    {
      "feature": "e2e-key-exchange",
      "type": "recommended",
      "reason": "Contact discovery is typically combined with key exchange to bootstrap end-to-end encrypted conversations"
    },
    {
      "feature": "identity-lookup",
      "type": "optional",
      "reason": "Identity lookup may consume contact discovery results to resolve account identifiers"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_private_contact_discovery",
        "description": "Issue short-lived HMAC-derived credentials that authenticate clients with an external privacy-preserving contact discovery service without exposing plaintext contact lists to the server",
        "success_metrics": [
          {
            "metric": "unauthorized_access_rate",
            "target": "0%",
            "measurement": "Failed authorization attempts that succeed"
          },
          {
            "metric": "response_time_p95",
            "target": "< 500ms",
            "measurement": "95th percentile response time"
          }
        ],
        "constraints": [
          {
            "type": "security",
            "description": "Follow OWASP security recommendations",
            "negotiable": false
          },
          {
            "type": "security",
            "description": "Sensitive fields must be encrypted at rest and never logged in plaintext",
            "negotiable": false
          }
        ]
      }
    ],
    "autonomy": {
      "level": "supervised",
      "human_checkpoints": [
        "before modifying sensitive data fields"
      ],
      "escalation_triggers": [
        "error_rate > 5",
        "consecutive_failures > 3"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "credentials_issued",
          "permission": "autonomous"
        },
        {
          "action": "unauthenticated",
          "permission": "autonomous"
        },
        {
          "action": "rate_limited",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "security",
        "over": "performance",
        "reason": "authentication must prioritize preventing unauthorized access"
      }
    ],
    "verification": {
      "invariants": [
        "sensitive fields are never logged in plaintext",
        "all data access is authenticated and authorized",
        "error messages never expose internal system details"
      ]
    },
    "coordination": {
      "protocol": "request_response",
      "consumes": [
        {
          "capability": "login",
          "from": "login",
          "fallback": "fail"
        },
        {
          "capability": "rate_limiting_abuse_prevention",
          "from": "rate-limiting-abuse-prevention",
          "fallback": "fail"
        }
      ]
    }
  }
}