Security
What lnk measure reads, keeps and sends, and what it never does.
Never content
- A measure is a number of a measure Link names, of a unit named by an
ID, a kind, its parent's ID and a name: an agent's or machine's name,
or a process's program. There's no field for text. A name or ID is
kept only if it's letters, digits and
._:/@-, at most 64 of them. - A process is named only by a program on Link's list (
lnkand its plugins,bwrap,sandbox-exec,node,bun,deno,python,python3,uv); any other has no name, only its ID. What a system calls a process is what it chose: a script's file name, or anything it set itself, so a name taken from it could carry a conversation's words, or a sandbox's, to wherever measures go. - An agent's and the machine's names are yours, and go with their measures to your endpoint.
- What a harness reports of itself is read as the same schema, and everything else is dropped as it's read: a measure Link doesn't name, a description, an attribute, text where an ID goes. So no message, prompt, file, tool argument or answer reaches what's kept, shown or sent, even from a harness that wrote one there. A harness may report only what it counts itself (a turn's tokens, cost, calls and times); what's measured from outside, it can't say.
- An agent's tokens are counted by its sandbox's proxy, from the
usage each model's answer gives as it passes, at most 4 MiB of a
stream's event and one value of each usage key of a whole answer: six counts a proxy
(requests, those without usage, and input, output, cached and
cache-written tokens), never a word of a prompt or an answer. It reads only the
events that name usage, and a whole answer's top-level
usage, and keeps their numbers; a count past a billion tokens is taken for what isn't so, and counted as an answer without usage. - Link Harness derives its measures from a turn's events, numbers only. A test sends a turn with a known phrase, through a tool call and its answer, and fails if its measures hold any of it; another writes the phrase everywhere a harness could, and fails if anything kept, shown or sent holds it; a third sends the phrase to a model through an agent's proxy and back, and fails if anything counted, kept, shown or sent holds it.
What it reads
- Each agent's processes, as this user, from outside: on Linux
/procand its service's control group, on a Maclibproc. Nothing runs inside an agent's sandbox, and no harness is asked anything. - The agents here, their processes and where their harnesses report,
from
lnk agent list --json --here; what each sandbox's proxy carried, fromlnk sandbox traffic --json(bytes each way, and the tokens of its model's requests, never where to). - The file a harness reports to, in its home, which the harness can write: it's opened without following a link, only if it's a plain file, at most 4 MiB a look, and a line longer than 64 KiB is skipped. A line longer than a look reads is skipped too, to its end however many looks that takes, so it never holds up the lines after it.
What it keeps
~/.config/lnk/measure/, only yours (700, files600): the watcher's looks, a day of them, and a summary of each minute, 30 days; old files deleted whole.counted.jsonthere keeps what each running proxy had counted at the last look, and which agents their proxy counts, so a restarted watcher counts none of it twice. Each agent's processes are shown and sent, not kept, unless your settings keep them (lnk measure settings --processes on).- Your endpoint's headers (an API key) are in
settings.tomlthere, which only you read, and never shown:lnk measure exportsays how many there are. An endpoint's URL can't hold a password (https://user:key@host):lnk measure exportrefuses it and says to use--header. Where a URL is shown, it's without a password or a query, and the watcher's log names only the endpoint's host. lnk uninstall --delete measuresdeletes the folder.
What it sends
- Nothing, until you name an endpoint (
lnk measure export <url>). Then every look goes there as OTLP, with your headers, at most 10 seconds a request;http://sends it in the clear, so usehttps://for an endpoint off this machine. Local Link never receives it.
