Liking cljdoc? Tell your friends :D

vaelii.browser.sandbox

Somewhere safe to be wrong.

A sandbox is a scratch context of one browser session's own, hung below CxWell so it sees what CxWell sees (every shipped context but the opt-in theories, the kb/middle/ files that state no genlCx edge from CxWell) and nothing shipped sees it. A reader can therefore use every type, every relation and every rule the KB ships, and cannot damage any of them: their content is visible only from inside, and one control takes all of it away again.

Why that shape and not a permission system: visibility here is logical, not administrative. genlCx already decides what a context can see, and hanging the sandbox at the bottom of the spindle gives exactly the asymmetry wanted — everything flows in, nothing flows out — with no new concept and nothing to enforce. A shipped rule firing over sandbox facts places its conclusion in the sandbox, because placement is the maximal common descendant of the rule's context and the antecedents' (docs/contexts.md), and the sandbox is the only context below both. So the derived content is inside the thing that gets discarded, without anything arranging for that.

Four facts about the lifecycle:

  • The context is created on the first write, not on the first page. A reader who only looks costs the KB nothing, and a KB full of empty sandboxes would be a KB with a genlCx edge per idle visitor.
  • The server mints the session token and tags it. The cookie carries the token and an HMAC of it under a key fixed at start, and a cookie whose tag does not check is replaced with a fresh one, so a client cannot choose a sandbox. The context name carries a digest of the token rather than the token, because every reader sees every context's name (/find, CxWell's term page, /op :contexts).
  • A process keeps at most max-sandboxes per KB. Opening one more resets the lowest-priority sandbox on the roster below (docs/web.md).
  • Reset is a real teardown, not a flag: every sentex in the extent goes through edit's :remove, and the genlCx edge with them. The edge is not in the extent — genlCx is a forced-decontextualized predicate, so it is stored in CxUniverse — which is why it is fetched by hand rather than swept up with the rest.

Promotion — moving something out of a sandbox into a context that outlives it — is deliberately not here. A sandbox is a dead end, and a dead end that cannot be half-escaped is easier to reason about than one with an entry point in it.

Somewhere safe to be wrong.

A **sandbox** is a scratch context of one browser session's own, hung below
`CxWell` so it sees what CxWell sees (every shipped context but the opt-in theories,
the `kb/middle/` files that state no `genlCx` edge from CxWell) and nothing shipped
sees it.  A
reader can therefore use every type, every relation and every rule the KB ships, and
cannot damage any of them: their content is visible only from inside, and one control
takes all of it away again.

Why that shape and not a permission system: visibility here is *logical*, not
administrative.  `genlCx` already decides what a context can see, and hanging the
sandbox at the bottom of the spindle gives exactly the asymmetry wanted — everything
flows in, nothing flows out — with no new concept and nothing to enforce.  A shipped
rule firing over sandbox facts places its conclusion **in the sandbox**, because
placement is the maximal common descendant of the rule's context and the antecedents'
(docs/contexts.md), and the sandbox is the only context below both.  So the derived
content is inside the thing that gets discarded, without anything arranging for that.

Four facts about the lifecycle:

- **The context is created on the first write, not on the first page.**  A reader who
  only looks costs the KB nothing, and a KB full of empty sandboxes would be a KB with
  a `genlCx` edge per idle visitor.
- **The server mints the session token and tags it.**  The cookie carries the token and
  an HMAC of it under a key fixed at start, and a cookie whose tag does not check is
  replaced with a fresh one, so a client cannot choose a sandbox.  The context name
  carries a digest of the token rather than the token, because every reader sees every
  context's name (`/find`, `CxWell`'s term page, `/op :contexts`).
- **A process keeps at most `max-sandboxes` per KB.**  Opening one more resets the
  lowest-priority sandbox on the roster below (docs/web.md).
- **Reset is a real teardown**, not a flag: every sentex in the extent goes through
  `edit`'s `:remove`, and the `genlCx` edge with them.  The edge is not in the
  extent — `genlCx` is a forced-decontextualized predicate, so it is stored in
  `CxUniverse` — which is why it is fetched by hand rather than swept up with the
  rest.

Promotion — moving something out of a sandbox into a context that outlives it — is
deliberately not here.  A sandbox is a dead end, and a dead end that cannot be
half-escaped is easier to reason about than one with an entry point in it.
raw docstring

(add-cookie resp c)

resp with one more Set-Cookie. Ring takes a header value as a string or as a collection of them, so a second cookie extends the header rather than replacing what is there.

Here rather than in vaelii.browser.web, which is the other caller: that namespace requires this one, so a helper the two share can only live on this side of the edge. The case is a response carrying both cookies the browser has — a reader who sets a reading preference on the same request that mints their session token — where an assoc drops whichever of the two ran first.

`resp` with one more `Set-Cookie`.  Ring takes a header value as a string or as a
collection of them, so a second cookie **extends** the header rather than replacing
what is there.

Here rather than in `vaelii.browser.web`, which is the other caller: that namespace
requires this one, so a helper the two share can only live on this side of the edge.
The case is a response carrying both cookies the browser has — a reader who sets a
reading preference on the same request that mints their session token — where an
`assoc` drops whichever of the two ran first.
sourceraw docstring

context-forclj

(context-for token)

