All notable changes to the NCP specification and its reference tooling (schemas, examples, validator, runtime) are documented in this file.
Format follows Keep a Changelog. Brick versions follow Semantic Versioning. NCP protocol versions follow the versioning policy in the spec (v0.2.x patch-compatible, breaking changes require v0.3.0).
runtime/src/lib.rs: crate-level//!documentation block — renders as the docs.rs landing page (https://docs.rs/ncp-runtime). Explains whatncp-runtimeis, shows the install command, summarizes what the runtime does, links to the project README + install guide + adoption guide + protocol spec, and notes the stability boundary (CLI/runtime stable for evaluation; Rust module API treated as reference-runtime internals until the SDK work lands in Phase 3A.4).
- docs.rs landing page: previously lacked crate-level orientation docs
(no
//!documentation inlib.rs), so docs.rs only exposed the module surface without explaining what the runtime is or how to start. v0.3.6 adds the landing page block. - rustdoc HTML-tag-interpretation warnings: 4 doc comments contained
bare angle-bracket constructs (
Option<f64>inmapping.rs,<ms>inncp-bench.rs,<the user's input value>inenvelope.rs,<short_name>.wasminresolver.rs) that rustdoc was interpreting as HTML tag starts. Wrapped each in inline backticks. Verified clean with rustdoc warnings denied:RUSTDOCFLAGS="-D warnings" cargo doc -p ncp-runtime --no-deps --all-features.
README.md+docs/ADOPTION_GUIDE.md: badges row gained crates.io + docs.rs + MSRV; Status line refreshed with concrete install-channel links; ADOPTION_GUIDE §0 Prereqs tightened (Rust 1.94+); §1 now leads withcargo install ncp-runtime --locked(source build demoted to developer path); §9 production-readiness framing updated to "distribution channels are live as of Phase 3A.1".runtime/Cargo.toml: crate version bumped0.3.5→0.3.6.Cargo.lockupdated to match (only thencp-runtimeself-version entry; no transitive dep drift).
README.md: converted repo-relative Markdown links and theNCP-logo.pngimage src to absolutehttps://github.com/.../blob/main/...(and/raw/main/for the image) URLs. crates.io renders the README as the crate's landing-page docs, and resolves relative links from the crate's manifest location (runtime/) — not the workspace root. That made every relative link 404 on the v0.3.4 crates.io page (e.g.docs/INSTALL.mdbecameruntime/docs/INSTALL.md). Absolute URLs render correctly on both crates.io and GitHub. Same-page anchors like#quick-start-runtimeare intentionally left relative.
runtime/Cargo.tomlcategories: replaced the misleadingasynchronous(the runtime is synchronous; wasmtime used in blocking mode, notokio/futures/async fn) with the acceptedartificial-intelligencecategory (crates.io's official scope: "machine learning, deep learning, large language models, AI agents, and related tooling" — direct fit for an agent-graph runtime). Final categories:["artificial-intelligence", "wasm", "command-line-utilities"]. Validated against the crates.io allowlist viacargo publish --dry-run --locked --allow-dirtyruntime/Cargo.toml: crate version bumped0.3.4→0.3.5.Cargo.lockupdated to match (only thencp-runtimeself-version entry; no transitive dep drift)docs/PUBLISHING.md§3.1: added a README-content gate to the pre-flight checklist. Unpacks the just-built.crateand greps for any bare repo-relative Markdown links or HTMLsrc=references that crates.io would rewrite under the crate's subdirectory. Fail-hard with non-zero exit. Catches the exact failure class that bit v0.3.4 (where the local dry-run was green but the rendered crates.io README shipped with broken links). Version-derived so the gate doesn't need hand-editing on every releaseREADME.md: Docker quick-install example version pin bumpedv0.3.4→v0.3.5so the rendered crates.io README ships consistent with the released image tag (intentionally not sweeping the equivalent references indocs/INSTALL.md— those are deferred to a separate doc-refresh PR post-v0.3.5)
docs/INSTALL.md: install matrix for adopters — GitHub Releases archives, Docker (GHCR),cargo installfrom crates.io, and build-from-source — each with per-OS commands and checksum verification. Architecture coverage table at top makes Apple Silicon vs Intel + Linux x86_64 vs aarch64 self-serviceruntime/Cargo.tomlcrates.io publish metadata:description,repository,homepage,readme = "../README.md",keywords(wasm,agentic-ai,graph,deterministic,ncp),categories(wasm,command-line-utilities,asynchronous), and explicitincludearray. Verified end-to-end viacargo publish --dry-run --lockedand unpacked-cratecargo install --path . --bin ncp --locked(produces workingncpbinary)runtime/LICENSE+runtime/NOTICE: verbatim copies of the repo-root files. Cargo'sincludearray silently strips..paths, so local copies are needed for Apache 2.0 §4(d) compliance in the published.crate(readme = "../README.md"continues to work because cargo special-cases thereadmefield)README.md: top-level "Install" section above "Quick start", linking todocs/INSTALL.md. Pre-built install paths are now the default story; building from source is positioned as the developer path- Release workflow (
.github/workflows/release.yml): pushing av*tag produces a GitHub Release with per-OS archives (linux_x86_64.tar.gz,macos_aarch64.tar.gz,windows_x86_64.zip) plusSHA256SUMS. Each archive ships thencpbinary,examples/,LICENSE,NOTICE,README.md(Apache 2.0 §4(d) compliant).workflow_dispatchaccepts ataginput and apublishchoice (defaultfalse) for build-only dry-runs against existing tags. Pre-release tags (v*-rc.*,v*-alpha.*,v*-beta.*) auto-marked as GitHub prerelease docs/PUBLISHING.md: maintainer-facing release ceremony covering prerequisites, release-state confirmation, workflow dry-run, RC tag flow, artifact verification, RC cleanup (including BOTH GHCR tag forms viagh api --paginate), Zenodo auto-archive verification, GHCR publish flow (build-only dry-run, post-publish digest-equality verification, ONE-TIME first-publish visibility flip), and crates.io publish flow (early dry-run gate, live publish from the resolved tag, README link audit, clean-host install verification)- Docker image (
Dockerfile+.dockerignore+.github/workflows/docker.yml): two-stage build (rust:1.94-bookworm→gcr.io/distroless/cc-debian12:nonroot, small distroless final image). Examples baked underWORKDIR=/app. Triggers onv*tag push +workflow_dispatch. Each release publishes BOTHv0.3.4(git-tag form) AND0.3.4(semver form) to GHCR — same image digest, two equivalent references. No:latest, no floating:0.3.linux/amd64only (multi-arch deferred to Phase 3C)
runtime/Cargo.toml: crate version bumped0.3.3→0.3.4to align with the v0.3.4 release tag.Cargo.lockupdated to match (only thencp-runtimeself-version entry; no transitive dep drift)
- Rust CI workflow (
.github/workflows/rust.yml): fmt, clippy with-D warnings, cross-platformcargo test -p ncp-runtimematrix on pinned OS images (ubuntu-24.04,macos-14,windows-2022); separatewasm-buildjob for brick crates targetingwasm32-unknown-unknown; per-jobtimeout-minutes; explicitpermissions:scope (contents: read,actions: writefor cache);--lockedon every cargo invocation - Smoke integration tests (
runtime/tests/smoke.rs): exercise every runnable example graph end-to-end viaRuntimeContext::load+.execute(in-process, no binary spawn); paths derived fromenv!("CARGO_MANIFEST_DIR")for OS-independent resolution; trap-pipeline assertion accepts any non-emptyerror_classto remain robust across Wasmtime version drift - Citation metadata:
CITATION.cff(GitHub "Cite this repository" panel) and.zenodo.json(Zenodo archive metadata), both bound to concept DOI10.5281/zenodo.19570209 - Branch protection: 6 new Rust CI check contexts required alongside the
existing DCO + validate +
wasm-digest-checkset; force-push and branch deletion blocked onmain; web-based commit sign-off enforced docs/BRANCH_PROTECTION.md: audit trail for the branch-protection ruleset (current required checks, exactgh apicommand sequence used, rollback procedure, schema-fallback note)
docs/ADOPTION_GUIDE.md: everyncpCLI example now includes the requiredrunsubcommand (previously copy-pasted commands failed withunrecognized argument).ncp-benchinvocations unaffected (positional graph argument, no subcommand)
runtime/Cargo.toml: crate version bumped0.1.0→0.3.3to align with the release tag and eliminate thecargo install ncp-runtimeversion surprise.Cargo.lockupdated to match (only the self-version entry).- Brick crates (
ncp-echo,ncp-classifier-stub) intentionally remain at crate version0.1.0. Their Rust crate version is decoupled from the NCP-brick-manifest version (declared inexamples/bricks/*/manifest.yaml, also0.1.0). The two will align when bricks are published to crates.io in Phase 3A.
- Apache-2.0 +
NOTICE+ DCO + No-CLA governance finalized - Zenodo DOI archive (
10.5281/zenodo.19570209) via Zenodo's GitHub integration — citable prior art for the protocol, reference runtime, and benchmark methodology - DCO enforced as required status check on
mainvia branch ruleset "Main Protection" README.mdfinalized: DOI / CI / license / release badges, headline benchmark summary, and "Numbers you can quote" framing
- Benchmark harness (
runtime/src/bin/ncp-bench.rs): configurable warmup/runs, JSON output, LLM latency simulation via--simulate-llm-mswithExecuteHooks.on_invoke,--datasetmode for mixed-workload JSONL files with dual timing (execute-only + end-to-end), dataset SHA-256 provenance in JSON output, contextual parse error messages,--concurrency Nmulti-threaded throughput mode viaArc<RuntimeContext>,--cold-startload+compile timing measurement - RuntimeContext library pattern (
runtime/src/lib.rs): load/compile once, execute N times; pluggableTraceSinktrait withenabled()for zero-cost bench mode - Classifier-stub brick (
bricks/classifier-stub/): keyword-based sentiment,bit_exact,no_std, returns Success (positive) or LowConfidence/LOW_CONFIDENCE (negative) - Support-routing-stubbed graph (
examples/graphs/support-routing-stubbed/): classifier → echo escalation path withon_error(LOW_CONFIDENCE)routing - Benchmark datasets (
bench/datasets/): 3 deterministic JSONL files (90/10, 97/3, 50/50 positive/negative mix) with variant rotation for realistic input diversity - Benchmark results (
bench/results/): 16 Windows + 16 Linux (WSL2) machine-readable JSON files covering pure runtime overhead, simulated LLM latency, LLM-only baseline, measured mixed synthetic workloads, cold-start timing, and concurrency throughput - Benchmark matrix script (
bench/run-matrix.sh): runs all 16 configs with one command - BENCHMARK.md: full methodology, results tables (pure overhead, simulated LLM, mixed workloads, cold start, concurrency throughput), Claims section with measured LLM-only baseline, measured mixed-workload speedups (not modeled), cross-platform comparison (Windows vs Linux/WSL2), and explicit caveats
- COST_MODEL.md: parameterized cost framework with explicit $/step derivation (~$0.00042 per million steps at $0.05/vCPU-hour)
- README.md: "Numbers you can quote" subsection with µs, ms, and $ figures
runtime/Cargo.toml: added[lib]section,ncp-benchbinary,default-run = "ncp"runtime/src/main.rs: thin CLI wrapper usingncp_runtime::*library importsruntime/src/cli.rs: added--verboseflag for per-step diagnosticsruntime/src/trace.rs: addedTraceSink::enabled()default method;NullTracereturns falseCargo.toml(workspace): addedbricks/classifier-stubto members
- Reference runtime (
runtime/): single-process Rust runtime executing NCP graphs end-to-end- Graph and Brick manifest loading with validation (version range, digest, size, format, limits)
- WASM sandbox via Wasmtime 43 with
StoreLimitsmemory enforcement - Model B ABI:
alloc/free/invokewith 4-byte LE length-prefixed result buffers - CBOR invocation envelope with sorted keys for cross-runtime determinism
- Result boundary validation: Success / LowConfidence / Failure per Section 9.2
- Deterministic routing per Section 7.4.1: on_error (priority desc, edge_id asc, single-target), on_success (threshold gating, weight desc, edge_id asc, fan-out)
- Field mapping: dot-path resolution, deep merge with stable key order
- SHA-256 artifact digest verification (case-insensitive hex, strict 64-char)
- JSON Lines trace emission per Section 11.1 (runtime_info + invoke records)
- FIFO queue orchestration with entry node detection and safety budgets (
--max-steps,--max-queued) - 44 unit tests: envelope, result boundary (16), routing conformance (13), field mapping (13)
- Trap Brick (
examples/bricks/trap/): WASM brick that always traps, for testing Section 16.2.1 error handling - Test graphs:
examples/graphs/echo-pipeline/: single-node echo (validates basic invocation + trace)examples/graphs/echo-chain/: two-node chain with on_success routing and field mappingexamples/graphs/trap-pipeline/: single-node trap (validates COMPUTATION_ERROR path)
- Cargo workspace configuration:
runtimeandbricks/echoas workspace members,runtimeas default - Rust toolchain pinned to 1.94.0 via
rust-toolchain.toml - Workspace-level
[profile.release]for WASM-optimized builds
bricks/echo/Cargo.toml: moved[profile.release]to workspace root (eliminates cargo warning)docs/ROADMAP.md: Phase 2 marked complete, Phase 3 restructured into parallel tracks (3A Integrations, 3B Runtime Completeness, 3C Production Hardening)README.md: added runtime quick-start section, updated repository structureCONTRIBUTING.md: added Rust development workflow.gitignore: addedtarget/for workspace-level Rust build cache
- Corrected RFC 8742 (CBOR Sequences) references to RFC 8949 §4.2 (Deterministic Encoding) in spec and design-decisions
- Section 5.2: Canonicalization pinned to deterministic CBOR per RFC 8949 §4.2; JSON requires JCS (RFC 8785); YAML features rejected for digest computation
- Section 16.3: Fixed intro from "MUST provide imports" to "MUST support result-buffer memory management" (alloc/free are Brick exports, not runtime imports)
- Section 6.6.2: Runtime intrinsics and external model access —
ncp_runtime.*import namespace, feature declaration/discovery, conformance profile statement - Section 7.4.1: Routing evaluation order — deterministic algorithm for on_error matching, on_success threshold/weight ordering, tie-breaking, fan-out dispatch, default weight 0.0, invalid confidence handling
- Section 16.2.1: WASM trap handling — runtime MUST catch traps and convert to Failure with COMPUTATION_ERROR
ncp-validate packcommand: stamps manifest templates with real artifact digest and sizeconformance/: Test vectors for canonicalization (RFC 8949 §4.2) and routing evaluation order (Section 7.4.1)- CI: WASM digest check job
- Result model clarified as a three-variant discriminated union (Success, LowConfidence, Failure)
- Section 9.2 (Structural Boundary Rule) updated for three-variant semantics
- Section 9.5 (Confidence Signaling) updated for LowConfidence variant
- Carry state semantics:
carry_state_nextapplies on Success and LowConfidence;carry_state_side_effectsapplies only on Failure
- Resolved contradiction between Section 9.1 (two-variant Result text) and Section 9.2 (Structural Boundary Rule requiring output on LOW_CONFIDENCE)
- Fixed duplicate "Appendix B" header in spec document
- JSON Schemas (Draft 2020-12) for Brick Manifest, Graph Manifest, Invocation Envelope, and Result Model
ncp-validateCLI: structural (JSON Schema) + cross-field invariant validation for Brick and Graph manifests- 24 invariant rules (12 brick, 8 graph, 4 cross) with spec section references
- Example manifests from spec appendices (sentiment-gate, llm-escalation, support-routing)
- Test suite with positive and negative fixtures for all invariants
- CI workflow (GitHub Actions)
- Artifact extension point (Section 6.2)
- Stochastic model support with
model_pinandreproducibility_level(Section 6.6.1) - MCP integration appendix (Appendix C)
- Cost metadata (
estimated_cost_per_invoke_usd) in resource limits - Carry state side-effects channel (Section 6.9)
- Fan-in activation policies (Section 7.0)
- Trigger provenance in invocation envelope (Section 8.1)
- Carry state lifecycle management (Section 10.5)
- Wire format and transport specification (Section 16)
- Conformance suites (Section 15)
- Initial draft: Brick and Graph manifest structure
- Core concepts: Brick, Graph, Runtime, State Taxonomy
- Identifier format and Brick bundle specification
- Basic invocation envelope and result model