• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
c15r

c15r

sync

Agent collaboration layer https://sync.parc.land
Public
Like
1
sync
Home
Code
41
.claude
2
.claude-plugin
2
docs
13
frontend
14
mcp
13
reference
10
scripts
11
skills
1
static
1
.gitignore
.mcp.json
.vtignore
CLAUDE.md
INSTALL.md
PLUGIN.md
README.md
actions.ts
agents.ts
audit.ts
auth.ts
cel.ts
context.ts
deno.json
deps.ts
docs.ts
help-content.ts
invoke.ts
H
main.ts
meta.ts
poll-v8.ts
replay.ts
rooms.ts
sampling.ts
schema-v7.ts
schema-v8.ts
schema.ts
timers.ts
tokens.ts
utils.ts
views.ts
wait.ts
Connections
Environment variables
2
Branches
8
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
Viewing readonly version of v9 branch: v47
View latest version
README.md
name:
sync
description:
Coordination substrate for multi-agent systems. Two operations — read context, invoke actions. No direct state writes. Every entry is { value, _meta } — the substrate reasons about its own observation. Agents declare vocabulary, then act through it. Unified auth via passkey-minted scoped tokens. Built on wrapped state, CEL expressions with domain helpers, and salience-driven context shaping. Base URL is https://sync.parc.land/.

sync v9

Coordination substrate for multi-agent systems at https://sync.parc.land/.

Two operations: read context, invoke actions. Everything else is wiring.

There is no _set_state. Agents declare write capabilities as actions, then invoke them. The declaration is the commitment. The vocabulary is the protocol.

What's new in v9

Every entry is wrapped: { value, _meta }. The substrate observes itself.

  • value — the stored data (or null if elided by salience)
  • _meta — provenance, trajectory, salience: revision, updated_at, writer, via, seq, score, velocity, writers, first_at, elided
  • Actions carry extra _meta: invocations, last_invoked_at, last_invoked_by, contested

CEL expressions access .value for data, ._meta for metadata. Domain helpers like salient(), elided(), written_by(), focus() make the wrapped shape ergonomic.

Context is shaped by salience: high-score entries get full values and metadata, low-score entries are elided (value: null, with expand hints). Override with elision: "none".


Authentication

Passkeys are the root of trust. Everything else is a scoped token minted by a passkey-authenticated user.

Quick start (CLI / scripts)

# 1. Initiate device auth curl -s -X POST https://sync.parc.land/auth/device \ -H "Content-Type: application/json" \ -d '{"scope":"rooms:* create_rooms"}' # → { device_code, user_code, verification_uri_complete } # 2. Open the URL in browser, authenticate with passkey, approve scope # 3. Poll for token curl -s -X POST https://sync.parc.land/auth/device/token \ -H "Content-Type: application/json" \ -d '{"device_code":"dev_xxx"}' # → { access_token: "tok_xxx", refresh_token: "ref_xxx", scope, expires_in }

Quick start (MCP clients)

MCP clients (Claude, ChatGPT, etc.) use OAuth 2.1 with PKCE + WebAuthn passkeys. The flow is automatic — the client handles DCR, authorization, and token exchange. After auth, use sync_lobby to see your rooms and sync_embody to start acting.

Token model

One token concept. Scope is the only knob.

ScopeMeaning
rooms:*All rooms the user has access to
rooms:*:readAll rooms, read-only
rooms:my-roomFull access to a specific room
rooms:my-room:writeRead + write
rooms:my-room:readRead-only (shareable dashboard link)
rooms:my-room:agent:aliceBound to agent alice (implies write)
create_roomsCan create new rooms

Effective access = min(token.scope, user_rooms.role). A token can only narrow, never widen.

Token operations

POST   /tokens              Mint a scoped token
GET    /tokens              List your tokens
PATCH  /tokens/:id          Update scope (bounded by your access)
DELETE /tokens/:id           Revoke a token
POST   /tokens/refresh      Exchange refresh_token for new access_token

Scope elevation (agent-initiated)

When an agent hits scope_denied, the response includes a stateless elevation URL. The agent presents the URL to the user. The user opens it → passkey auth → choose access level → approve. The server patches the token's scope. The agent retries.

Legacy tokens

Legacy room_, view_, as_ prefix tokens continue to work for backward compatibility.


Core workflow

Step 1: Create a room

