Lantunnel
Install Lantunnel Client on each participating device to access your whole LAN from anywhere with P2P-first low-latency routing, encrypted transport, and relay fallback without port forwarding.
翻譯準備中
製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Release ledger and XRPL-anchored trust clock for a repo network: signed events, node manifests, and verification. Separate from Attestia's event store.
Attestia, Cognate, and RepoMesh are three products.
RepoMesh is the release network: signed events, node manifests, and an XRPL-anchored trust clock. It keeps its own RFC 6962 ledger.
Attestia proves that an event, a transaction, or a state transition happened, and binds that proof to a chain. The domain it ships is financial truth: personal vault, org treasury, and registrum. Its Merkle proofs are not this ledger.
Cognate is the AI governance domain on Attestia's event store and Merkle proofs. It calls RepoMesh when it needs a release checked. It does not keep a second event store, and it does not use Attestia's Merkle tree for this network.
Version 2.5.0.
post-anchor.mjs refuses to post, and opens no connection, unless the config says testnet and the WebSocket URL is a known testnet endpoint. An environment variable alone can't switch posting to mainnet. See XRPL Anchoring (Testnet Guard).node --test suites with a line-coverage floor and a production npm audit at high. validate-ledger and test are required checks on main, and registry-ci.yml now runs only after ledger-ci succeeds on main.run.preregistered, run.outcome and cognate.root.anchored, each with a sha256 digest and a urn:cognate:... URI. Only a governance node on both trustedAttestors and trustedRunAttestors (today, mcp-tool-shop-org/cognate) may sign them, and it may sign nothing else. Every run.outcome must reference a run.preregistered event already on the ledger.canonicalHash. The validator names and refuses a signature made over the canonical JSON text or over the 64-character hex string.See CHANGELOG.md for the full list.
RepoMesh turns a collection of repos into a cooperative network. Each repo is a node with:
node.json) declaring what it provides and consumesToday one GitHub organization, mcp-tool-shop-org, operates the log, the attestors, the policy check, and the XRPL anchor. Seven registered nodes do not make seven operators. An independent witness would be a party this organization does not operate.
The network enforces three invariants:
npx @mcptoolshop/repomesh init --repo your-org/your-repo --profile open-source
# JSON output for CI piping:
npx @mcptoolshop/repomesh init --repo your-org/your-repo --profile open-source --json
This generates everything you need:
node.json — your node manifestrepomesh.profile.json — your chosen profile.github/workflows/repomesh-broadcast.yml — release broadcast workflowThen add two secrets to your repo:
REPOMESH_SIGNING_KEY — your private key PEM (printed by init)REPOMESH_LEDGER_TOKEN — GitHub PAT with contents:write + pull-requests:write on this repoCut a release. Trust converges automatically.
All commands accept: --quiet, --verbose, --debug, --no-color. The init command also supports --json for machine-readable output.
Shell completions are available:
repomesh completion bash >> ~/.bashrc
repomesh completion zsh >> ~/.zshrc
| Variable | Purpose |
|---|---|
REPOMESH_LEDGER_URL | Override ledger endpoint |
REPOMESH_MANIFESTS_URL | Override manifests endpoint |
REPOMESH_FETCH_TIMEOUT | Fetch timeout in ms |
| Profile | Evidence | Assurance Checks | Use When |
|---|---|---|---|
baseline | Optional | None required | Internal tools, experiments |
open-source | SBOM + provenance | License audit + security scan | Default for OSS |
regulated | SBOM + provenance | License + security + reproducibility | Compliance-critical |
node registry/scripts/verify-trust.mjs --repo your-org/your-repo
Shows integrity score, assurance score, profile-aware recommendations.
Per-repo customization without forking verifiers:
// repomesh.overrides.json
{
"license": { "allowlistAdd": ["WTFPL"] },
"security": { "ignoreVulns": [{ "id": "GHSA-xxx", "justification": "Not reachable" }] }
}
repomesh/
profiles/ # Trust profiles (baseline, open-source, regulated)
schemas/ # Source of truth for all schemas
ledger/ # Append-only signed event log
events/events.jsonl # The ledger itself
nodes/ # Registered node manifests + profiles
scripts/ # Validation + verification tooling
attestor/ # Universal attestor (sbom, provenance, sig chain)
verifiers/ # Independent verifier nodes, operated by the same organization today
license/ # License compliance scanner
security/ # Vulnerability scanner (OSV.dev)
anchor/xrpl/ # XRPL anchoring (Merkle roots + testnet posting)
manifests/ # Committed partition manifests (append-only)
scripts/ # compute-root, post-anchor, verify-anchor
policy/ # Network policy checks (semver, hash uniqueness)
registry/ # Network index (auto-generated from ledger)
nodes.json # All registered nodes
trust.json # Trust scores per release (integrity + assurance)
anchors.json # Anchor index (partitions + release anchoring)
badges/ # SVG trust badges per repo
snippets/ # Markdown verification snippets per repo
pages/ # Static site generator (GitHub Pages)
docs/ # Public verification docs
tools/ # Developer UX tools
repomesh.mjs # CLI entrypoint
templates/ # Workflow templates for joining
Add node.json to your repo root:
{
"id": "your-org/your-repo",
"kind": "compute",
"description": "What your repo does",
"provides": ["your.capability.v1"],
"consumes": [],
"interfaces": [
{ "name": "your-interface", "version": "v1", "schemaPath": "./schemas/your.v1.json" }
],
"invariants": {
"deterministicBuild": true,
"signedReleases": true,
"semver": true,
"changelog": true
},
"maintainers": [
{ "name": "your-name", "contact": "https://github.com/your-org", "keyId": "ci-yourrepo-2026", "publicKey": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----" }
]
}
# Mint an ed25519 key and a paste-ready node.json maintainer block:
npx @mcptoolshop/repomesh keygen --repo <your-org>/<your-repo> --out repomesh-private.pem
keygen prints the public key + a keyId ready to drop into your node.json maintainers entry, and
writes the private key (mode 0600) only where you point --out — never to a tracked path. Store it as a
GitHub repo secret (REPOMESH_SIGNING_KEY). (Equivalent by hand: openssl genpkey -algorithm ED25519 ....)
Register ≥2 keys for a trust-critical node (TUF §6.1): a single key cannot sign its own revocation if compromised.
repomesh init --second-keyregisters a distinct second maintainer so one key can revoke the other —initwarns when a node has only one active key.
Open a PR to this repo adding your node manifest:
ledger/nodes/<your-org>/<your-repo>/node.json
ledger/nodes/<your-org>/<your-repo>/repomesh.profile.json
Copy templates/repomesh-broadcast.yml to your repo's .github/workflows/.
Set the REPOMESH_LEDGER_TOKEN secret (a fine-grained PAT with contents:write + pull-requests:write on this repo).
Every release will now automatically broadcast a signed ReleasePublished event to the ledger.
schemas/event.schema.json(repo, version, type) entriesThe ledger currently emits the live event types below. The rest are reserved / planned — the schema accepts them, but no node emits them yet. We list them so the roadmap is visible without implying coverage that does not exist (front-door honesty for a trust product).
Live (emitted today):
| Type | When |
|---|---|
ReleasePublished | A new version is released |
AttestationPublished | An attestor verifies a release |
ledger.anchor | The anchor node seals a partition (Merkle root + XRPL memo) |
attestation.dispute | A trusted node disputes an attestation (downgrades the verdict) |
KeyRotation | A maintainer key is rotated to a successor (prospective — past signatures stay valid) |
KeyRevocation | A maintainer key is revoked (compromise = retroactive invalidity, RFC 5280) |
AttestationPublished also carries Cognate's run attestations (run.preregistered, run.outcome,
cognate.root.anchored, since 2.4.0), signed only by its governance node.
Reserved / planned (not yet emitted):
| Type | Intended meaning |
|---|---|
BreakingChangeDetected | A breaking change is introduced |
HealthCheckFailed | A node fails its own health checks |
DependencyVulnFound | A vulnerability is found in dependencies |
InterfaceUpdated | An interface schema changes |
PolicyViolation | A network policy is violated. policy/scripts/check-policy.mjs can build and sign one; none is on the ledger yet |
Maintainer keys have a lifecycle. A key can be rotated to a successor or revoked, and verification is time-aware: a signature is trusted only if the key was valid at the signature's trusted time — the XRPL anchor close-time, the same trusted clock the ledger already uses.
# Rotate to a successor key (the retired key's past signatures stay valid)
npx @mcptoolshop/repomesh key rotate --repo your-org/your-repo \
--retiring mike-2026-01 --new-key mike-2026-06 --public-key new.pem
# Revoke a compromised key (signatures at/after the invalidity date are rejected)
npx @mcptoolshop/repomesh key revoke --repo your-org/your-repo \
--key mike-2026-01 --reason compromise --invalid-after 2026-06-18T00:00:00Z
KeyRevocation events; a single-key node whose only key is compromised is
recovered by a governance (trustedPolicy) node signing the revocation. Trust-critical nodes
should register ≥2 keys (TUF §6.1).node.json, a revocation is re-imposed from the signed, XRPL-anchored
events — a stripped manifest cannot revive a revoked key. See the threat model
for the boundary (verify against the canonical ledger; use --anchored for revocation-sensitive checks).| Kind | Role |
|---|---|
registry | Indexes nodes and capabilities |
attestor | Verifies claims (builds, compliance) |
policy | Enforces rules (scoring, gating) |
oracle | Provides external data |
compute | Does work (transforms, builds) |
settlement | Finalizes state |
governance | Makes decisions; since 2.4.0, signs Cognate's run attestations and nothing else |
identity | Issues/verifies credentials |
New check kinds and verifier nodes are added by editing data, not code. The check-kinds
registry, scoring weights, and node-kind permissions live in
verifier.policy.json (schema-validated, fail-closed). Adding a check (e.g.
sast.scan) is a ~6-line policy edit + a node.json, reviewed in a PR — no code change.
The one invariant: registered ≠ trusted. Registration lets a check participate; credit still requires a trusted-set consensus pass. Full guide: docs/verifier-plugin-contract.md.
Anyone can verify a release with one command — no clone required, the CLI fetches the public ledger for you:
npx @mcptoolshop/repomesh verify-release --repo mcp-tool-shop-org/shipcheck --version 1.0.4 --anchored
This checks:
ReleasePublished event exists and is signed (Ed25519) by a key registered to that repo's own node.json — a key registered to a different repo cannot validate it.pass (per (check, signer), the event at the greater ledger index wins; the signer's timestamp is data only), with at least one independent attestor. A release with only a self-signature and no independent attestations reports UNVERIFIED, never PASS.--anchored: the partition's Merkle root is recomputed and matched to the manifest, and — when the network is reachable — the on-chain XRPL transaction is fetched and asserted (validated + tesSUCCESS, the signing account is in the trusted-anchor allowlist, and the on-chain memo binds to the local root/manifest-hash/count). Offline, it reports XRPL NOT verified rather than a fake transaction; strict --anchored then fails (use --anchored-or-local to accept a locally-verified manifest without the on-chain proof).For CI gates, choose an output format with --format <text|json|sarif|markdown> (--json is an alias
for --format json):
npx @mcptoolshop/repomesh verify-release --repo mcp-tool-shop-org/shipcheck --version 1.0.4 --anchored --format json
The exit code is derived from the tri-state verdict, so a CI step can gate on it directly:
| Exit | Verdict | Meaning |
|---|---|---|
0 | PASS | Authentic and assured (or UNVERIFIED when relaxed by --fail-on=fail). |
1 | FAIL | Hard failure — forged/wrong-repo signature, non-allowlisted attestor, or a required check failed. |
3 | UNVERIFIED | Soft — not-yet-anchored, no independent witness, or a required check missing. |
2 | — | Usage error or internal crash. |
The same CLI is published as ghcr.io/mcp-tool-shop-org/repomesh, tagged with the npm version and the git sha. The image runs as a non-root user. It does not contain a wallet seed.
docker run --rm ghcr.io/mcp-tool-shop-org/repomesh verify-anchor --tx <TX_HASH>
Posting an anchor is a separate command. XRPL_SEED is passed at runtime:
docker run --rm -e XRPL_SEED --entrypoint node ghcr.io/mcp-tool-shop-org/repomesh \
anchor/xrpl/scripts/post-anchor.mjs
The daily workflow builds this image from the checkout and posts with it.
Anchoring in anchor/xrpl/config.json is testnet only ("network": "testnet"). anchor/xrpl/scripts/post-anchor.mjs enforces a fail-closed endpoint guard (assertPostingEndpoint) before validating XRPL_SEED or constructing an xrpl.Client:
config.network === "testnet" and the resolved WebSocket URL (process.env.XRPL_WS_URL || config.rippledUrl) is in KNOWN_TESTNET_WS_URLS (wss://s.altnet.rippletest.net:51233, wss://clio.altnet.rippletest.net:51233, wss://testnet.xrpl-labs.com). Setting XRPL_WS_URL to a mainnet or unknown URL is refused immediately with a message naming both the resolved network and the resolved URL.anchor/xrpl/config.json setting "network": "mainnet", "allowMainnetPosting": true, and "mainnetAllowedEndpoints": ["wss://..."] containing the target wss:// endpoint, after adding the funded mainnet classic address to the shipped allowlist ceiling (packages/repomesh-cli/src/trusted-anchor-accounts.mjs). That allowlist is a ceiling: a fetched config can drop an account and cannot add one.--fail-on <fail\|unverified> sets strictness. Default unverified fails on both FAIL and
UNVERIFIED; --fail-on=fail lets UNVERIFIED pass (exit 0, with a warning) for warn-mode adoption.
Verify a whole batch in one ledger load with verify-all, and verify offline against a local clone
with --local:
# Every release in the trust index, warn-mode
npx @mcptoolshop/repomesh verify-all --from-registry --fail-on fail
# Offline against a local ledger checkout
npx @mcptoolshop/repomesh verify-release --repo org/repo --version 1.0.0 --local ./repomesh
Gate it in CI with the bundled composite action — see Using the GitHub Action:
- uses: mcp-tool-shop-org/repomesh/.github/actions/verify@v1
with:
repo: ${{ github.repository }}
version: ${{ github.event.release.tag_name }}
anchored: "true"
See docs/verification.md for the full verification guide, threat model, and key concepts.
The verification engine is exported as a stable programmatic API — embed it in your own tooling instead of shelling out to the CLI:
import { verifyRelease, buildSarif, exitCodeForStatus } from "@mcptoolshop/repomesh";
const result = await verifyRelease({ repo: "org/repo", version: "1.0.0", local: "./repomesh" });
process.exitCode = exitCodeForStatus(result.status);
The dashboard publishes a machine-readable status.json
for external polling — ledger freshness (with a frozen-ledger signal), trust-verdict counts, anchored vs.
pending partitions, and an ok/degraded rollup with reasons.
Repos can embed trust badges from the registry:
[](https://mcp-tool-shop-org.github.io/repomesh/repos/mcp-tool-shop-org/shipcheck/)
[](https://mcp-tool-shop-org.github.io/repomesh/repos/mcp-tool-shop-org/shipcheck/)
[](https://mcp-tool-shop-org.github.io/repomesh/repos/mcp-tool-shop-org/shipcheck/)
npx @mcptoolshop/repomesh verify-release --repo mcp-tool-shop-org/shipcheck --version 1.0.4 --anchored
Attesting and running verifiers are operator tasks that act on a clone of this ledger, so they run from a checkout. Verifying a release does not — use the
npxcommand above.
node attestor/scripts/attest-release.mjs --scan-new # process all unattested releases
node attestor/scripts/attest-release.mjs --scan-new --dry-run # preview without writing
Checks: sbom.present, provenance.present, signature.chain
node verifiers/license/scripts/verify-license.mjs --scan-new
node verifiers/security/scripts/verify-security.mjs --scan-new
Security verifier thresholds (max CVEs, allowed severities) are config-driven via verifiers/security/config.json.
node policy/scripts/check-policy.mjs
Checks: semver monotonicity, artifact hash uniqueness, required capabilities.
RepoMesh touches ledger events (signed JSON), node manifests (public keys + capabilities), registry indexes (auto-generated trust scores), and XRPL testnet (anchor transactions; posting refuses any endpoint that isn't a known testnet one). It does not touch member repo source code, private keys, user credentials, or browsing data. Private signing keys never leave the CI runner. Network access is limited to the GitHub API (PR creation), XRPL testnet (anchoring), and OSV.dev (vulnerability lookups). No telemetry is collected or sent — zero analytics, zero crash reports, zero phone-home. See SECURITY.md for the full scope, required permissions, and vulnerability reporting process, and the threat model for the key-lifecycle trust boundary (why node.json authenticity depends on its source, and why revocation-sensitive verification should use --anchored).
Hardening:
execFileSync with array arguments; the remaining execSync calls use static, constant command strings — no shell-injection vectors.try/catch with structured, line-numbered errors; a malformed line is skipped and surfaced, never crashes the tool with a raw stack..gitignore, never printed to stdout or CI logs, and written with owner-only (0600) permissions.The full node --test suite covers Ed25519 signatures, schema validation, Merkle tree
integrity (v1 + RFC-6962 v2), append-only invariants, path traversal prevention, anchor
verification, the trusted-attestor allowlist, and input validation across the CLI, ledger,
anchor, verifier, and tools layers.
# Run every suite and read the exact pass/fail counts from the summary footer:
node --test $(git ls-files '*.test.mjs')
The test count grows as suites are added — run the command above for the current total rather than relying on a number that drifts out of date.
CI runs the same 9 suites on every pull request (ledger-ci.yml, the required test check), with
--experimental-test-coverage and a line-coverage floor (--test-coverage-lines=57), then
npm audit --audit-level=high --omit=dev for the root, anchor/xrpl and ledger.
MIT
Built by MCP Tool Shop