@gnolith/workshop
v0.4.2
Published
Hosted agent tasks, memories, coordination, and tooling.
Maintainers
Readme
Workshop
@gnolith/workshop is Gnolith's agent-facing operating layer: durable research
tasks, ephemeral task packets, reusable memories, canonical prompts,
authorization-aware unified search and graph access, Taproot-backed knowledge
tools, Streamable HTTP MCP, Worker route factories, and the Workshop Waystone UI.
One Codex Site is one research project. Workshop operates inside that Site-wide graph and task system; it does not add projects, memberships, agent sessions, packet snapshots, or a background coordinator.
Runtime surfaces
| Import | Runtime | Purpose |
| ------------------------------ | -------------- | ----------------------------------------------------- |
| @gnolith/workshop | any | Package identity and safe shared types |
| @gnolith/workshop/core | any | Process-local services and authorized tool dispatch |
| @gnolith/workshop/protocol | browser/Worker | Models, errors, and injectable HTTP client |
| @gnolith/workshop/server | Worker/process | Persistence services, health, and HTTP adapters |
| @gnolith/workshop/mcp | any/Worker | Neutral tool dispatcher and stateless HTTP MCP server |
| @gnolith/workshop/site | Worker | Thin App Router-compatible route factories |
| @gnolith/workshop/ui | browser | React 19 components and workshopPlugin |
| @gnolith/workshop/migrations | installer | Embedded canonical migration manifest |
| @gnolith/workshop/styles.css | browser | Workshop-specific styles |
The root export intentionally does not import all runtimes.
Process-local integration
Core services run directly in a process without HTTP, a UI, or a listening server. The host injects one structural SQLite persistence capability, the same live atomic authorization authority used by Taproot, an opaque cursor codec, and read-authorized knowledge/health adapters:
import { createWorkshopCore } from '@gnolith/workshop/core';
import { createWorkshopSearchIntegrationV1 } from '@gnolith/workshop/server';
const search = await createWorkshopSearchIntegrationV1({
db: persistence,
taproot,
hostCapability,
installationId,
registrationContext: principal,
});
const workshop = createWorkshopCore({
persistence,
authorization,
cursorCodec,
knowledge: { authorizedReader, health: taprootHealth },
diamondHealth,
search,
});Workshop owns its exact migrations and service behavior. Seedbed owns database paths, adapter lifecycle, stdio/CLI wiring, Docker, and package assembly.
Install
npm install @gnolith/workshop @gnolith/diamond @gnolith/taproot reactWorkshop targets Node.js 22+ for development and Web API runtimes. Its published package is checked in isolated Worker and vinext consumers without the Workers Node compatibility flag. Those consumers inject or stub peer services and do not represent a complete Gnolith Site.
Site integration
Create the runtime once from host-provided D1, identity, Diamond, and Taproot services. Authentication belongs to the Site; role labels on tasks never grant permissions.
import { createWorkshopRuntime } from '@gnolith/workshop/server';
export const workshop = createWorkshopRuntime({
db: env.DB,
authorization: siteAuthorization,
cursorCodec: siteCursorCodec,
knowledge: {
authorizedReader: createAuthorizedReader,
health: taprootHealth,
},
diamondHealth: siteDiamond.health,
resolvePrincipal: authenticateWorkshopRequest,
search: workshopSearch,
});workshopSearch is created once with createWorkshopSearchIntegrationV1 after
Taproot and Workshop migrations. The factory initializes Taproot's durable
materialization state before registering the Task, Memory, and Prompt producers.
All three domains commit the Workshop mutation, immutable revision snapshot,
and canonical source event through Taproot's sealed atomic boundary. Legacy
adoption and rebuilds are explicit bounded search:admin operations.
siteAuthorization remains the single shared live source for authorized reads,
backfill maintenance, and cursor snapshots. Host-issued guards must preserve
exact capabilities and never add or translate them.
createAuthorizedReader must return the public AuthorizedTaprootReader bound
to that same source. Knowledge mutations are unavailable until that shared
foundation is complete.
Generated App Router files stay thin:
import { createWorkshopMcpHandler } from '@gnolith/workshop/site';
import { workshop } from '@/lib/gnolith/server';
const handler = createWorkshopMcpHandler(workshop);
export const GET = handler;
export const POST = handler;Consumers apply migrations explicitly before constructing the runtime. Runtime
construction never creates tables. workshopMigrations provides canonical SQL
and checksums; applyWorkshopMigrations(persistence) applies only
Workshop-owned schema through Diamond's shared namespaced checksum ledger when
the host chooses to initialize or migrate.
Core behavior
- Task creation validates every field, statically rejects SPARQL writes and unsafe query forms, and verifies all memory references before inserting.
claim_taskis one conditional SQLite update. Concurrent callers cannot both win.- Completion is one conditional update and accepts negative or inconclusive nonempty results.
- Task packets resolve authorized current memories on every read. Unscoped context-query execution is disabled until the host supplies a scoped graph boundary. Packet reads do not claim or mutate tasks.
- Task, Memory, and Prompt histories are bounded newest-first canonical snapshots. Each snapshot is authorized independently, and the exact current record plus live installation authorization are rechecked immediately before content returns.
- Knowledge reads use Taproot's authorized-reader boundary. Mutations are fail-closed and are not advertised by Workshop's MCP surface.
- MCP authenticates every request and authorizes every tool server-side.
- Detailed diagnostics require exact
admin; abandoned-claim reset requires exactadminplustask-write. Capabilities never imply one another. These operations are not normal MCP tools.
Development
npm ci
npm run checkThe gate covers formatting, lint, strict types, coverage, local D1 integration
and concurrency, MCP, routes, interactive UI, build, performance, generic
exact-tarball validation, isolated Worker and vinext package consumers, audit,
readiness, and release-artifact invariants. One generated tarball and its
machine-verifiable provenance are reused by every package consumer and release
check. Peer services in the runtime consumers are injected or stubbed. See
docs/release-provenance.md.
Configure the Waystone contribution with a browser-only client. Construction is lazy, so importing the UI never initializes a server runtime or captures host bindings:
import { createWorkshopClient } from '@gnolith/workshop/protocol';
import { createWorkshopPlugin } from '@gnolith/workshop/ui';
export const workshopUi = createWorkshopPlugin({
client: () =>
createWorkshopClient({
baseUrl: '',
token: () => sessionToken(),
}),
capabilities: currentCapabilities,
loadMcpStatus: loadWorkshopMcpStatus,
});Legacy onboarding journals remain quarantined and are not exposed by the public core, protocol, MCP, HTTP, or UI surfaces. A separately scoped reusable exploration skill will own future onboarding behavior.
Workshop package handoff ready means these package-owned gates pass against
the exact tarball. It does not qualify a complete Gnolith Site. The Codex agent
creating a Site owns four-package assembly, infrastructure and migrations,
identity and secrets, deployment configuration, live browser/MCP/Codex probes,
and final acceptance.
Documentation
- Architecture and domain semantics
- HTTP and client API
- MCP tools
- Authentication and authorization
- Migrations and upgrades
- Authorization foundation ledger
- Waystone UI
- Health and semantic verification
- Operational limits
- Security and threat assumptions
- Codex Sites compatibility
- Troubleshooting
- Release checklist and current evidence
- Package handoff contract
License
MIT
