Skip to main content
Glama

bsp

Destructive

The unified bsp() function. Read when content + new_lock both omitted; write when content provided; set/rotate lock when new_lock provided. Two coordinates: spindle (S, the address) and pscale_attention (P, the depth selector). Shape derives from (S, P). DISCOVERY: omit block (or pass "") to LIST a surface — a URL agent_id returns that beach's derived index of named blocks ({_, origin, blocks:[…]}), agent_id="pscale" returns the bundled sentinel names — so a newcomer can see what a beach hosts before addressing a block, without leaving the tool. (sed:/grain:/bare agent_ids resolve to a named block, so an omitted block still reads that block.) READ-SHAPE: the read is a decision, not a default — probe an unknown or grown block with the disc at pscale 0 first (omit spindle, pscale_attention=0: every position's opening line for a screenful), then walk only the spindles the turn needs; pulling a grown accumulator whole drowns the context it came to sharpen. pscale://whetstone 2.8 teaches the balance by descent. Lock semantics: secret = proof of current authority; new_lock = target lock value (the two never overlap). See pscale://whetstone branch 2 for shape derivation, branch 3 for modifiers, branch 4 for storage. Substrate dispatch via agent_id prefix (sed:, grain:, ordinary).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
faceNoCADO access modifier. Validated against sed: collective membership. Advisory in v0.1; enforced in v0.2.
grayNoPrivacy by encryption (client-side at bsp-mcp; a spine-legal ciphertext envelope lands at the beach). On ordinary blocks: opt-in self-encryption (default false) — secret is the key, only the author decrypts. On grain blocks: private by DEFAULT (shared key from both parties' published keypairs; either party reads, outsiders cannot) — pass gray:false to write public. Requires a non-empty spindle: at a leaf the envelope is the entry; at a position holding entries it voices that position and every entry stays, so a gray history pays its zero-slot summaries exactly as an open one does. Degray = read with the key, then write the plaintext back at the same address with gray:false: the line takes the envelope's place, keeping its arrival stamp and anything standing in it, so a keyed reader and an open one read the same line. Grain mode needs both parties to have run pscale_key_publish — each from the ONE secret they then seal and read with (enc_secret, else secret); a grain write sealed under any other secret is refused, since the partner could never open it.
tierNoSMH aperture modifier. Composes with face per the face-tier matrix. Advisory in v0.1; enforced in v0.2.
blockNoBlock name within the agent_id's namespace. For URL agent_id this is whatever the host has named the block — common names per substrate-wide convention include "marks", "lighthouse" (operator-curated navigation when present, per block-conventions:4.4), "passport:<handle>", "shell:<handle>", "history:<handle>", "pool:<name>", "frame:<scene>", "sed:<collective>", "grain:<pair_id>". The host serves whichever named blocks it hosts. **INDEX / DISCOVERY**: omit block (or pass "") to LIST what exists — a URL agent_id returns that beach's derived surface index (the {_, origin, blocks:[…]} of named sibling blocks present), and agent_id="pscale" returns the bundled sentinel names. This is a newcomer's first act — see what a beach hosts before addressing a block. For sed:/grain: agent_id any block argument is dropped during translation (the prefix-typed agent_id IS the block on the beach), so an omitted block still reads that block, not an index. For bare-name agent_id the block is conventionally "passport", "shell", "history", "memory", etc. — translated to "<block>:<handle>" at the default beach.
appendNoAccumulator append — marks / history / pools / grain sides. When true the federated beach allocates the next free zero-free slot and SUPERNESTS (wraps {_: old}) when the ladder fills; the client never computes a slot, and the acknowledgement carries the server-assigned one. Without a spindle this grows the BLOCK at its root, exactly as before. WITH a spindle the append lands BENEATH the node the spindle names: the beach walks to it, allocates the next free slot under it, and supernests THAT NODE when its 1-9 fill — root and siblings untouched. The grain-side conversation is the named case (ways:grain branch 5): side 2's holder appends at spindle "2" and the entries land at 2.1, then 2.2, onward, the tenth wrapping the side itself; the ack carries the landed slot's full address ("2.3"). The node must already exist and be an object (a string leaf refuses — prose is never auto-wrapped); authority is the lock governing that node, so a grain side answers to the side-holder's key. `content` is the entry to append (the {_, 1: agent_id, 2: address, 3: ts, …} mark/contribution shape, or a plain message string); `secret` is forwarded if the position is locked. Omit pscale_attention. Atomic server-side — concurrent appends never race on slot allocation. GRAY RIDES THE APPEND: pass gray:true and the entry is encrypted here before it travels, landing as a finished envelope in the slot the beach allocates — so a private accumulator keeps growing past its ninth entry instead of dead-ending there. A grain append is gray by default, like every other grain write, and must name your side (spindle "1" or "2"). Group accumulators are not supported yet.
secretNoProof of current authority — an EDIT-LATCH, not a login or account password (pscale://open-commons:4). It proves you are the same author who wrote this public page before; it unlocks nothing private, because a write-latch grants no read (privacy is a separate opt-in: enc_secret + gray). Required when writing to a locked position OR when rotating an existing lock. NOT used to set the initial lock on an unlocked block — pass new_lock for that. Forwarded to the federated beach which computes the hash and verifies.
contentNoPayload for writes. Shape MUST match the shape derived from (spindle, pscale_attention). Omit for reads. Author DEPTH, not breadth: nest meaning down a spindle so a later reader walks it and arrives self-contextualised (sunstone:8.5) — design by CONCEPT, which nests, never by CATEGORY, which fans flat. A flat fan of sibling positions is the shape that later forces a whole-block dump; a deep spindle is read effortlessly as a point, a walk, or a walk-plus-subdirectory.
membersNoGroup encryption — the DECLARATIVE full read-list (handles allowed to read; include yourself). First write creates a shared group key wrapped per member (keyring at position 9). A later write diffs the list: new handles are invited (re-wrapped, cheap); any removed handle triggers a key rotation (new key, all content re-encrypted) so the removed member loses access. Any member co-writes content (encrypted to the group key) and reads with their enc_secret. Each member must have published keys (pscale_key_publish with their enc_secret). Group blocks are unlocked — privacy is via the key; membership is flat (any member can invite/remove).
spindleNoAddress path (S). Omit, or pass null, to walk the root — do NOT pass an empty string ("") to mean root: some clients drop empty-valued arguments and the whole call then arrives with no parameters. Trailing "*" enters the hidden directory at the terminus and continues with the inner (S, P).
agent_idYesAddressed namespace — substrate dispatched by form. Three real targets after dispatch: (1) URL ("https://beach.happyseaurchin.com") → that federated beach at <origin>/.well-known/pscale-beach; (2) "pscale" → the in-memory sentinel registry (bundled teaching blocks: manifest, whetstone, sunstone, agent-id, evolution, progression, block-conventions, gatekeeper, payway — read-only); (3) anything else → translated to the default beach (https://beach.happyseaurchin.com) with the agent_id encoded into the block name. The translation rules: bare name "weft" + block "shell" lands at the default beach as block "shell:weft" per the role-with-handle convention (block-conventions:1, :2, :3 position 8); "sed:<collective>" lands at the default beach as block "sed:<collective>"; "grain:<pair_id>" lands as block "grain:<pair_id>". Translation is internal — callers just pass the agent_id form they have. **Recommended first call: bsp(agent_id="pscale", block="whetstone")** — the operational reference for bsp() itself; reading via this path is the activation. Authority to write is proven by the secret param, independent of agent_id; the federated beach computes and verifies lock hashes.
new_lockNoTarget value for the EDIT-LATCH — a wiki-style edit token on a public page you own, not an account credential (pscale://open-commons:4). Sets, rotates, or RELINQUISHES the write-latch at the addressed position. Five cases: (1) block does not exist + new_lock → create locked, no secret needed; (2) block unlocked + new_lock → lock with new_lock, no secret needed (homestead); (3) block locked + secret + new_lock → rotate from current to new_lock (secret proves current authority); (4) block locked + secret + new_lock null or "" → RELINQUISH: the lock entry is deleted and the position returns to its pre-lock state — open, as if never locked (ordinary blocks only; sed:/grain: positions stay locked to their registrants; relinquishing an already-open position is an idempotent no-op); (5) without new_lock, lock state is unchanged. Forwarded to the federated beach.
enc_secretNoEncryption key — your privacy identity, SEPARATE from `secret` (write-authority). Derives your keypair and encrypts/decrypts gray content (self + grain). NEVER sent to the beach. Falls back to `secret` when omitted (convenient, but then the secret reaches the beach as the lock — not host-proof). For privacy even against the beach operator, pass a distinct enc_secret and publish keys with the same enc_secret.
pscale_attentionNoDepth selector (P) — the aperture dial. Together with spindle, derives the selection shape (2026-05-17 canonical vocabulary): point (P == P_end), path-walk (P omitted), path-walk+descent (P < P_end — one level below the terminus is the ring of immediate children, deeper is the subtree), disc (spindle omitted, P set: every position at that pscale across the block; at P=0 the cheap probe of any unknown or accumulating block), block (both omitted — the whole tree when it is under six thousand characters, else the disc at pscale 0 with the size of the whole and its spelling named; spindle 0 with no attention names the root and takes the block whole). Set it truly: starve neither the turn nor drown it (pscale://whetstone 2.8).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / pscale_attention / description
      Previous value: -"Depth selector (P) — the aperture dial. Together with spindle, derives the selection shape (2026-05-17 canonical vocabulary): point (P == P_end), path-walk (P omitted), path-walk+descent (P < P_end — one level below the terminus is the ring of immediate children, deeper is the subtree), disc (spindle omitted, P set: every position at that pscale across the block; at P=0 the cheap probe of any unknown or accumulating block), block (both omitted — the whole tree, right only when every position is in play). Set it truly: starve neither the turn nor drown it (pscale://whetstone 2.8)."New value: +"Depth selector (P) — the aperture dial. Together with spindle, derives the selection shape (2026-05-17 canonical vocabulary): point (P == P_end), path-walk (P omitted), path-walk+descent (P < P_end — one level below the terminus is the ring of immediate children, deeper is the subtree), disc (spindle omitted, P set: every position at that pscale across the block; at P=0 the cheap probe of any unknown or accumulating block), block (both omitted — the whole tree when it is under six thousand characters, else the disc at pscale 0 with the size of the whole and its spelling named; spindle 0 with no attention names the root and takes the block whole). Set it truly: starve neither the turn nor drown it (pscale://whetstone 2.8)."
  2. Changed1 schema field changed
    • changedInput schema / properties / gray / description
      Previous value: -"Privacy by encryption (client-side at bsp-mcp; a spine-legal ciphertext envelope lands at the beach). On ordinary blocks: opt-in self-encryption (default false) — secret is the key, only the author decrypts. On grain blocks: private by DEFAULT (shared key from both parties' published keypairs; either party reads, outsiders cannot) — pass gray:false to write public. Requires a non-empty spindle: at a leaf the envelope is the entry; at a position holding entries it voices that position and every entry stays, so a gray history pays its zero-slot summaries exactly as an open one does. Degray = read with the key, then write the plaintext back at the same address with gray:false: the line takes the envelope's place, keeping its arrival stamp and anything standing in it, so a keyed reader and an open one read the same line. Grain mode needs both parties to have run pscale_key_publish."New value: +"Privacy by encryption (client-side at bsp-mcp; a spine-legal ciphertext envelope lands at the beach). On ordinary blocks: opt-in self-encryption (default false) — secret is the key, only the author decrypts. On grain blocks: private by DEFAULT (shared key from both parties' published keypairs; either party reads, outsiders cannot) — pass gray:false to write public. Requires a non-empty spindle: at a leaf the envelope is the entry; at a position holding entries it voices that position and every entry stays, so a gray history pays its zero-slot summaries exactly as an open one does. Degray = read with the key, then write the plaintext back at the same address with gray:false: the line takes the envelope's place, keeping its arrival stamp and anything standing in it, so a keyed reader and an open one read the same line. Grain mode needs both parties to have run pscale_key_publish — each from the ONE secret they then seal and read with (enc_secret, else secret); a grain write sealed under any other secret is refused, since the partner could never open it."
  3. Changed1 schema field changed
    • changedInput schema / properties / gray / description
      Previous value: -"Privacy by encryption (client-side at bsp-mcp; a spine-legal ciphertext envelope lands at the beach). On ordinary blocks: opt-in self-encryption (default false) — secret is the key, only the author decrypts. On grain blocks: private by DEFAULT (shared key from both parties' published keypairs; either party reads, outsiders cannot) — pass gray:false to write public. Requires a non-empty spindle: at a leaf the envelope is the entry; at a position holding entries it voices that position and every entry stays, so a gray history pays its zero-slot summaries exactly as an open one does. Degray = read with secret, then write the plaintext back with gray:false. Grain mode needs both parties to have run pscale_key_publish."New value: +"Privacy by encryption (client-side at bsp-mcp; a spine-legal ciphertext envelope lands at the beach). On ordinary blocks: opt-in self-encryption (default false) — secret is the key, only the author decrypts. On grain blocks: private by DEFAULT (shared key from both parties' published keypairs; either party reads, outsiders cannot) — pass gray:false to write public. Requires a non-empty spindle: at a leaf the envelope is the entry; at a position holding entries it voices that position and every entry stays, so a gray history pays its zero-slot summaries exactly as an open one does. Degray = read with the key, then write the plaintext back at the same address with gray:false: the line takes the envelope's place, keeping its arrival stamp and anything standing in it, so a keyed reader and an open one read the same line. Grain mode needs both parties to have run pscale_key_publish."
  4. Changed1 schema field changed
    • changedInput schema / properties / gray / description
      Previous value: -"Privacy by encryption (client-side at bsp-mcp; a spine-legal ciphertext envelope lands at the beach). On ordinary blocks: opt-in self-encryption (default false) — secret is the key, only the author decrypts. On grain blocks: private by DEFAULT (shared key from both parties' published keypairs; either party reads, outsiders cannot) — pass gray:false to write public. Requires a non-empty spindle (encrypt at a leaf). Degray = read with secret, then write the plaintext back with gray:false. Grain mode needs both parties to have run pscale_key_publish."New value: +"Privacy by encryption (client-side at bsp-mcp; a spine-legal ciphertext envelope lands at the beach). On ordinary blocks: opt-in self-encryption (default false) — secret is the key, only the author decrypts. On grain blocks: private by DEFAULT (shared key from both parties' published keypairs; either party reads, outsiders cannot) — pass gray:false to write public. Requires a non-empty spindle: at a leaf the envelope is the entry; at a position holding entries it voices that position and every entry stays, so a gray history pays its zero-slot summaries exactly as an open one does. Degray = read with secret, then write the plaintext back with gray:false. Grain mode needs both parties to have run pscale_key_publish."
  5. Changed1 schema field changed
    • changedInput schema / properties / append / description
      Previous value: -"Accumulator append — marks / history / pools / grain sides. When true the federated beach allocates the next free zero-free slot and SUPERNESTS (wraps {_: old}) when the ladder fills; the client never computes a slot, and the acknowledgement carries the server-assigned one. Without a spindle this grows the BLOCK at its root, exactly as before. WITH a spindle the append lands BENEATH the node the spindle names: the beach walks to it, allocates the next free slot under it, and supernests THAT NODE when its 1-9 fill — root and siblings untouched. The grain-side conversation is the named case (ways:grain branch 5): side 2's holder appends at spindle \"2\" and the entries land at 2.1, then 2.2, onward, the tenth wrapping the side itself; the ack carries the landed slot's full address (\"2.3\"). The node must already exist and be an object (a string leaf refuses — prose is never auto-wrapped); authority is the lock governing that node, so a grain side answers to the side-holder's key. `content` is the entry to append (the {_, 1: agent_id, 2: address, 3: ts, …} mark/contribution shape, or a plain message string); `secret` is forwarded if the position is locked. Omit pscale_attention. Atomic server-side — concurrent appends never race on slot allocation. Not compatible with gray/group (those encrypt at a leaf and need a spindle)."New value: +"Accumulator append — marks / history / pools / grain sides. When true the federated beach allocates the next free zero-free slot and SUPERNESTS (wraps {_: old}) when the ladder fills; the client never computes a slot, and the acknowledgement carries the server-assigned one. Without a spindle this grows the BLOCK at its root, exactly as before. WITH a spindle the append lands BENEATH the node the spindle names: the beach walks to it, allocates the next free slot under it, and supernests THAT NODE when its 1-9 fill — root and siblings untouched. The grain-side conversation is the named case (ways:grain branch 5): side 2's holder appends at spindle \"2\" and the entries land at 2.1, then 2.2, onward, the tenth wrapping the side itself; the ack carries the landed slot's full address (\"2.3\"). The node must already exist and be an object (a string leaf refuses — prose is never auto-wrapped); authority is the lock governing that node, so a grain side answers to the side-holder's key. `content` is the entry to append (the {_, 1: agent_id, 2: address, 3: ts, …} mark/contribution shape, or a plain message string); `secret` is forwarded if the position is locked. Omit pscale_attention. Atomic server-side — concurrent appends never race on slot allocation. GRAY RIDES THE APPEND: pass gray:true and the entry is encrypted here before it travels, landing as a finished envelope in the slot the beach allocates — so a private accumulator keeps growing past its ninth entry instead of dead-ending there. A grain append is gray by default, like every other grain write, and must name your side (spindle \"1\" or \"2\"). Group accumulators are not supported yet."
  6. Changed1 schema field changed
    • changedInput schema / properties / append / description
      Previous value: -"Accumulator append — marks / history / pools. When true the federated beach allocates the next free zero-free slot and SUPERNESTS (wraps {_: old}, raising the floor) when the floor fills; the client does NOT compute a spindle, and the acknowledgement carries the server-assigned slot. `content` is the entry to append (the {_, 1: agent_id, 2: address, 3: ts, …} mark/contribution shape); `secret` is forwarded if the accumulator is locked. Omit spindle and pscale_attention. Atomic server-side — concurrent appends never race on slot allocation. Not compatible with gray/group (those encrypt at a leaf and need a spindle)."New value: +"Accumulator append — marks / history / pools / grain sides. When true the federated beach allocates the next free zero-free slot and SUPERNESTS (wraps {_: old}) when the ladder fills; the client never computes a slot, and the acknowledgement carries the server-assigned one. Without a spindle this grows the BLOCK at its root, exactly as before. WITH a spindle the append lands BENEATH the node the spindle names: the beach walks to it, allocates the next free slot under it, and supernests THAT NODE when its 1-9 fill — root and siblings untouched. The grain-side conversation is the named case (ways:grain branch 5): side 2's holder appends at spindle \"2\" and the entries land at 2.1, then 2.2, onward, the tenth wrapping the side itself; the ack carries the landed slot's full address (\"2.3\"). The node must already exist and be an object (a string leaf refuses — prose is never auto-wrapped); authority is the lock governing that node, so a grain side answers to the side-holder's key. `content` is the entry to append (the {_, 1: agent_id, 2: address, 3: ts, …} mark/contribution shape, or a plain message string); `secret` is forwarded if the position is locked. Omit pscale_attention. Atomic server-side — concurrent appends never race on slot allocation. Not compatible with gray/group (those encrypt at a leaf and need a spindle)."
  7. Changed1 schema field changed
    • changedInput schema / properties / pscale_attention / description
      Previous value: -"Depth selector (P). Together with spindle, derives selection shape — point (P==P_end), ring (P==P_end-1), subtree (P<P_end-1), disc (spindle omitted/null), whole-block (both omitted/null)."New value: +"Depth selector (P) — the aperture dial. Together with spindle, derives the selection shape (2026-05-17 canonical vocabulary): point (P == P_end), path-walk (P omitted), path-walk+descent (P < P_end — one level below the terminus is the ring of immediate children, deeper is the subtree), disc (spindle omitted, P set: every position at that pscale across the block; at P=0 the cheap probe of any unknown or accumulating block), block (both omitted — the whole tree, right only when every position is in play). Set it truly: starve neither the turn nor drown it (pscale://whetstone 2.8)."
  8. Changed1 schema field changed
    • changedInput schema / properties / content / description
      Previous value: -"Payload for writes. Shape MUST match the shape derived from (spindle, pscale_attention). Omit for reads."New value: +"Payload for writes. Shape MUST match the shape derived from (spindle, pscale_attention). Omit for reads. Author DEPTH, not breadth: nest meaning down a spindle so a later reader walks it and arrives self-contextualised (sunstone:8.5) — design by CONCEPT, which nests, never by CATEGORY, which fans flat. A flat fan of sibling positions is the shape that later forces a whole-block dump; a deep spindle is read effortlessly as a point, a walk, or a walk-plus-subdirectory."
  9. Changed2 schema fields changed
    • changedInput schema / properties / new_lock / description
      Previous value: -"Target lock value. Sets, rotates, or RELINQUISHES the write-lock at the addressed position. Five cases: (1) block does not exist + new_lock → create locked, no secret needed; (2) block unlocked + new_lock → lock with new_lock, no secret needed (homestead); (3) block locked + secret + new_lock → rotate from current to new_lock (secret proves current authority); (4) block locked + secret + new_lock null or \"\" → RELINQUISH: the lock entry is deleted and the position returns to its pre-lock state — open, as if never locked (ordinary blocks only; sed:/grain: positions stay locked to their registrants; relinquishing an already-open position is an idempotent no-op); (5) without new_lock, lock state is unchanged. Forwarded to the federated beach."New value: +"Target value for the EDIT-LATCH — a wiki-style edit token on a public page you own, not an account credential (pscale://open-commons:4). Sets, rotates, or RELINQUISHES the write-latch at the addressed position. Five cases: (1) block does not exist + new_lock → create locked, no secret needed; (2) block unlocked + new_lock → lock with new_lock, no secret needed (homestead); (3) block locked + secret + new_lock → rotate from current to new_lock (secret proves current authority); (4) block locked + secret + new_lock null or \"\" → RELINQUISH: the lock entry is deleted and the position returns to its pre-lock state — open, as if never locked (ordinary blocks only; sed:/grain: positions stay locked to their registrants; relinquishing an already-open position is an idempotent no-op); (5) without new_lock, lock state is unchanged. Forwarded to the federated beach."
    • changedInput schema / properties / secret / description
      Previous value: -"Proof of current authority. Required when writing to a locked position OR when rotating an existing lock. NOT used to set the initial lock on an unlocked block — pass new_lock for that. Forwarded to the federated beach which computes the hash and verifies."New value: +"Proof of current authority — an EDIT-LATCH, not a login or account password (pscale://open-commons:4). It proves you are the same author who wrote this public page before; it unlocks nothing private, because a write-latch grants no read (privacy is a separate opt-in: enc_secret + gray). Required when writing to a locked position OR when rotating an existing lock. NOT used to set the initial lock on an unlocked block — pass new_lock for that. Forwarded to the federated beach which computes the hash and verifies."
  10. Changed2 schema fields changed
    • changedInput schema / properties / new_lock / description
      Previous value: -"Target lock value. Sets or rotates the write-lock at the addressed position. Four cases: (1) block does not exist + new_lock → create locked, no secret needed; (2) block unlocked + new_lock → lock with new_lock, no secret needed; (3) block locked + secret + new_lock → rotate from current to new_lock (secret proves current authority); (4) without new_lock, lock state is unchanged. Forwarded to the federated beach."New value: +"Target lock value. Sets, rotates, or RELINQUISHES the write-lock at the addressed position. Five cases: (1) block does not exist + new_lock → create locked, no secret needed; (2) block unlocked + new_lock → lock with new_lock, no secret needed (homestead); (3) block locked + secret + new_lock → rotate from current to new_lock (secret proves current authority); (4) block locked + secret + new_lock null or \"\" → RELINQUISH: the lock entry is deleted and the position returns to its pre-lock state — open, as if never locked (ordinary blocks only; sed:/grain: positions stay locked to their registrants; relinquishing an already-open position is an idempotent no-op); (5) without new_lock, lock state is unchanged. Forwarded to the federated beach."
    • changedInput schema / properties / new_lock / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
  11. Changed2 schema fields changed
    • changedInput schema / properties / block / description
      Previous value: -"Block name within the agent_id's namespace. For URL agent_id this is whatever the host has named the block — common names per substrate-wide convention include \"marks\", \"lighthouse\" (operator-curated navigation when present, per block-conventions:4.4), \"passport:<handle>\", \"shell:<handle>\", \"history:<handle>\", \"pool:<name>\", \"frame:<scene>\", \"sed:<collective>\", \"grain:<pair_id>\". The host serves whichever named blocks it hosts. For sed:/grain: agent_id any block argument is dropped during translation (the prefix-typed agent_id IS the block on the beach). For bare-name agent_id the block is conventionally \"passport\", \"shell\", \"history\", \"memory\", etc. — translated to \"<block>:<handle>\" at the default beach."New value: +"Block name within the agent_id's namespace. For URL agent_id this is whatever the host has named the block — common names per substrate-wide convention include \"marks\", \"lighthouse\" (operator-curated navigation when present, per block-conventions:4.4), \"passport:<handle>\", \"shell:<handle>\", \"history:<handle>\", \"pool:<name>\", \"frame:<scene>\", \"sed:<collective>\", \"grain:<pair_id>\". The host serves whichever named blocks it hosts. **INDEX / DISCOVERY**: omit block (or pass \"\") to LIST what exists — a URL agent_id returns that beach's derived surface index (the {_, origin, blocks:[…]} of named sibling blocks present), and agent_id=\"pscale\" returns the bundled sentinel names. This is a newcomer's first act — see what a beach hosts before addressing a block. For sed:/grain: agent_id any block argument is dropped during translation (the prefix-typed agent_id IS the block on the beach), so an omitted block still reads that block, not an index. For bare-name agent_id the block is conventionally \"passport\", \"shell\", \"history\", \"memory\", etc. — translated to \"<block>:<handle>\" at the default beach."
    • changedInput schema / required
      Previous value: -[
      -  "agent_id",
      -  "block"
      -]New value: +[
      +  "agent_id"
      +]
  12. First observed

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations declare openWorldHint=true, destructiveHint=true, and idempotentHint=false. The description adds substantial behavioral context beyond that: lock authority semantics, secret versus new_lock, gray encryption, append atomicity, group key rotation, relinquish deletion, and substrate dispatch. Nothing contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is front-loaded and clearly states the modes. However, the description is extremely long and dense, with teaching-block references and design philosophy that may not be necessary for tool selection or invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a 13-parameter unified read/write/lock tool, sparse annotations, and no output schema, the description is complete enough. It covers modes, discovery, locking, encryption, append behavior, and substrate dispatch, so an agent has the context needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 13 parameters in detail. The top-level description mostly restates those parameter meanings and adds mode-selection conditions, but it does not substantially extend parameter semantics beyond the structured schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the unified bsp() function's three modes (read, write, set/rotate lock) and names the two coordinates, spindle and pscale_attention. It is specific about what the tool does, but it does not distinguish itself from sibling pscale_* tools such as pscale_genus or pscale_grain_reach.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear mode-selection rules: read when content and new_lock are omitted, write when content is provided, and lock when new_lock is provided. It also gives discovery and read-shape guidance (omit block to list, probe with pscale 0 first). However, it does not explicitly route the agent to alternative sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.