Public open-source boundary for the runx CLI, trusted Rust local runtime, generated contracts, language-neutral extension protocols, SDKs, harness, local receipts, registry CE, marketplace integrations, official skills, and IDE plugin shells.
The npm CLI package is @runxhq/cli and exposes the runx binary.
Start with the checked-in hello-world skill:
cd oss
cargo build --manifest-path crates/Cargo.toml -p runx-cli
export RUNX_RECEIPT_SIGN_KID=runx-demo-key
export RUNX_RECEIPT_SIGN_ED25519_SEED_BASE64=QkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkI=
export RUNX_RECEIPT_SIGN_ISSUER_TYPE=hosted
export RUNX_RECEIPT_DIR="$(mktemp -d)"
crates/target/debug/runx skill examples/hello-world \
--message "hello from docs" \
--non-interactive \
--jsonThen inspect the emitted receipt. The full walkthrough is in docs/getting-started.md, and the next step is docs/skill-to-graph.md. For governed code changes, see docs/issue-to-pr.md.
Run the local payment dogfood lane without a funded wallet, hosted account, or provider keys:
pnpm x402:dogfood:localThis proves runx payment authority, refusal, receipt signing, offline receipt
verification, and the documented x402 upstream/x402-rs/CDP/Stripe SPT preflight
shape. It does not claim real x402 settlement or a real Stripe charge; live
conformance lanes require dedicated funded testnet wallets or provider test
credentials. No-secret preflight reports use can_run: false and missing_env
to name live blockers without printing secret values. See
docs/demos.md for the full split between
local dogfood and live protocol conformance.
Native CLI:
- Rust 1.85+
- The native Rust CLI path must stay useful without Node, pnpm, tsx, or TypeScript packages installed.
Workspace and npm wrapper:
- Node.js 20+
- pnpm 10+
pnpm install
pnpm build
pnpm test
pnpm typecheck
pnpm verify:fast
pnpm rust:checkContributor setup, test selection, and commit sign-off rules are in CONTRIBUTING.md.
For a live creator workflow, link the global runx binary to this checkout once:
pnpm --dir oss cli:link-globalThen invoke the linked runx binary from anywhere. Use explicit paths outside
a runx workspace; bare skill names resolve from the current workspace's
skills/ directory.
runx --help
runx skill /path/to/runx/oss/fixtures/skills/echo --message hello --json
cd /path/to/runx/oss
runx skill ./skills/design-skill --objective "build sourcey docs skill" --jsonRecommended flows:
runx init
runx init -g --prefetch official
runx new docs-demo
npm create @runxhq/skill@latest docs-demo
runx list skills
runx registry search sourcey --json
runx skill sourcey/sourcey@1.0.0 --registry https://runx.example.test --project . --json
runx add sourcey/sourcey@1.0.0 --registry https://runx.example.test --to ./skills --json
runx skill issue-to-pr --fixture /path/to/repo --task-id task-123
runx skill /path/to/skill --run-id <run-id> --answers answers.json
runx history <receipt-id> --json
runx history
runx mcp serve ./fixtures/skills/echo
runx skill ./skills/design-skill --objective "build github review skill"
runx harness ./fixtures/harness/echo-skill.yaml
runx config set agent.provider openai
runx config set agent.model gpt-5.1
runx config set agent.api_key "$OPENAI_API_KEY"With agent.provider, agent.model, and agent.api_key configured, the CLI
can now resolve managed agent work directly. Deterministic tools, approvals,
and required human inputs keep their existing local behavior.
The global link points at oss/packages/cli in this checkout. Rebuild with
pnpm --dir oss build; do not reinstall.
Rust owns the trusted local runtime path. The Rust crate graph is the enforced boundary map:
runx-contracts: Rust-owned public contract types and schema emission.runx-core: pure state-machine and policy decisions.runx-parser: pure skill, graph, runner, and tool manifest parsing.runx-receipts: canonical receipt model, hashing, signatures, and tree verification.runx-runtime: impure local runtime, adapters, sandbox planning, harness replay, journals, registry clients, payment gates, MCP, and execution.runx-cli: nativerunxbinary over the runtime.runx-sdk: blocking CLI-backed SDK over stable contracts.
The TypeScript package graph is the client, authoring, wrapper, and generated contract layer:
@runxhq/contracts: generated validators and TypeScript types over the Rust-owned schema artifacts.@runxhq/cli: npm distribution wrapper and client presentation around the native CLI.@runxhq/authoring,@runxhq/create-skill,@runxhq/host-adapters, and@runxhq/langchain: authoring, scaffolding, host presentation, and bridge packages over language-neutral contracts.
For the generated package export index, see docs/api-surface.md.
runx-runtime is the canonical local runtime. It owns local skill, graph,
harness, receipt, history, policy, authority, payment, sandbox admission and
metadata, MCP, built-in adapter execution, and external execution-adapter
supervision for the native CLI path. OS sandbox enforcement remains a separate
runtime hardening lane and must not be assumed from sandbox declarations alone.
TypeScript remains for generated contracts, CLI/client wrappers,
cloud/product integrations, host adapters, authoring tooling, and helper SDKs
over language-neutral protocols. Host adapters can shape host responses over
the runx host protocol; they do not own local execution. External execution
adapter authors target manifests and wire protocols, so they do not need Rust,
runx-core, runx-runtime, or a fork of the core repository. Source-event
ingress, hosted runtime binding, catalog/read-model access, and thread/outbox
provider adapters are separate protocol lanes, not reasons to broaden the
execution-adapter protocol into a second runtime.
Command-surface ownership:
| Surface | Canonical owner | TypeScript role |
|---|---|---|
runx skill local execution |
runx-runtime::execution via runx-cli |
npm launcher/client wrapper |
runx harness <fixture.yaml> |
Rust harness replay | tests and wrapper views |
| receipts and history | Rust receipt store and journal | display/client views |
| policy, authority, payment, x402 | Rust core/runtime policy | published type mirrors and product UX |
| external execution-adapter protocol | runx-runtime supervisor |
generated types, helper SDKs, host/client wrappers |
| non-execution extension protocols | lane-specific Rust/cloud owners | generated types, helper SDKs, provider glue |
| marketplace and docs tooling | TypeScript/scafld until separately cut over | canonical for authoring UX |
cli-tool skills declare sandbox intent in SKILL.md: profile, cwd policy,
env allowlist, network intent, and writable paths. Receipts record both the
declared policy and the actual local enforcement mode.
The current OSS runtime is declared-policy-only for local sandbox isolation:
runx applies admission, cwd, environment shaping, input delivery, and receipt
metadata, but it does not enforce filesystem, network, process-tree, or resource
isolation with OS primitives. Receipts mark filesystem and network isolation as
not-enforced-local.
Set sandbox.require_enforcement: true in a skill, or
RUNX_SANDBOX_REQUIRE_ENFORCEMENT=true in the environment, when a run must fail
unless a future OS-level sandbox enforcer is available. In the current OSS
runtime, that setting fails closed.
Runx is the generic execution engine. Product workflows stay outside the runx CLI and ship as local skills, runners, and tools in the consuming repo.
The intended extension model is:
runxowns generic runtime, thread, outbox, receipt, and handoff machinery- service repos own their product workflows as local capability packs
- operators execute those workflows through normal skill invocation
- CLI, API, and GitHub-comment triggers all normalize into the same capability execution envelope, while the thread stays the review/control object
Sourcey is the reference shape for this model: from inside the Sourcey repo,
runx skill ./skills/outreach --runner status --issue ... resolves the local
skills/outreach capability pack. outreach is not a privileged engine
command, and there is no privileged runx docs ... path inside the engine.
issue-to-pr follows the same boundary. runx owns the generic source-thread to
scafld to PR machinery; service repos own Slack, Sentry, owner assignment, and
publish policy. See docs/issue-to-pr.md.
runx new <name> is the canonical standalone package scaffold:
runx new docs-demoFor cold-start adoption, the package entrypoint is:
npm create @runxhq/skill@latest docs-demoBoth entrypoints go through the same scaffolder. Community skills should be
authored and published as standalone packages created this way. The main runx
repo is the first-party lane for official skills and runtime code, not the
community package catalog.
Registry search and install now normalize public trust into three tiers:
first_party, verified, and community. Richer provenance and attestation
metadata still travels with the registry row, but the user-facing install/search
surface stays readable.
Executable skills split authored skill content from execution profiles. X.yaml
is the runx execution profile file; the short name is public compatibility for
existing skill packages, but docs and code should describe it as the execution
profile:
skills/sourcey/
SKILL.md
X.yaml
Direct execution accepts the package directory or SKILL.md inside it. Flat
foo.md skill files are no longer a supported execution surface.
See ../docs/skill-profile-model.md for resolution rules, publication modes, trust tiers, MCP export, and composite skill behavior.
See ../docs/evolution-model.md for the evolve lane, the skill/tool boundary,
and the canonical composite execution geometry.
First-party tools are authored from source in:
tools/<namespace>/<tool>/
src/index.ts
fixtures/*.yaml
manifest.json
run.mjs
src/index.ts is the source of truth and uses defineTool() from
@runxhq/authoring. manifest.json and run.mjs are generated runtime
artifacts:
pnpm exec tsx packages/cli/src/index.ts tool build --all --json
pnpm exec tsx packages/cli/src/index.ts dev --lane deterministic --json
pnpm exec tsx packages/cli/src/index.ts dev --lane repo-integration --jsonrun.mjs is intentionally checked in as the thin runtime shim that imports the
authored source. Do not hand-edit generated manifest.json or run.mjs.
The official catalog is explicit about why each package is public:
- canonical governed skills:
charge,dispute-respond,evolve,improve-skill,least-privilege-auditor,overlay-generator,policy-author,receipt-auditor,refund,send-as,spend,weather-forecast - branded provider skills:
nitrosend,nws-weather-forecast,stripe-pay,x402-pay - context skills:
brand-voice,taste-profile
Other bundled packages stay in the same SKILL.md + X.yaml shape, but are
internal by default. Internal packages must declare why they remain bundled:
graph-stage, runtime-path, harness-fixture, or context. Owned graph
stages live below their public skill at skills/<skill>/graph/<stage>/X.yaml,
not as root catalog packages.
For first-party skill proposal work, the core builder bar is explicit: proposal packets should name the real pain being solved, explain fit against the current runx catalog, surface maintainer decisions cleanly, and avoid builder residue or placeholder targets.
Each ships as a portable SKILL.md plus a colocated execution profile at
skills/<skill>/X.yaml when it exposes deterministic runners or inline harness
coverage. Upstream skills that runx does not own keep their execution profiles
under bindings/<owner>/<skill>/X.yaml with adjacent binding.json
governance metadata. Bare skill names resolve only to local workspace skills or
locked first-party official shorthand. Third-party registry execution uses the
explicit owner/name@version form, optionally with --registry and
--digest, and only trusted signed registry packages are materialized into the
runnable cache. Official skills are registry-backed and cached locally on first
acquisition. The npm CLI package no longer needs to ship the official runtime
skill bodies for normal execution.
Agent graphs can also demand-load skills as context instead of executing them.
Put reusable judgement, operating procedure, or capability skills in the local
registry, then reference them from an agent-task step with context_skills:
context_skills:
- ../taste-profile
- registry:runx/taste-profile@1.0.0The runtime injects each referenced SKILL.md as a generic
runx.skill.context artifact in the agent invocation current_context. Local
path refs resolve relative to the graph; registry refs require
RUNX_REGISTRY_DIR and are read from the local registry, not fetched remotely at
execution time. Context skills are bounded, digest-labeled, and presented to
managed agents as untrusted advisory data.
Graph steps can execute local-registry skills too:
steps:
- id: build_docs
skill: registry:runx/sourcey
runner: sourceyThis uses the same explicit local-registry rule: set RUNX_REGISTRY_DIR, sync or
publish the skill into that registry first, and treat .runx/registry-step-skills
as generated runtime cache rather than source.
Any runnable skill package can also be exposed locally as an MCP tool with:
runx mcp serve ./skills/sourceyThat MCP surface is a thin facade over the normal runx kernel path, so receipts, policy, approvals, and resolution requests still behave the same way.
Local receipts are append-only JSON files under .runx/receipts unless RUNX_RECEIPT_DIR is set. runx history verifies receipt signatures and surfaces verified, unverified, or invalid status.
Publish a local receipt to the hosted notary with:
runx publish ./.runx/receipts/<receipt-id>.jsonrunx publish posts the full sealed receipt to POST /v1/receipts/notarize
with publish: true, then prints the public /r link and content hash returned
by the notary. Configure the hosted API with RUNX_PUBLIC_API_BASE_URL (default
https://runx.ai) and authenticate with RUNX_PUBLIC_API_TOKEN,
RUNX_CONNECT_ACCESS_TOKEN, or --token.
Projects can opt into stricter local cli-tool admission with
.runx/config.json:
{
"policy": {
"strict_cli_tool_inline_code": true
}
}When enabled, local execution rejects known inline interpreter and shell eval
forms such as node -e, python -c, and bash -lc. Move the program into a
checked-in script file and invoke that file instead.
Trainable export is currently a TypeScript-maintained projection command. It can project verified receipt lineage into newline-delimited training rows without mutating the original receipts, but it is not yet part of the native Rust CLI surface:
runx export-receipts --trainable
runx export-receipts --trainable --receipt-dir ./.runx/receipts --status complete --source cli-toolRows are emitted as JSONL and follow the public training contract published at:
https://runx.ai/spec/training/trainable-receipt-row.schema.json
The export keeps receipt identity, verified outcome resolution, ledger artifacts, and runner provenance together so downstream training and eval systems can consume governed lineage instead of raw prompt logs.
runx harness currently supports standalone fixture YAML files in the native
Rust CLI:
runx harness ./fixtures/harness/echo-skill.yaml --jsonDo not advertise runx harness <skill-dir|SKILL.md> until the Rust CLI expands
inline X.yaml harness cases natively.
For the core first-party skill lane, run:
pnpm dogfood:core-skillsThis remains a TypeScript wrapper lane. The native Rust proof for local orchestration is the Rust CLI/runtime test and fixture suite; wrapper dogfood is useful only after the same behavior is proven without Node, pnpm, or tsx.
For the default structural verification lane during refactors, run:
pnpm verify:fastThat lane keeps the cheap workspace checks together: OSS typecheck plus the fast package test surface with the current structural budget and boundary coverage.
pnpm --dir oss build
pnpm --dir oss test tests/cli-package.test.ts
cd oss/packages/cli
npm pack --dry-run --jsonThe package must include dist/index.js and dist/index.d.ts, and dist/index.js must be executable.
oss/must not import fromcloud/.- State-machine and policy packages remain pure.
- Rust owns trusted local runtime/execution, including sandbox, receipts, policy, authority, payment, harness, built-in adapters, and external execution-adapter supervision.
- TypeScript runtime-local and adapters packages must not be fallback executors for trusted local behavior.
- External execution adapters own their side effects behind language-neutral protocols and manifests; non-execution extension lanes have their own protocol contracts.
- External extension authors must not need Rust, a
runx-coreorrunx-runtimedependency, or a core repository fork. - CLI, SDK, IDE plugin, host adapter, and MCP entrypoints delegate to runner contracts or external protocols instead of duplicating the engine.