Skip to content

Latest commit

 

History

History
29 lines (20 loc) · 6.69 KB

AGENTS.md

File metadata and controls

29 lines (20 loc) · 6.69 KB

AGENTS.md

This file provides guidance to AI Agents (like OpenAI's Codex, Cursor Agent, Claude Code, etc) when working with code in this repository.

The public README.md is the short, house-style introduction to the gem. The full north-star product contract — the exhaustive description of every capability, claim, and boundary that README.md used to be — now lives in docs/north-star-readme.md; read it before designing or changing any public behavior, and keep it updated when public behavior changes. The guides/ directory has the detailed integration guides. The product research corpus lives in docs/, which is deliberately git-ignored; read it if it is present locally, and never publish it.

This gem is part of a coherent ecosystem (railsfast, sessions, chats, moderate, organizations, pricing_plans, usage_credits, wallets, api_keys). Match the ecosystem conventions exactly: a single Clickwrap.configure do |config| … end block, has_*/verb-style class macros, adapter objects + no-op-default hook procs, string class names constantized lazily, adaptive install migrations, Minitest with a test/dummy app, SimpleCov, and the README/docs voice.

What makes this gem different to work on

Clickwrap's value is evidence that is still true and still verifiable years after it was written. That makes a few ordinary habits actively dangerous here:

  1. Never overclaim in a public string. No public name, comment, error message, receipt field, task output, generated file, or documentation line may say or imply: compliant, GDPR compliant, enforceable, legally binding, court-proof, tamper-proof, audit approved, trusted time, qualified electronic signature, verified identity, physical location (for IP geolocation), that a person read or understood something, or anything that reads as legal advice. The gem provides evidence mechanics; the host application and its counsel own the legal text, lawful basis, substantive validity, capacity, authority, and retention periods.
  2. Distinguish source classes. In documentation, keep law, court decisions, regulator guidance, technical standards, vendor claims, pinned source-code observations, and product-design inferences visibly separate. Add an exact, direct URL for every external factual or legal claim, and pin source-code citations to immutable commits rather than moving branches.
  3. Released evidence formats are permanent. Every released receipt schema, canonicalization profile, digest field, event action, and lifecycle meaning gets a golden fixture, and new versions must keep verifying old receipts. A format change means a new explicit schema and verifier, never a silent reinterpretation. Do not edit a released migration underneath an installed application; add an upgrade migration.
  4. Required writes cannot be error-isolated. Evidence and the protected database action commit together or not at all. Optional after-commit hooks, analytics, and notifications are isolated and can never undo a committed action or stand in for one.
  5. The browser is not a policy author. Policy key, revision, document versions, validity, subject binding, retention, and request-evidence fields are resolved server-side and rechecked at submit. Never add a hidden field, parameter, or header that lets a client choose any of them.
  6. The host's privacy policy owns the why; the gem records the what, honestly. Clickwrap is nobody's nanny. Its job is evidence mechanics, not gatekeeping collection: it never refuses to record something because a developer did not write a sentence justifying it. Every record_* flag still ships false, and the gem's own default is still record-nothing — but turning collection on is frictionless in every form. config.record_request_evidence_by_default = true records the coarse trio (IP address, browser user agent, country/region/city). record_ip_address, record_browser_user_agent, and record_ip_geolocation all take zero keyword arguments in a policy. Purposes, legal_basis_reference:, DPIA references, deletion clocks, trusted_proxy_configuration_digest, and the because: on keep_recorded_*_indefinitely! and deliberately_store_request_evidence_unencrypted! are ALL optional; gem-supplied honest defaults (Vocabulary::DEFAULT_REQUEST_EVIDENCE_PURPOSE and friends) fill every purpose field so no record ever carries a blank, and the privacy inventory marks each one gem_default or host so the gem's sentence never passes for a reviewed one. What survives, and is not negotiable: never add a switch whose NAME hides what it collects (gdpr_compliant_mode, full_evidence, maximum_evidence, legal_proof); never overclaim (rule 1); never blur not_configured / unavailable / recorded / deleted_after_retention; encryption stays on by default and = false still requires the named deliberately_store_request_evidence_unencrypted! call; scaffolding text (TODO) a host actually supplied is still rejected rather than recorded as a purpose; and a deletion clock declared alongside a keep-indefinitely for the same category is still refused as a contradiction. Owner directive, 2026-08-20 (v0.3.0), deliberately reversing the previous "every field needs a written purpose and a retention decision or boot fails" rule: the ceremony was pushing integrators to collect nothing, and no evidence is worse than un-reviewed evidence. Do not "fix" this back.
  7. Names read aloud. Complete verb-and-noun names, positive booleans, destructive methods that say exactly what they delete, ip_address not ip, browser_user_agent not ua, ip_geolocation not location, http_request not context, recorded_at_by_server not signed_at. If an example does not make sense read aloud by a developer who has never seen the gem, the name is wrong.

Working here

  • Run bundle exec rake test before claiming anything works, and bundle exec rubocop before committing.
  • Add tests in the same change. Fault injection, concurrency, replay, stale-token, disposition, and golden-receipt tests are load-bearing, not extras.
  • Prefer explaining a refusal in a full sentence over raising a terse error. The policy compiler's job is to tell a developer what is wrong and what to do about it.
  • Do not add a runtime dependency. Every integration is an optional adapter with a working no-op default.
  • Do not publish, push, or create anything outside this repository without the owner asking for it.

Release-candidate record: the independent audit findings are resolved in the implementation and tracked in docs/reviews/2026-08-15-production-release-checklist.md. The remaining remote-CI, downstream proof, unfamiliar-developer, legal/privacy, and publication gates are recorded there; do not collapse them into a generic “production ready” claim.