# AGENTS.md — autoloaded by Aider / Cursor / Continue.dev / Claude Code / OpenHands

fulcra-attention is **fully relayless**. The real work lives in the Chrome MV3 extension under `chrome/`: it signs in with an Auth0 device flow and POSTs records **directly to the Fulcra API** (`https://api.fulcradynamics.com/ingest/v1/record/batch`). There is no localhost daemon involvement, no pairing, no per-extension token, and no relay route — the relay-era Python backend (CLI / `ingest.py` / `fulcra.py` / `state.py`) has been retired.

The Python package (`fulcra_attention/`) is now just the Fulcra Collect *pointer* plugin (`collect_plugin.py`): it does no collection and only surfaces an "Attention" entry that tells the user to install the browser extension and sign in via the browser.

Key extension details: records use the `com.fulcra.attention.v3.` source_id namespace, folding the identity slug into the hash for multi-browser distinctness. **The slug and the human label are two different things and are sourced differently per browser — do not conflate them.** Chrome derives both from the identity label its wizard refuses to skip. Safari has no wizard and cannot read the device name (`UIDevice.name` is entitlement-gated since iOS 16 and returns the bare model without it — and the *simulator returns a real-looking name*, so never validate that path on a simulator), so `DeviceIdentity.swift` mints an automatic per-installation slug in the shared App Group and leaves the label nil. Consequence: a `machine:<slug>` tag exists only where a human label does. Anything touching this must preserve injectivity — two distinct installs must never produce one slug; over-counting a device is acceptable, merging two is not, because source_ids cannot be recomputed after the fact. Cross-check `chrome/src/relayless/*` (`oidc.ts`, `signIn.ts`, `relaylessSender.ts`, `ensureDefinition.ts`, `wire.ts`, `config.ts`) and `fulcra_attention/collect_plugin.py` before making claims about the flow.
