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
consentis 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.
captureis 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 doesimported_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_longitudeis 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
- COARSE_IP_GEOLOCATION_DATA_FIELDS =
The three coarse fields
config.record_request_evidence_by_default = trueturns on. Coarse means administrative area, not a point: a country, a region, and a city are what a provider can estimate from an address with any confidence at all. Everything finer — a postal code, coordinates, a timezone, a metro code — stays its own separately named decision, because a switch that reads "record request evidence" should not hand somebody coordinates they never asked for. %w[country region city].freeze
- DEFAULT_REQUEST_EVIDENCE_PURPOSE =
The purpose Clickwrap records when a host enables request evidence without writing a purpose of their own. It is the gem's own sentence, not a reviewed host decision, and the privacy inventory says which of the two it is looking at. It exists because the alternative — refusing to boot until somebody writes a sentence — was pushing integrators to record nothing at all, and no corroboration is worse evidence than corroboration collected under the gem's stated purpose.
"Corroborate who performed each recorded act, from where, on what client — to defend " \ "the recorded agreement itself."
- DEFAULT_REASON_FOR_KEEPING_REQUEST_EVIDENCE_INDEFINITELY =
The reason recorded when a host keeps request evidence indefinitely without writing their own. Same posture as the purpose above: the declaration is still recorded and still readable years later; only the obligation to phrase it yourself is gone.
"Corroboration lives as long as the evidence it corroborates"- DEFAULT_REASON_FOR_STORING_REQUEST_EVIDENCE_UNENCRYPTED =
The reason recorded when a host turns off encryption for request evidence without writing their own. Calling the method is still the ceremony —
deliberately_store_request_evidence_unencrypted!is a sentence a reviewer finds in a diff and cannot misread — but the gem no longer demands the sentence be phrased twice. "The application deliberately stores request evidence unencrypted; the reason lives " \ "outside Clickwrap"
- 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
- .action?(value) ⇒ Boolean
- .actions_for(kind) ⇒ Object
- .capture_channel?(value) ⇒ Boolean
- .correctable?(kind) ⇒ Boolean
- .event_type?(value) ⇒ Boolean
- .expirable?(kind) ⇒ Boolean
- .human_action_event_type?(value) ⇒ Boolean
- .inactive_state?(value) ⇒ Boolean
- .initial_action_for(kind) ⇒ Object
- .kind?(value) ⇒ Boolean
- .one_time_allowed?(kind) ⇒ Boolean
- .state?(value) ⇒ Boolean
- .withdrawable?(kind) ⇒ Boolean
Class Method Details
.action?(value) ⇒ Boolean
305 |
# File 'lib/clickwrap/vocabulary.rb', line 305 def action?(value) = ACTIONS.include?(value.to_s) |
.actions_for(kind) ⇒ Object
310 311 312 313 314 |
# File 'lib/clickwrap/vocabulary.rb', line 310 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
307 |
# File 'lib/clickwrap/vocabulary.rb', line 307 def capture_channel?(value) = CAPTURE_CHANNELS.include?(value.to_s) |
.correctable?(kind) ⇒ Boolean
324 |
# File 'lib/clickwrap/vocabulary.rb', line 324 def correctable?(kind) = CORRECTABLE_KINDS.include?(kind.to_s) |
.event_type?(value) ⇒ Boolean
306 |
# File 'lib/clickwrap/vocabulary.rb', line 306 def event_type?(value) = EVENT_TYPES.include?(value.to_s) |
.expirable?(kind) ⇒ Boolean
323 |
# File 'lib/clickwrap/vocabulary.rb', line 323 def expirable?(kind) = EXPIRABLE_KINDS.include?(kind.to_s) |
.human_action_event_type?(value) ⇒ Boolean
326 |
# File 'lib/clickwrap/vocabulary.rb', line 326 def human_action_event_type?(value) = HUMAN_ACTION_EVENT_TYPES.include?(value.to_s) |
.inactive_state?(value) ⇒ Boolean
327 |
# File 'lib/clickwrap/vocabulary.rb', line 327 def inactive_state?(value) = INACTIVE_STATES.include?(value.to_s) |
.initial_action_for(kind) ⇒ Object
316 317 318 319 320 |
# File 'lib/clickwrap/vocabulary.rb', line 316 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
304 |
# File 'lib/clickwrap/vocabulary.rb', line 304 def kind?(value) = KINDS.include?(value.to_s) |
.one_time_allowed?(kind) ⇒ Boolean
325 |
# File 'lib/clickwrap/vocabulary.rb', line 325 def one_time_allowed?(kind) = ONE_TIME_KINDS.include?(kind.to_s) |
.state?(value) ⇒ Boolean
308 |
# File 'lib/clickwrap/vocabulary.rb', line 308 def state?(value) = STATES.include?(value.to_s) |
.withdrawable?(kind) ⇒ Boolean
322 |
# File 'lib/clickwrap/vocabulary.rb', line 322 def withdrawable?(kind) = WITHDRAWABLE_KINDS.include?(kind.to_s) |