Settings
Settings
Sign in to a private stack, tune the breakers every agent call is judged against, and give your projects names only this browser knows.
Connection the API this page talks to Not read yet
Every value on this page came from GET /policy/config, not from a default written into the page.
Sign in
Reading the public demo needs nothing. Saving, and reading a private stack, need the operator.
Sign in, rather than paste a key
On the machine that holds the operator key, in the folder where you ran connect, run python threefold.py open. It opens the dashboard already signed in, through a link that works once and only for a short while. This browser then holds a sign-in session that expires, never the key, and every page here uses it for reads and saves.
Fallback: an operator key for this browser
For a machine without threefold.py. A sign-in replaces it: signing in removes a key stored here, and while this browser is signed in the session is sent instead.
Kept in this browser's localStorage under threefold-operator-key and sent as X-API-Key on the requests the dashboard, rules, sessions and settings pages make to the API. It is not shown again after you store it. A key typed into a page's own field is used before this one.
Any script these pages load can read what is stored here, and that includes the Tailwind bundle every page loads from cdn.tailwindcss.com and the Swagger UI bundle the API page loads from unpkg.com. Both are pinned to an exact version, and Swagger UI is checked against a hash, but a third party still serves them. Store the key only on a machine you trust, and clear it when you are done.
The stored key is sent only to the host that served this page. Point the API address under Connection at another host and it is held back, so only a key you type there goes to it.
Breakers
What stops a call, or a whole session, before it runs. All four reach the gates.
Saving needs the operator. On the public demo, reading does not.
A saved policy is written to DynamoDB and adopted by every container that starts afterwards, so an anonymous write would change the thresholds this product leads with for everyone who came after it. The public demo keeps reads open, because a reader has to be able to see what is enforced; a stack deployed with private reads needs the key for those too. Sign in with python threefold.py open, as above; the key, typed into the key field under Connection or stored in this browser, is the fallback. A deployment that has configured no key refuses writes outright and says so.
The service rebuilds the whole policy from each POST, so this form always submits all four numbers and the secret shapes together. Sending one field on its own would reset the others to their defaults.
The bounds on this form are enforced in the browser. The API accepts any parseable number and answers 400 only when a value cannot be parsed at all, so a policy written with curl is not checked the way this form checks it.
Secret shapes
Saved with the numbers above, by the same Save policy button.
blocked_patterns is the policy's own list of secret shapes, one regular expression per line. A call whose arguments match one is refused as a credential is: always, never staged. The service refuses the whole save when an entry does not compile, and allows at most fifty entries of two hundred characters each.
Where a saved policy lives
A saved policy is written to DynamoDB under CONFIG#policy, read back when a cold Lambda container starts, and re-read by warm containers every thirty seconds, so a change made here outlives the container that accepted it and reaches the others within half a minute. If that write fails, the service keeps the value in process memory only and the next container starts on the previous policy.
The service's last answer
Nothing sent yet.
Your own names for these projects
The service knows each project only by its alias, so that is what every page, every link and every request uses. Give an alias a name of your own here and every page shows it beside the alias, quieter.
Nothing here is sent anywhere.
Save writes to this browser's localStorage under threefold-local-names and does nothing else. No request this page or any other makes carries one of these names: not in a URL, not in a query string, not in a body and not in a header. The service is never told them, so they cannot reach the ledger, a screenshot of a public page, or anyone else.
A browser's storage belongs to that browser on that machine. These names do not follow you to another browser, another machine or a private window, and clearing this site's data deletes them. Keep the copy that matters in a file of your own: Copy as JSON hands you exactly that.
Any script this page loads can read what is stored here, as it can the operator key. That includes the Tailwind bundle from cdn.tailwindcss.com. Name what you would not mind a script on this page reading.
Loading the projects this stack knows…
A JSON object of alias to name, for a mapping you keep in a file. It is applied over the fields above when you press Save, so it can name an alias that has no field yet. A name is one line of at most 60 characters; anything that is not text is left out and the count below says how many were.
The switch in the navigation above turns every name off at once, for a screenshot or a demo, and remembers that in this browser too. It appears as soon as one name is saved. Building the mapping from the checkouts on your own machine: python threefold.py status --names-json prints a JSON object of alias to folder name, ready to paste above.
What these numbers change, and what they do not
All four numbers reach the gates
Saving sets the loop detector's repetition threshold from monomorphic_repetition_threshold, its cycle search length from loop_history_window, and the breaker's single-call cap and session ceiling from max_single_call_usd and max_session_budget_usd. Raise the threshold to 5 and the first scenario on the demo no longer halts on the third call: that is the quickest proof this page reaches the evaluator the gate uses. The caps are weighed against caller-declared token counts, so a caller that declares zero tokens is not stopped by them.
The patterns refuse like secrets
Every blocked_patterns entry is an additional secret shape: a call whose arguments match one is refused with the compiled shapes' force, which means always enforced and never staged. The list above is editable, one regular expression per line; the service refuses the whole save when an entry does not compile.