Module: Clickwrap::Vocabulary

Defined in:
lib/clickwrap/vocabulary.rb

Overview

Every stable string Clickwrap writes into evidence lives here, frozen, in one place. Historical receipts are read by code that may be years newer than the code that wrote them, so these values are part of the public compatibility promise: they are added to, never renamed or repurposed.

This taxonomy is product design. It is not a statutory vocabulary, and naming an act agreement or consent does not determine its legal effect.

Constant Summary collapse

KINDS =

The six kinds, each with the lifecycle it actually needs.

%w[
  agreement
  acknowledgment
  consent
  declaration
  attestation
  authorization
].freeze
VERB_FOR_KIND =

The policy DSL verb that declares each kind.

{
  "agreement" => "agree_to",
  "acknowledgment" => "acknowledge",
  "consent" => "consent_to",
  "declaration" => "declare",
  "attestation" => "attest",
  "authorization" => "authorize"
}.freeze
KIND_FOR_VERB =
VERB_FOR_KIND.invert.freeze
INITIAL_ACTION_FOR_KIND =

The action recorded when a statement is first captured.

{
  "agreement" => "agreed",
  "acknowledgment" => "acknowledged",
  "consent" => "granted",
  "declaration" => "declared",
  "attestation" => "attested",
  "authorization" => "authorized"
}.freeze
ACTIONS_FOR_KIND =

Every action a statement of each kind may ever record.

{
  "agreement" => %w[agreed superseded].freeze,
  "acknowledgment" => %w[acknowledged superseded expired].freeze,
  "consent" => %w[granted declined withdrawn renewed scope_changed].freeze,
  "declaration" => %w[declared corrected superseded expired].freeze,
  "attestation" => %w[attested corrected superseded].freeze,
  "authorization" => %w[authorized consumed expired revoked].freeze
}.freeze
ACTIONS =
ACTIONS_FOR_KIND.values.flatten.uniq.freeze
WITHDRAWABLE_KINDS =

Kinds whose meaning includes a withdrawal route. Withdrawing future consent never rewrites a historical agreement or factual declaration, so only consent is withdrawable.

%w[consent].freeze
EXPIRABLE_KINDS =

Kinds that may carry a validity period.

%w[acknowledgment consent declaration authorization].freeze
CORRECTABLE_KINDS =

Kinds that may be corrected by the same actor without implying the original statement was false when it was made.

%w[declaration attestation].freeze
ONE_TIME_KINDS =

Kinds that may be scoped to a single protected action.

%w[authorization].freeze
EVENT_TYPES =

What produced an event. capture is a human action recorded by this application; every other value says plainly that something else happened.

%w[
  capture
  withdrawal
  correction
  supersession
  expiry
  consumption
  revocation
  renewal
  scope_change
  exemption
  imported_legacy
  external_receipt
  disposition
  legal_hold_placed
  legal_hold_released
  receipt_access
  provider_outcome
].freeze
HUMAN_ACTION_EVENT_TYPES =

Event types that record an act by a human through a Clickwrap presentation. These satisfy agreed_to?, consented_to? and the other human-action predicates — as does imported_legacy, which carries what a previous system recorded about a human action (an exemption never does: it records that no human acted).

%w[capture correction renewal scope_change].freeze
ACTOR_RECEIPT_EVENT_TYPES =

What belongs in an actor's own receipts collection: every act they performed here, plus their history imported from a previous system or recorded by an external provider. A migrated user's records screen must show their history, not an empty list that implies they never agreed to anything.

(HUMAN_ACTION_EVENT_TYPES + %w[imported_legacy external_receipt]).freeze
CAPTURE_CHANNELS =

Where a capture came from. This is recorded, never guessed: a missing browser parameter is not evidence of a system actor.

%w[
  web_browser
  native_app
  api_client
  operator
  background_job
  imported_provider
  system
].freeze
STATES =

The current state of one statement for one actor/subject, projected from retained event payloads.

%w[
  active
  declined
  withdrawn
  expired
  superseded
  consumed
  revoked
  corrected
  exempted
].freeze
INACTIVE_STATES =

A statement in one of these states cannot satisfy a requirement.

%w[declined withdrawn expired superseded consumed revoked corrected].freeze
REQUEST_EVIDENCE_STATES =

How a receipt describes each optional request-evidence field. "Blank" is never allowed to blur "we chose not to collect this" into "collection failed" or "we deleted it".

%w[
  not_configured
  unavailable
  recorded
  redacted_for_this_viewer
  deleted_after_retention
  held
].freeze
IP_GEOLOCATION_DATA_FIELDS =

Every IP-geolocation data field a policy can enable individually. latitude_and_longitude is one coupled choice on purpose: half a coordinate is not a result.

%w[
  country
  region
  city
  postal_code
  latitude_and_longitude
  timezone
  continent
  metro_code
  accuracy_radius_in_kilometers
].freeze
IP_GEOLOCATION_PROVENANCE_FIELDS =

Provenance that travels with any stored IP-geolocation result. A policy cannot keep provider-derived coordinates while stripping the uncertainty needed to interpret them.

%w[
  ip_geolocation_provider_name
  ip_geolocation_provider_source
  ip_geolocation_database_version
  ip_geolocation_database_sha256
  ip_geolocation_accuracy_radius_confidence_percentage
  ip_geolocation_was_estimated
  ip_geolocation_source_was_verified_by_host
  ip_geolocation_resolved_at
  ip_geolocation_unavailable_reason
].freeze
ATTRIBUTION_METHODS =

