Concepts
What gets an automated session detected, and where Weles shows it.
The constructs in a trajectory that let a platform tell a Weles session from a person, the Weles primitive each one is replaced by, and the command that lists every file still showing it.
How to find each one#
Every anti-pattern below is a construct in source, so the files that show it are listed by searching the source revision for it: node tests/inventory.mjs <revision> '<pattern>' <path> in the Weles checkout prints one revision:path:line:text per instance and nothing when none remains. A revision git cannot read, or a pattern git refuses, fails the command with git's reason. The pattern and path for each anti-pattern are in its row.
A listed line is a finding to read, not a verdict: the row names the one case where the construct is the sanctioned use, and every other instance is replaced by the primitive the row names.
The anti-patterns#
| Anti-pattern | Why it is detected | Use instead | List it with |
|---|---|---|---|
A click run as page code: element.click() inside evaluate or an arrow the page runs. | The DOM marks a click dispatched by page script isTrusted: false, and platforms read that flag; nothing precedes it — no pointer path, no hover, no press and release. | humanClickLocator in src/human/mouse.ts, which moves the pointer and clicks through the browser's own input pipeline. jsClick (src/session/wsession/page-actions/js-click.ts) is the one sanctioned page-code click, for a control inside a shadow root the input pipeline cannot reach. | node tests/inventory.mjs HEAD '(evaluate|=>).*\.click\(\)|\)\.click\(\),$|[a-zA-Z]\.click\(\)\)' src/trajectories |
A synthetic input event: new MouseEvent, PointerEvent, KeyboardEvent or TouchEvent dispatched on an element. | Like a page-code click it is untrusted, and no person's browser ever produces one. | The humanized pointer and keyboard in src/human/mouse.ts and src/human/keyboard.ts. | node tests/inventory.mjs HEAD 'new (Mouse|Pointer|Keyboard|Touch)Event\(' src |
A field filled by assigning element.value. | The value appears with no focus, no key presses and no time between characters, which typing-cadence checks measure. | humanType in src/human/keyboard.ts, through the session's fill. A solved captcha token written into the provider's own hidden response field is the sanctioned exception: the provider reads the token there, and no person types it (src/trajectories/_shared/linkedin/checkpoint.mjs). | node tests/inventory.mjs HEAD '\.value ?= ?[^=]' src/trajectories |
A persona sampled inside a trajectory. | An account whose browser, version, screen or locale changes between its registration and its later sessions is a different device to the platform, and the cohort of sessions is distrusted. | The account's stored persona, which resolveAccountSession in src/account/session.ts reads and writes back once for an account that has none. | node tests/inventory.mjs HEAD 'generatePersona\(|sampleDevice\(' src/trajectories |
An exit resolved inside a trajectory for an account. | An account that arrives from an address it was not registered from, or from a new one every run, is linked to every other account seen on those addresses. | The account's pin, which src/account/pinned_proxy.ts rebuilds and refuses to replace (see Proxy quality). The LinkedIn login's rotation (src/trajectories/_shared/linkedin/signup/proxy_rotation.mjs) is the sanctioned use: it resolves fresh exits only for an account without a pin, from the proxy request the run states. | node tests/inventory.mjs HEAD 'resolveProxy\(' src/trajectories |
A fixed pause: waitForTimeout or setTimeout to wait for a page. | The same interval before every action is a machine's rhythm, and it waits either too long or not long enough for the page it is meant for. | pageSettled in src/trajectories/_shared/page/settled.mjs, which waits for the page's own readiness, and the humanized pointer's own motion timing. | node tests/inventory.mjs HEAD 'waitForTimeout\(|setTimeout\(' src/trajectories |