proof-aware-crypto-tooling-.../notebooks/07_agent_consequences.ipynb
mrwulf 4a37da8fd9 Curriculum: the ratchet rule, the four-tier reality, and lecture 9 (dogfood)
The notebooks now carry the same didactic contract as the companion book
(the "ratchet rule", stated in the course map): every load-bearing idea
runs twice - napkin scale, then real scale - and every pair is EXECUTABLE
in the notebook, not narrated.

- Lecture 1: the truth boundary updated to the proven four-tier apex,
  with the what-is-still-NOT-proven list (SHA-512, parsers, signing,
  wallets) given equal weight.
- Lecture 2: napkin/real scoring pair - a two-certificate toy card
  scored in your head, then the shipped sixteen-certificate R4 fixture
  through the same function, residual blockers and per-tier boundary
  axioms printed.
- Lecture 6: new split-view section. A runnable equivocation drill:
  pin a two-leaf view, grow it honestly with a consistency proof, then
  present a forged same-size root and watch the pin store name the
  attack. Real-scale pointers to --sth-store, log-consistency,
  log-audit, and the freshness policy; a new exercise asks students to
  construct the lie a size-only anchor check would miss.
- Lecture 7: the wallet gate now swings BOTH ways on real evidence -
  a partial card denied at R3, the shipped R4 card allowed - both
  runnable.
- Lecture 8 capstone: "design R4" became "audit R4": read the shipped
  card like an auditor, then design the R5 discharge plan (parser
  specs, verified SHA-512, signing-side, per-fork production-path
  mapping).
- NEW Lecture 9, "Eat Your Own Dogfood": the honest coverage ledger of
  the proven-path verifier; a napkin PEM decode (the fixed 12-byte
  Ed25519 SPKI prefix, read with your eyes) paired with the mechanical
  extraction; live backend dispatch; the fail-closed
  --require-verified-verifier policy; and the hybrid-PQC section -
  proven-classical Ed25519 plus a required-but-honest ML-DSA slot
  ("blockers get fixed; placeholders get trusted").

Every code cell of the changed notebooks was executed end-to-end before
committing (outputs stripped per house rules). 49/49 tests green with
the notebook inventory updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:18:06 +02:00