curl -X POST https://sync.parc.land/rooms \ -H "Authorization: Bearer tok_xxx" \ -H "Content-Type: application/json" \ -d '{"id":"my-room"}'

Step 2: Embody an agent

Via MCP: sync_embody({ room: "my-room", name: "Alice" }).

Or via HTTP:

curl -X POST https://sync.parc.land/rooms/my-room/agents \ -H "Content-Type: application/json" \ -d '{"id":"alice","name":"Alice","role":"agent"}'

Step 3: Read context

curl -H "Authorization: Bearer tok_xxx" \ https://sync.parc.land/rooms/my-room/context

Returns wrapped entries. Example state entry:

{ "phase": { "value": "executing", "_meta": { "revision": 3, "writer": "architect", "score": 0.85, "velocity": 0.1, "elided": false } } }

The _shaping summary tells you how context was shaped. In an empty room, help({ key: "vocabulary_bootstrap" }) guides the first move.

Step 4: Bootstrap vocabulary

POST /rooms/my-room/actions/help/invoke
{ "params": { "key": "standard_library" } }
POST /rooms/my-room/actions/_register_action/invoke
{ "params": {
    "id": "submit_result",
    "description": "Submit a result keyed to your identity",
    "params": { "result": { "type": "any" } },
    "writes": [{ "scope": "_shared", "key": "${self}.result", "value": "${params.result}" }]
}}

Step 5: Invoke actions

POST /rooms/my-room/actions/submit_result/invoke
Authorization: Bearer tok_xxx
{ "params": { "result": "42" } }
→ {
    "invoked": true,
    "writes": [{
      "scope": "_shared",
      "key": "alice.result",
      "value": "42",
      "_meta": { "revision": 1, "writer": "alice", "score": 0.7, "velocity": 1.0 }
    }]
  }

The invoke response includes _meta on every written key — the agent sees the structural consequences of its action.

Step 6: Wait for conditions

GET /rooms/my-room/wait?condition=views.results.value.size()>0
→ { "triggered": true, "context": { ... } }

Note: v9 CEL expressions use .value to access entry data.


Built-in actions

ActionDescriptionKey params
_register_actionDeclare a write capabilityid, description, params, writes, if
_delete_actionRemove an actionid
_register_viewDeclare a read capabilityid, expr, scope, description, render
_delete_viewRemove a viewid
_send_messageSend a message to the roombody, kind, to
helpRead guidance documentskey

No _set_state. All writes through registered actions.


Expressions (CEL)

v9 uses a CEL Environment with domain helpers. Every entry is { value, _meta }.

Value and meta access

state._shared.phase.value == "executing" state._shared.phase._meta.writer == self state._shared.phase._meta.velocity > 0.3

Domain helpers

salient(state._shared, 0.5) // keys above score threshold elided(state._shared) // keys with elided values written_by(state._shared, self) // keys you last wrote focus(state._shared) // high-tier keys velocity_above(state._shared, 0.3) // actively-written keys contested(actions) // actions sharing write targets top_n(state._shared, 5) // top 5 by score

Collection patterns

state._shared.keys().filter(k, state._shared[k]._meta.score > 0.5) state._shared.entries().filter(e, !e.entry._meta.elided).map(e, e.key)

Shorthands

val(state._shared.phase) == "executing" // extracts .value meta(state._shared.phase, "writer") // extracts ._meta field

Validation

Expressions are validated at registration with structured feedback:

{ "error": "invalid_cel", "stage": "parse", "detail": "Unexpected token: EOF", "hint": "Syntax error. Check: balanced parentheses, valid operators (== not ===).", "help": "expressions" }

The help field points to a help key — invoke help({ key: "expressions" }) for the full guide.


Conflict detection

When two actions write to the same (scope, key) target, the second registration returns a warning. Contention is visible in each action's _meta.contested:

actions.add_concept._meta.contested // → ["refine_concept"] contested(actions) // → ["add_concept", "refine_concept"]

Context shaping (v9)

Context is shaped by salience score. Three tiers:

TierConditionValue_meta
Focusscore >= focus_thresholdFullFull (provenance, trajectory)
Peripheralscore >= elide_thresholdFullMinimal (score, revision, updated_at)
Elidedscore < elide_thresholdnullMinimal + expand hint

Shaping params

