Skip to content

Tne-max/runx

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

788 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

runx OSS

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.

Your First Skill In 5 Minutes

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 \
  --json

Then 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.

Zero-Funded Payment Dogfood

Run the local payment dogfood lane without a funded wallet, hosted account, or provider keys:

pnpm x402:dogfood:local

This 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.

Requirements

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+

Install For Development

pnpm install
pnpm build
pnpm test
pnpm typecheck
pnpm verify:fast
pnpm rust:check

Contributor setup, test selection, and commit sign-off rules are in CONTRIBUTING.md.

Local CLI

For a live creator workflow, link the global runx binary to this checkout once:

pnpm --dir oss cli:link-global

Then 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" --json

Recommended 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.

Package Topology

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: native runx binary 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

Local Sandbox Posture

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.

Capability Packs

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:

  • runx owns 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.

Standalone Skill Packages

runx new <name> is the canonical standalone package scaffold:

runx new docs-demo

For cold-start adoption, the package entrypoint is:

npm create @runxhq/skill@latest docs-demo

Both 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.

Skill And X Model

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.

Tool Authoring

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 --json

run.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.

Official Packages

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.0

The 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: sourcey

This 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/sourcey

That MCP surface is a thin facade over the normal runx kernel path, so receipts, policy, approvals, and resolution requests still behave the same way.

Receipts

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>.json

runx 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.

Workspace Policy

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 Exports

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-tool

Rows 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.

Harness

runx harness currently supports standalone fixture YAML files in the native Rust CLI:

runx harness ./fixtures/harness/echo-skill.yaml --json

Do not advertise runx harness <skill-dir|SKILL.md> until the Rust CLI expands inline X.yaml harness cases natively.

Doctor And Dogfood

For the core first-party skill lane, run:

pnpm dogfood:core-skills

This 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:fast

That lane keeps the cheap workspace checks together: OSS typecheck plus the fast package test surface with the current structural budget and boundary coverage.

Build And Pack

pnpm --dir oss build
pnpm --dir oss test tests/cli-package.test.ts
cd oss/packages/cli
npm pack --dry-run --json

The package must include dist/index.js and dist/index.d.ts, and dist/index.js must be executable.

Boundary Rules

  • oss/ must not import from cloud/.
  • 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-core or runx-runtime dependency, 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.

About

the governed runtime for agent skills

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Rust 50.6%
  • TypeScript 42.4%
  • JavaScript 6.1%
  • Python 0.5%
  • Shell 0.4%
  • PowerShell 0.0%