go.ecorce.app · mission brief

One tree.
Many leaves.

GO is a single place where reusable functions live as bark, and every app is only a leaf on that bark. You do not grow a private root for each leaf.

For the Grok builder Read this before writing code Cloudflare Workers v0 · 2026-08-29

The idea

Écorce is the bark of a tree: the living skin that every branch shares. GO is that skin, as software.

People will ask you to build tools — ordering, directories, dashboards, little utilities. Those tools are leaves. The work that more than one leaf could use is bark. Bark is published once, versioned, and discovered by every later leaf.

All of it lives on one origin, built as Cloudflare Workers: go.ecorce.app.

Two kinds of asset

Surface · the bark

Reusable capability

A named function with a schema, a version, and a permission. APIs, actions, lookups, agent descriptions. Anything another app or agent should be able to call.

App · a leaf

Generated experience

A site, applet, or tool that people use. It may orchestrate and display. It may not hide a backend of its own. It only calls surface functions listed in its lockfile.

A catalog lists every surface function and every app, with versions, and hands agents a clean URL for each. If it is not in the catalog, it does not exist.

A catalog entry for a surface function must have: name, version, permission, job, input schema, output schema, errors, changelog.

Permission is one of:

public caller kernel

The one rule

When a new app needs behavior, do not invent a private function for that app. Do this, in order:

An app may be rebuilt later. Rebuilding means: read the catalog again, prefer newer compatible surface versions, reuse first, then ship a new app version.

Addresses

One hostname. Assets are versioned, not the platform.

WhatURL
This missiongo.ecorce.app/mission
Cataloggo.ecorce.app/catalog
Surface, latestgo.ecorce.app/s/{name}
Surface, pinnedgo.ecorce.app/s/{name}@{semver}
App, latestgo.ecorce.app/a/{slug}
App, pinnedgo.ecorce.app/a/{slug}@{n}
Buildergo.ecorce.app/builder

Names are dotted and stable: orders.create, catalog.search, app.state.get.

How you call a function

When a surface function is live, call it with POST to https://go.ecorce.app/s/{name}@{semver}. The body is JSON input. The response is { ok, data, error }.

Pin the semver in production. latest is browse-only — never a production pin.

POST is live for published functions. Call POST /s/{name}@{semver} with JSON input. The catalog lists every published surface function and app. Pin @1.0.0 in production. latest is browse-only.

How you build

  1. 1Read the catalog. Always. Before code, before a plan. Treat it as the only memory of what already exists. It lists published surface functions and apps — not upcoming names.
  2. 2Name the smallest surface change. Reuse, a compatible extension, or one new function. Never a private helper.
  3. 3Publish surface first. Schema, permission, short changelog, implementation. Versions are immutable.
  4. 4Generate the leaf. UI and orchestration only. Lock the exact surface versions you call.
  5. 5Ship an app version. Give it a slug, a number, and a URL. Then stop. Do not keep a secret backend on the side.

Versions, simply

Surface uses semver. Apps use a rising integer plus a lockfile.

A leaf may only call the pins in its lockfile:

# app lockfile
{
  "app": "slug",
  "version": 1,
  "surface": [{ "name": "catalog.list", "version": "1.0.0" }]
}

Upcoming bark

bark · mixed

Live names are in /catalog. The rest stay reserved until published. Do not ship mock grocery data, private backends, or invented functions to look busy.

NameJobStatus
catalog.listList assets.live @1.0.0
catalog.getFetch one asset and its versions.live @1.0.0
catalog.searchFind a function by name or job.upcoming
app.state.getRead per-app state.upcoming
app.state.putWrite per-app state.upcoming
assets.putStore generated files.upcoming
builder.proposeSubmit a surface or app version.upcoming
audit.logRecord who called what.upcoming

app.state.get / app.state.put are session and UI state only. Domain records — orders, merchants, producers — must be named surface functions. Never dump a product database into app.state.

How it runs

One trusted kernel Worker on Cloudflare. It owns the catalog, the routes, and the real credentials. Generated apps do not get raw D1, KV, R2, or open network. They receive only a surface binding: the functions in their lockfile.

Start without evaluating arbitrary server code. First generation: static UI plus the kernel. If isolates are available later, the URLs do not change.

You are done when

Agent contract

If you are Grok, this page is standing orders. You are a gardener, not a carpenter of sheds. Grow bark when the orchard needs it. Grow leaves that drink from that bark. Do not bury pipes under a single tree.

When the human prompts you to build GO, or to build an app on GO, follow the loop. Speak in small plans. Name the surface functions you will reuse or create before you emit files.

Machine copy of this contract: mission.json

# standing orders
look → reuse | extend | grow → lock → ship

allowed
  publish surface functions
  generate apps that only call surface
  version, pin, rebuild

forbidden
  private backends
  silent breaking changes
  calling unlisted functions
  treating latest as a pin