5 Use cases (modeled)
UC-FF2B+-01
Verified vs decode-only JWT mode comparison
Request with Authorization: Bearer eyJ…. FF in verified mode requires JWKS + aud=pty-feature-flags · signature verified. FF in decode-only mode parses claims without verify and surfaces warnings.
expected ⇒ verified: allow · warnings=[] · auth_source=jwt ·· decode-only: allow · warnings=['auth_not_verified'] · auth_source=jwt_unverified
UC-FF2B+-02
Tenant override with current backing explanation
PUT /v1/flags/override/tenant/T-pty/ff.example (dev) · 2b+ writes to override JSON · in-memory dict updates · backing_state surfaced in response meta.
expected ⇒ 200 · meta.backing_state='file_backed' · meta.warnings=['dev_mode_only_write_path']
UC-FF2B+-03
User override precedence
Tenant override false + user override true → evaluation returns enabled=true · reason_chain=[user_override, tenant_override, default].
expected ⇒ enabled=true · reason='user_override_precedence' · source='file_backed'
UC-FF2B+-04
Cache invalidation / refresh semantics
2b+: no cache · each evaluate re-reads JSON. 2c (planned): Redis hit → meta.cache='hit' · invalidation broadcast on mutation keeps replicas consistent.
expected ⇒ 2b+ meta.cache='uncached' ·· 2c meta.cache='hit|miss' + invalidation event on channel ptt.ff.invalidate
UC-FF2B+-05
Sensitive flag gated via Admin 2b
Flag with sensitive_flag=true · requires_approval=true · approval_matrix_row=row-sensitive-override. FF consults Admin 2b /api/policy/sensitive.check.2b with approval_ref from JWT. Admin returns ttl_state=valid → allow with approval_ref in meta · ttl_state=expired → deny reason=approval_expired.
expected ⇒ valid: allow · meta.approval_ref='APP-…' · meta.ttl_state='valid' ·· expired: deny · reason='approval_expired' · suggested_action='request_fresh_approval'