Google Cloud Storage Store
lnk-gcs keeps an agent's conversations, their events and their
leases, off the machine as objects in a Google Cloud Storage bucket, so
any machine reading the bucket can take the agent's next turn. It
keeps nothing on the machine, and serves, keeping its connections to
Cloud Storage between calls
(Interface).
Its settings
Its settings are in its environment (Settings::from_env):
LNK_GCS_BUCKET, the bucket its objects are kept in; LNK_GCS_PREFIX,
where its objects go in the bucket, left out conversations;
LNK_GCS_TOKEN or LNK_GCS_TOKEN_FILE, an OAuth token or a file
holding one, read for every call; and LNK_GCS_URL, Cloud Storage's
address, left out https://storage.googleapis.com.
Its objects
An event is <prefix>/<owner>/<agent>/<thread>/events/<seq>, its
number in 20 digits so the names sort as the numbers do, and a lease is
<prefix>/<owner>/<agent>/<thread>/lease, each as JSON.
Their names
Each of owner, agent and thread is escaped: a byte but a letter, a
digit, - or _ is % and its two hex digits. A conversation's name
is read back from one spelling only (its escapes in uppercase hex), so
two objects can't pass for one conversation.
One writer
Each event is written only if it isn't there (ifGenerationMatch=0),
so of two writers of one number, on any machines, Cloud Storage lets
one write it. A lease is replaced only if it's still the one read
(ifGenerationMatch=<its generation>), so of the takers of a lapsed
lease, one takes it.
Its calls
A call Cloud Storage didn't answer, or answered that it couldn't (429, 5xx), is tried 4 times, 200 ms before the second. A request may take 10 seconds, and a call 25 all told, less than its caller waits on it, so it says why it failed rather than being stopped. It reads or removes 8 events at once.
Its token
Its token (LNK_GCS_TOKEN, or the file LNK_GCS_TOKEN_FILE names) is
in the environment of whatever runs it. It sends the token only over
https://, or http:// to this machine alone, never on a command line,
and never logs it.
Who reads it
For Link Harness's calls that's the agent's store bridge, outside the harness's sandbox, which takes each call only as the agent's own, so neither the harness nor what it runs reads the token; memory runs it in memory's sandbox, which does.
What it reaches
The token reaches what Cloud Storage lets it reach, the whole bucket at least, every owner's and agent's prefix in it included: give each agent a bucket, or a token, of its own.
What the bucket answers
What the bucket answers is bounded: an object read is at most an event's most (16 MiB) and 64 KiB more, a listing's page 16 MiB, a listing 10,000 pages, and a call's tries end within 25 seconds, before its caller stops it.
What it doesn't keep
It keeps no jobs. Its tests/contract.rs runs it through
link_store_contract::store::check against a stand-in for Cloud
Storage on the machine, here and behind the store bridge.