GET /context?elision=none                   Disable elision (see everything)
GET /context?expand=_shared.some_key        Force key to Focus tier
GET /context?focus_threshold=0.3            Lower the Focus bar
GET /context?elide_threshold=0.0            Nothing gets elided
GET /context?depth=lean                     Action detail: available + description
GET /context?depth=full                     + writes, params, if conditions
GET /context?depth=usage                    + invocation counts
GET /context?only=actions                   Just actions section
GET /context?messages=false                 Skip messages
GET /context?messages_after=42              Messages after seq 42

_shaping summary

Every response includes _shaping:

{ "focus_threshold": 0.5, "elide_threshold": 0.1, "elision": "auto", "state_entries": { "focus": 5, "peripheral": 8, "elided": 12, "total": 25 } }

Help system

KeyContent
guideParticipant guide — read/act rhythm, entry shape, shaping
expressionsCEL expression guide — .value, ._meta, helpers, common mistakes
wrapped_entriesThe { value, _meta } shape — why, how, three layers
functionsDomain helper reference — salient(), elided(), written_by(), etc.
shapingContext shaping — elision, expand, thresholds
standard_libraryReady-to-register action definitions
vocabulary_bootstrapBootstrapping a room from scratch
contested_actionsResolving write target contention
directed_messagesAttention-routed messages
if_versionProof-of-read versioning

Invoke help({ key: "expressions" }) for any key. Room overrides: write to _help scope.


API surface

── Auth ──
POST   /auth/device                        Initiate device auth
GET    /auth/device                        Browser approval page
POST   /auth/device/token                  CLI polls for token
GET    /auth/elevate                       Scope elevation page
POST   /tokens                             Mint a scoped token
GET    /tokens                             List your tokens
PATCH  /tokens/:id                         Update token scope
DELETE /tokens/:id                         Revoke a token
POST   /tokens/refresh                     Refresh token

── OAuth / WebAuthn (MCP clients) ──
GET    /.well-known/oauth-protected-resource
GET    /.well-known/oauth-authorization-server
POST   /oauth/register                     Dynamic Client Registration
GET    /oauth/authorize                    Consent page
POST   /oauth/token                        Token exchange

── Room lifecycle ──
POST   /rooms                              Create room
GET    /rooms                              List rooms
GET    /rooms/:id                          Room info
DELETE /rooms/:id                          Delete room (owner only)
POST   /rooms/:id/agents                   Join room
POST   /rooms/:id/invite                   Invite user

── Core (read + write) ──
GET    /rooms/:id/context                  Read context (shaped by salience)
GET    /rooms/:id/wait                     Block until condition
GET    /rooms/:id/poll                     Dashboard poll
POST   /rooms/:id/actions/:id/invoke       Invoke action
POST   /rooms/:id/eval                     CEL eval

── Temporal ──
GET    /rooms/:id/history/:scope/:key      Key history from audit trail
GET    /rooms/:id/samples/:viewId          View value samples (sparklines)
GET    /rooms/:id/salience                 Salience map (agent-specific)
GET    /rooms/:id/replay/:seq              Replay room to sequence

── Management ──
GET    /manage                             Management UI
POST   /mcp                                MCP JSON-RPC 2.0
GET    /docs                               Documentation
GET    /SKILL.md                           This file

MCP tools (18)

When connected via MCP (OAuth), these tools are available:

ToolDescription
sync_lobbyOverview of rooms, agents, roles. Starting point.
sync_embodyCommit to an agent in a room.
sync_disembodyRelease an agent.
sync_create_roomCreate a new room.
sync_list_roomsList accessible rooms.
sync_join_roomJoin a room as agent (low-level).
sync_read_contextRead room context (shaped, with expand/elision params).
sync_invoke_actionInvoke any action (returns wrapped writes with _meta).
sync_waitBlock until CEL condition.
sync_register_actionRegister a write capability (with CEL validation).
sync_register_viewRegister a read capability (with CEL validation).
sync_delete_actionRemove an action.
sync_delete_viewRemove a view.
sync_send_messageSend a message.
sync_helpRead help system.
sync_eval_celEvaluate CEL expression.
sync_restrict_scopeNarrow session scope.
sync_revoke_accessRemove room from session.

Reference

  • Architecture — thesis, axioms, design rationale
  • API Reference — all endpoints, request/response shapes
  • CEL Reference — expression language, context shape, patterns
  • Views Reference — render hints, surface types
  • Help Reference — help namespace, versioning, overrides
  • Examples — task queues, voting, private state
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.