Dinoer

What Dinoer does not do behind your back

Five guarantees, each with the file that enforces it — and, for the one guarantee that is not absolute, exactly what it does not cover.

You are considering giving a research pipeline access to your credentials and your machine’s outbound traffic. That is a serious decision. Here is what it rests on, with the file that enforces it each time — not our word.

Dinoer never puts your credentials in a terminal

They never pass through your shell, your command history, or Dinoer’s logs.

→ lib/repertoire_chiffre.py — how a credential actually reaches a form →

The same rule holds inside evaluer: a scenario action carrying a plaintext value on a password/secret-looking field is rejected — action_secret_en_clair, checked before the scenario ever reaches Playwright, not audited after the fact.

What Dinoer itself writes is redacted by default. Return values, URLs and error messages that pass through stdout or the operations log are neutralised unless you explicitly ask otherwise (--no-filtre-evaluer, which the JSON output then reports on itself).

→ lib/sanitisation.py

What this does not cover: the agent driving Dinoer has its own access to your machine. If you give it a terminal, it can read your mounted directory like any other file. Dinoer protects the path it controls — not the one you open beside it.

The corpus is what the delegated model is allowed to leave

opencode.jsonc denies websearch/webfetch to the model that writes your report — it exists because a real run on 14 August 2026 caught the opposite: twelve live searches, invisible in the final text, sourcing content the collected corpus never contained. Verified by capturing the model’s full event stream, not by trusting what it returned.

→ opencode.jsonc, lib/modeles.py::invoquer_opencode()

What this does not cover. bash stays allowed — real scenarios need it — and a model denied websearch has, in a verification run, reached the live web through bash curl instead. This is the one guarantee on this page that is not absolute, and it is named as such rather than rounded up to one.

It does not depend on where you launch it. OpenCode reads opencode.jsonc from the directory it is launched in, and the .deb package does not install that file. Since 1.0.1, invoquer_opencode() therefore sets the same denial itself, in OPENCODE_CONFIG_CONTENT, merged with any value you already had. Measured on 25 September 2026 with opencode debug config (OpenCode 1.18.32), launched from /tmp with that value: websearch and webfetch are deny, bash stays allow. Without it, from the same directory, the first two are allow — which is why the value is set on every call rather than left to the directory.

What Dinoer reports, it does not decide

pret_a_agir: false means a friction was perceived — a WAF signature, a session drift, a navigation cap. It does not mean I refuse to run. Dinoer reports what it noticed and hands you the decision.

WAF detection is keyword-based and can be wrong. It is reported as a count, never raised as an exception that halts execution, and --ignorer-waf is there for when you have checked and it was wrong.

The distinction matters more than it looks. A tool that moralises about access becomes a tool you work around, and a tool people work around stops reporting anything at all.

The agent does not decide what it does — with one named exception

Every click, every keystroke, every navigation the retained browser core performs is a line written in a scenario file. That part of Dinoer executes a list; it does not invent one.

→ scenarios/schema.json

The research pipeline is not the same claim. campagne.py delegates real interpretive judgment to a model — whether a page answers an open question, whether two pages describe the same event. That delegation is the point of the pipeline, not a gap in it — but it means this guarantee, read literally, covers the browser core and not the synthesis step above it. Say so plainly rather than let the RPA-era phrasing imply more than it now covers.

You can review everything afterwards

Every run is recorded in a dated, append-only operations log — what was attempted, where, with what outcome, tagged with the intention behind it. What the pipeline did, you can look at — not only the report it hands you.

→ journal.py, /var/log/dinoer/operations.jsonl

What leaves your machine, and by which door

Three things can, and each is your choice: the queries sent to the SearXNG instance you configure, the collected text sent to OpenCode’s model, and a notification sent to a ntfy server (ntfy.sh unless you set another). Your credentials do not. The whole table, with the file behind each line, is on the architecture page; the price of the second is stated in technical choices.

And what Dinoer does not claim

It is no more careful than the scenario or manifest you give it. A badly written one does real damage, at machine speed — and the corpus guarantee above covers where an answer came from, not whether the question was a good one to ask.