The sandbox context named by token, or nil when the token is not well-formed. CxSandbox<digest> satisfies the context naming invariant (Cx prefix, CapitalCamelCase), so it is an ordinary context in every other respect. The digest is the first 128 bits of the token's SHA-256: the name is listed to every reader, so it must not carry the token a cookie holds.

The sandbox context named by `token`, or nil when the token is not well-formed.
`CxSandbox<digest>` satisfies the context naming invariant (`Cx` prefix,
CapitalCamelCase), so it is an ordinary context in every other respect.  The digest
is the first 128 bits of the token's SHA-256: the name is listed to every reader, so
it must not carry the token a cookie holds.
sourceraw docstring

context-ofclj

(context-of req)

The sandbox context this request belongs to, or nil when it carries no valid token.

The sandbox context this request belongs to, or nil when it carries no valid token.
sourceraw docstring

source

extentclj

(extent target ctx)

Every sentex stored in the sandbox — what the reader put there and what the shipped rules concluded from it, which are in the same place by construction.

Every sentex stored in the sandbox — what the reader put there and what the shipped
rules concluded from it, which are in the same place by construction.
sourceraw docstring

live?clj

(live? target ctx)

Does this sandbox exist in the KB yet? It exists exactly when its edge does; the extent can be empty (everything in it retracted) and the sandbox still be open.

Does this sandbox exist in the KB yet?  It exists exactly when its edge does; the
extent can be empty (everything in it retracted) and the sandbox still be open.
sourceraw docstring

max-sandboxesclj

(max-sandboxes)

How many sandboxes a KB holds at most (VAELII_SANDBOX_MAX).

How many sandboxes a KB holds at most (`VAELII_SANDBOX_MAX`).
sourceraw docstring

max-sentexesclj

How many sentexes one sandbox may store. /assert refuses a form that would take its sandbox past this, with :over-ceiling; the conclusions an admitted form derives may pass it. Only the lines addressed to the sandbox count: a line the form writes into another context counts toward no ceiling.

How many sentexes one sandbox may store.  `/assert` refuses a form that would take its
sandbox past this, with `:over-ceiling`; the conclusions an admitted form derives may
pass it.  Only the lines addressed to the sandbox count: a line the form writes into
another context counts toward no ceiling.
sourceraw docstring

mint-tokenclj

(mint-token)

A fresh session token: 128 bits from SecureRandom, as 32 hex digits, which need no encoding in a cookie or a symbol.

A fresh session token: 128 bits from `SecureRandom`, as 32 hex digits, which need no
encoding in a cookie or a symbol.
sourceraw docstring

note-use!clj

(note-use! target ctx)

Record a request by the session whose sandbox is ctx.

Record a request by the session whose sandbox is `ctx`.
sourceraw docstring

note-write!clj

(note-write! target ctx)

Record a write request by the session whose sandbox is ctx, and its size after.

Record a write request by the session whose sandbox is `ctx`, and its size after.
sourceraw docstring

openclj

(open target ctx)

Make sure ctx exists, and answer it. Idempotent — the edge is find-or-create, so a second call on a live sandbox writes nothing. Opening a sandbox past max-sandboxes resets the lowest-priority one first. Bare, not !: it removes only through reset!.

Make sure `ctx` exists, and answer it.  Idempotent — the edge is find-or-create, so a
second call on a live sandbox writes nothing.  Opening a sandbox past `max-sandboxes`
resets the lowest-priority one first.  Bare, not `!`: it removes only through `reset!`.
sourceraw docstring

reset!clj

(reset! target ctx)

Discard the whole sandbox: every sentex in it, then the edge that made it a context, and its roster entry.

One edit, so it is one settle, and the dependency-directed sweep does the rest — a conclusion derived into the sandbox goes with the premises it rested on, and its justification with it. Retracting the extent wholesale is safe even though the sweep reaches some of it first: a handle already gone is a no-op in :remove.

Answers {:removed-sentexes n :removed-justifications n}. Irreversible, hence the ! — that is the whole point of the control.

Discard the whole sandbox: every sentex in it, then the edge that made it a context,
and its roster entry.

One `edit`, so it is one settle, and the dependency-directed sweep does the rest — a
conclusion derived into the sandbox goes with the premises it rested on, and its
justification with it.  Retracting the extent wholesale is safe even though the sweep
reaches some of it first: a handle already gone is a no-op in `:remove`.

Answers `{:removed-sentexes n :removed-justifications n}`.  Irreversible, hence the
`!` — that is the whole point of the control.
sourceraw docstring

token-ofclj

(token-of req)

This request's session token — the one wrap-session put on it, else the cookie's when its tag checks, else nil.

This request's session token — the one `wrap-session` put on it, else the cookie's
when its tag checks, else nil.
sourceraw docstring

wrap-sessionclj

(wrap-session handler kb-of)

Give every request a session token, minting one into a cookie when the request carries none whose tag checks, and record the use against the KB kb-of answers.

The token alone writes nothing — it names a sandbox that may not exist yet. Only open creates the context, and only a write calls it.

Give every request a session token, minting one into a cookie when the request
carries none whose tag checks, and record the use against the KB `kb-of` answers.

The token alone writes nothing — it names a sandbox that may not exist yet.  Only
`open` creates the context, and only a write calls it.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close