How the actor was attributed to the event. None of these is an identity claim; they say which application-supplied context was recorded.

%w[
  authenticated_session
  account_registration
  public_form
  operator_session
  api_credential
  anonymous_identifier
  system_process
  imported_provider
  unknown
].freeze
VERIFICATION_ERRORS =

Stable machine-readable reasons a verification can fail. Applications branch on these symbols; the human message is localized separately.

%i[
  no_evidence
  wrong_actor
  wrong_tenant
  wrong_subject
  subject_fingerprint_mismatch
  stale_policy_revision
  unseen_document_version
  missing_answer
  declined
  declaration_expired
  acknowledgment_expired
  consent_withdrawn
  superseded
  revoked
  authorization_consumed
  authorization_expired
  predecessor_missing
  wrong_order
  replay_rejected
  presentation_expired
  presentation_invalid
  presentation_actor_mismatch
  presentation_subject_mismatch
  presentation_tenant_mismatch
  presentation_channel_mismatch
  presentation_policy_mismatch
  represented_party_mismatch
  represented_party_authority_mismatch
  represented_party_creation_flow_mismatch
  registration_flow_mismatch
  registration_actor_type_mismatch
  document_digest_mismatch
  integrity_check_failed
  exemption_not_accepted
  request_evidence_unavailable
  core_event_disposed
  unknown_policy
  unknown_statement
].freeze
INTEGRITY_TIERS =

Which assurance tier a verification result was produced under. Each tier states exactly what it detects and nothing more.

%w[
  baseline
  database_hardening
  chained_history
  external_event_anchoring
  third_party_timestamp
].freeze
PROHIBITED_CLAIM_PHRASES =

Public words that would overclaim what any of this proves. The release test greps generated output, receipts, task output, and documentation for these.

[
  "gdpr compliant",
  "gdpr-compliant",
  "legally compliant",
  "compliance guaranteed",
  "court proof",
  "court-proof",
  "tamper proof",
  "tamper-proof",
  "legally binding",
  "guarantees enforceability",
  "audit guaranteed",
  "qualified electronic signature",
  "trusted time",
  "trusted_timestamp",
  "verified identity",
  "legal advice"
].freeze

Class Method Summary collapse

Class Method Details

.action?(value) ⇒ Boolean

Returns:

  • (Boolean)


269
# File 'lib/clickwrap/vocabulary.rb', line 269

def action?(value) = ACTIONS.include?(value.to_s)

.actions_for(kind) ⇒ Object



274
275
276
277
278
# File 'lib/clickwrap/vocabulary.rb', line 274

def actions_for(kind)
  ACTIONS_FOR_KIND.fetch(kind.to_s) do
    raise UnknownStatementError, "#{kind.inspect} is not one of: #{KINDS.join(", ")}"
  end
end

.capture_channel?(value) ⇒ Boolean

Returns:

  • (Boolean)


271
# File 'lib/clickwrap/vocabulary.rb', line 271

def capture_channel?(value) = CAPTURE_CHANNELS.include?(value.to_s)

.correctable?(kind) ⇒ Boolean

Returns:

  • (Boolean)


288
# File 'lib/clickwrap/vocabulary.rb', line 288

def correctable?(kind) = CORRECTABLE_KINDS.include?(kind.to_s)

.event_type?(value) ⇒ Boolean

Returns:

  • (Boolean)


270
# File 'lib/clickwrap/vocabulary.rb', line 270

def event_type?(value) = EVENT_TYPES.include?(value.to_s)

.expirable?(kind) ⇒ Boolean

Returns:

  • (Boolean)


287
# File 'lib/clickwrap/vocabulary.rb', line 287

def expirable?(kind) = EXPIRABLE_KINDS.include?(kind.to_s)

.human_action_event_type?(value) ⇒ Boolean

Returns:

  • (Boolean)


290
# File 'lib/clickwrap/vocabulary.rb', line 290

def human_action_event_type?(value) = HUMAN_ACTION_EVENT_TYPES.include?(value.to_s)

.inactive_state?(value) ⇒ Boolean

Returns:

  • (Boolean)


291
# File 'lib/clickwrap/vocabulary.rb', line 291

def inactive_state?(value) = INACTIVE_STATES.include?(value.to_s)

.initial_action_for(kind) ⇒ Object



280
281
282
283
284
# File 'lib/clickwrap/vocabulary.rb', line 280

def initial_action_for(kind)
  INITIAL_ACTION_FOR_KIND.fetch(kind.to_s) do
    raise UnknownStatementError, "#{kind.inspect} is not one of: #{KINDS.join(", ")}"
  end
end

.kind?(value) ⇒ Boolean

Returns:

  • (Boolean)


268
# File 'lib/clickwrap/vocabulary.rb', line 268

def kind?(value) = KINDS.include?(value.to_s)

.one_time_allowed?(kind) ⇒ Boolean

Returns:

  • (Boolean)


289
# File 'lib/clickwrap/vocabulary.rb', line 289

def one_time_allowed?(kind) = ONE_TIME_KINDS.include?(kind.to_s)

.state?(value) ⇒ Boolean

Returns:

  • (Boolean)


272
# File 'lib/clickwrap/vocabulary.rb', line 272

def state?(value) = STATES.include?(value.to_s)

.withdrawable?(kind) ⇒ Boolean

Returns:

  • (Boolean)


286
# File 'lib/clickwrap/vocabulary.rb', line 286

def withdrawable?(kind) = WITHDRAWABLE_KINDS.include?(kind.to_s)