221 lines
8.8 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Lecture 7: Agent Consequences\n",
"\n",
"An evidence interpreter is incomplete if nothing changes after evaluation. PACTA has a small consequence engine: it can build a lower-layer Rust decision capsule when evidence satisfies policy, and it refuses wallet construction when coverage is insufficient.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Learning Objectives\n",
"\n",
"- Explain how risk levels map to actions.\n",
"- Run a dry-run agent action.\n",
"- Understand the generated Rust capsule.\n",
"- Explain why R3 permits lower-layer use but denies wallet demos.\n",
"- Run the gate both ways: a partial (arithmetic-only) card is denied; the full four-tier card is allowed.\n",
"- Connect transparency receipts to build authorization.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Action Policy\n",
"\n",
"Current actions:\n",
"\n",
"- `build-library`: default threshold R3. Produces a proof-gated component capsule.\n",
"- `build-wallet-demo`: threshold R4. Writes a denial artifact below R4 - and since the corpus completed its four-tier apex, R4 evidence EXISTS, so this gate can now legitimately open. Watch it swing both ways below.\n",
"\n",
"This is deliberately conservative. The theorem boundary for Ed25519 field plus Edwards arithmetic is valuable, but it does not cover key custody, encoding, hashing, scalar arithmetic completeness, signature verification, transaction construction, or market decisions.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pathlib import Path\n",
"import sys\n",
"\n",
"repo_root = Path.cwd()\n",
"if not (repo_root / \"src\" / \"pacta\").exists():\n",
" repo_root = repo_root.parent\n",
"sys.path.insert(0, str(repo_root / \"src\"))\n",
"\n",
"from pacta.agent import run_agent_action\n",
"from pacta.claims import build_claim_card\n",
"from pacta.config import load_config\n",
"\n",
"repo = load_config(repo_root / \"examples\" / \"repos.yaml\").repo_named(\"dalek-ed25519-verified\")\n",
"card = build_claim_card(repo, repo_root / \"repos\" / repo.name, offline_fixture=True)\n",
"\n",
"library_decision = run_agent_action(card, \"build-library\", repo_root / \"artifacts-notebook\", dry_run=True)\n",
"wallet_decision = run_agent_action(card, \"build-wallet-demo\", repo_root / \"artifacts-notebook\", dry_run=True)\n",
"print(library_decision.to_dict())\n",
"print(wallet_decision.to_dict())\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# NAPKIN: an arithmetic-only card faces the wallet gate - DENIED.\n",
"from pathlib import Path\n",
"import sys, tempfile\n",
"\n",
"repo_root = Path.cwd()\n",
"if not (repo_root / \"src\" / \"pacta\").exists():\n",
" repo_root = repo_root.parent\n",
"sys.path.insert(0, str(repo_root / \"src\"))\n",
"\n",
"from pacta.agent import run_agent_action\n",
"from pacta.risk import score_claim_card\n",
"\n",
"partial = {\n",
" \"component\": \"napkin-arithmetic-only\",\n",
" \"kind\": \"ed25519\",\n",
" \"certificates\": [\n",
" {\"name\": \"CurveFieldProofs.fieldImplementation\", \"status\": \"proven\", \"axiom_status\": \"clean\"},\n",
" {\"name\": \"CurveFieldProofs.edwardsImplementation\", \"status\": \"proven\", \"axiom_status\": \"clean\"},\n",
" ],\n",
" \"exclusions\": [\"full EdDSA signature verification\"],\n",
" \"meta\": {\"r4_requirements\": []},\n",
"}\n",
"partial[\"risk\"] = score_claim_card(partial).to_dict()\n",
"with tempfile.TemporaryDirectory() as tmp:\n",
" decision = run_agent_action(partial, \"build-wallet-demo\", tmp, dry_run=True)\n",
" print(\"allowed:\", decision.allowed, \"at\", decision.risk_level)\n",
" print(decision.rationale)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# REAL: the shipped four-tier R4 card faces the same gate - ALLOWED\n",
"# (a demo scaffold only; the residual blockers ride along in the card).\n",
"from pacta.yamlio import load_data\n",
"\n",
"full = load_data(repo_root / \"examples\" / \"dalek-ed25519.claims.yaml\")\n",
"with tempfile.TemporaryDirectory() as tmp:\n",
" decision = run_agent_action(full, \"build-wallet-demo\", tmp, dry_run=True)\n",
" print(\"allowed:\", decision.allowed, \"at\", decision.risk_level)\n",
" print(decision.rationale)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The Rust Capsule\n",
"\n",
"The generated capsule is not cryptographic code. It is a consumable policy artifact. It embeds the claim card and exposes constants such as:\n",
"\n",
"- component,\n",
"- repo URL,\n",
"- kind,\n",
"- verified backend,\n",
"- risk level,\n",
"- evidence mode,\n",
"- attestation provider,\n",
"- deployment constraints.\n",
"\n",
"Downstream automation can import this crate and check `allowed_for_lower_layer_crypto()` before enabling a code path.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pacta.artifact import _lib_rs\n",
"\n",
"print(_lib_rs(card).splitlines()[:24])\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Receipt-Required Builds\n",
"\n",
"The strongest dogfood path in this prototype is:\n",
"\n",
"1. Provider replays Lean and signs attestation.\n",
"2. Provider appends attestation to a Merkle transparency log.\n",
"3. Provider emits an inclusion receipt with Signed Tree Head.\n",
"4. Agent verifies provider signature, receipt inclusion proof, and STH signature.\n",
"5. Agent builds only if risk and transparency policy pass.\n",
"\n",
"This transforms \"I read a report\" into \"I accepted a logged, signed proof-check result and acted within its theorem boundary.\"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Command-Line Lab\n",
"\n",
"Run these from the repository root after generating a provider attestation:\n",
"\n",
"```bash\n",
"pacta receipt-verify \\\n",
" --attestation provider/out/dalek-ed25519.attestation.yaml \\\n",
" --receipt provider/out/dalek-ed25519.receipt.yaml \\\n",
" --log-public-key provider/state/local-provider/provider.ed25519.pub\n",
"\n",
"pacta agent \\\n",
" --config examples/repos.yaml \\\n",
" --repo-name dalek-ed25519-verified \\\n",
" --repo repos/dalek-ed25519-verified \\\n",
" --attestation provider/out/dalek-ed25519.attestation.yaml \\\n",
" --trust-attestation-provider local-pacta-provider \\\n",
" --attestation-public-key provider/state/local-provider/provider.ed25519.pub \\\n",
" --transparency-receipt provider/out/dalek-ed25519.receipt.yaml \\\n",
" --transparency-log-public-key provider/state/local-provider/provider.ed25519.pub \\\n",
" --require-transparency-receipt \\\n",
" --action build-library\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exercises\n",
"\n",
"- Modify a claim card to R2 and show that `build-library` is refused.\n",
"- Explain why a denial artifact is useful for auditability.\n",
"- Design a policy where an agent requires `both` Ed25519 and ML-DSA signatures for production deployment but allows Ed25519-only in a local lab.\n",
"- Write a downstream Rust pseudo-code snippet that imports the generated capsule before enabling a code path.\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}