mergedhumanPR #197Trust
Trust/Payments layer: verifiable capsule receipts (capsule-emit-nanda) — rebuild addressing #177
Re-opens the work from #54 → #177 (closed by @Skyrider3), rebuilt to address every
Description
The pitch.
# Trust/Payments layer: verifiable capsule receipts (`capsule-emit-nanda`) > cc @Skyrider3 @dhve — this reopens the trust-layer work from #54 → #177, which > you closed as surface-level. You were right, and the clean review was appreciated. > It's been rebuilt so the structural work is actually done: each of your four points > is addressed below, verified against this repo's real `ci.yml` (plain `uv sync` → > `ruff` / `pyright` strict / `pytest`), and the anchoring validator is scoped to its > own scenario type so it never touches the stock `receipt_reputation` scenario. Grateful > for another look when you have a moment. Re-opens the work from #54 → #177 (closed by @Skyrider3), rebuilt to address every point raised. This adds an optional **Trust** layer plugin (`capsule_emit`) and a **Payments** adapter backed by [capsule-emit](https://pypi.org/project/capsule-emit/): each receipt is sealed into a verifiable JSONL **capsule ledger**, and reputation is scored only from receipts that still verify against that sealed ledger (a tamper-evident "Gate 3" that `agent_receipts` cannot provide because it has no ledger reference). ## Every rejection point from #177, addressed **1. "The plugin is never installed/registered in CI."** `capsule-emit-nanda` is now a declared **root dependency** (not just a `[tool.uv.workspace]` member), so the plain `uv sync` that CI runs installs it and registers the `nest.plugins.trust` entry point. Verified clean-room: `uv sync` → entry point `['capsule_emit']` → `nest run scenarios/receipt_reputation_capsule.yaml` → ledger written. **2. "The adversarial validator never runs — nothing is registered in `VALIDATORS`."** Registered `validate_receipt_reputation_anchored` in `nest_core.validators.VALIDATORS` under a **new `receipt_reputation_capsule` scenario type** (task mechanics aliased to the `receipt_reputation` factory; validator set = ring-severance + honest-confidence + anchoring), so `validate_trace` now enforces it. It is a real trace validator, not a pytest test: every **signature-valid** receipt observed on the wire must be **anchored** — its independently recomputed RFC 8785 (JCS) content digest must appear as a sealed `agent_input_digest` in the capsule ledger the run produced. It verifies the issuer Ed25519 signature too, so "valid receipt" means signature-valid, not merely well-formed. Proven: - Capsule scenario, `trust: capsule_emit` → **PASS** — "all 29 receipts anchored in capsule ledger". - Same scenario, `trust: agent_receipts` (no ledger) → **FAIL** — the reference plugin genuinely fails our stronger validator (this is the discrimination dhve asked for, not a parity demo). - Tamper-after-seal → **FAIL** (digest no longer matches). - The **stock `receipt_reputation` scenario is untouched** — the anchoring validator is scoped to its own type, so we don't break any existing scenario. The rig now grades the thing being submitted. **3. "The pyright gate was excluded, not passed (`exclude = ["examples"]`)."** Removed the exclude; `examples/capsule-emit` is in pyright's checked set and `testpaths`. All 69 strict errors fixed **by fixing the types** — PEP 561 stub-only packages for the inline-typed-but-un-`py.typed` `capsule_emit` / `agent_action_capsule`, local reimplementation of the stock scoring helpers (so there is no cross-module private access), explicit annotations. **No `exclude`, no `# type: ignore`, no `# pyright: ignore`, no `reportX = false`.** `uv run pyright` → **0 errors** (full repo). **4. "`anchor=True` default → live POST; ledger ordering nondeterministic."** `anchor=False` by default — the graded run does no network I/O — and the ledger write is synchronous. The graded **trace is byte-identical across runs**. (Anchoring is one flag away for real adopters: `anchor=True` posts a digest-only record to the free public transparency log `https://anchor.agentactioncapsule.org/v1/digest` with zero further config; it stays off for the deterministic benchmark.) ## Also harde …
Try it
Open PR on GitHubView diffCheckout locally
git fetch origin pull/197/head:pr-197
git checkout pr-197