#!/usr/bin/env bash # Builds identity-episode13/ — a disposable repo demonstrating real # per-agent Ed25519 identity injection for Episode 13 ("Agents Are # First-Class Citizens"). Re-run to regenerate; never hand-edit the repo # directory itself. set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO="$HERE/identity-episode13" rm -rf "$REPO" mkdir -p "$REPO" cd "$REPO" muse init --json | python3 -m json.tool echo "hello" > README.md muse code add README.md muse commit -m "Initial commit" --agent-id claude-code --model-id claude-sonnet-5 --json | python3 -m json.tool echo echo "=== Deriving an operator identity and a scoped agent sub-seed ===" python3 - <<'PY' import os import sys sys.path.insert(0, "/Users/gabriel/ecosystem/muse") from muse.core.hdkeys import ( derive_agent_sub_seed, derive_identity_key, DOMAIN_IDENTITY, ENTITY_HUMAN, ) from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey # Throwaway 64-byte seed for this demo -- never a real operator mnemonic. operator_seed = os.urandom(64) operator_dk = derive_identity_key(operator_seed, entity_type=ENTITY_HUMAN) operator_priv = Ed25519PrivateKey.from_private_bytes(operator_dk.private_bytes) operator_pub = operator_priv.public_key().public_bytes_raw() # Scoped sub-seed for agent slot 0 -- SLIP-0010 hardened, cannot derive # the operator's own key or any other domain's keys. agent_sub_seed = derive_agent_sub_seed(operator_seed, domain=DOMAIN_IDENTITY, agent_id=0) print("operator pubkey:", operator_pub.hex()) with open("sub_seed.bin", "wb") as f: f.write(agent_sub_seed) PY echo echo "=== Injecting the sub-seed through a real pipe fd (never an env var) ===" muse code add README.md 2>/dev/null || true echo "hello v2" > README.md muse code add README.md python3 - <<'PY' import os import sys with open("sub_seed.bin", "rb") as f: sub_seed = f.read() assert len(sub_seed) == 64 read_fd, write_fd = os.pipe() os.set_inheritable(read_fd, True) pid = os.fork() if pid == 0: os.close(write_fd) env = dict(os.environ) env["MUSE_AGENT_KEY_FD"] = str(read_fd) env["MUSE_AGENT_HANDLE"] = "agent-slot-0" os.execvpe("muse", ["muse", "commit", "-m", "Agent-signed commit via pipe fd", "--agent-id", "claude-code", "--model-id", "claude-sonnet-5", "--sign", "--json"], env) else: os.close(read_fd) os.write(write_fd, sub_seed) os.close(write_fd) _, status = os.waitpid(pid, 0) sys.exit(os.waitstatus_to_exitcode(status)) PY echo echo "=== Confirming the agent's key is real, unique, and verifies ===" muse read --json | python3 -c "import json,sys; print('signer_public_key:', json.load(sys.stdin)['signer_public_key'])" muse verify-commit HEAD --json | python3 -m json.tool rm -f sub_seed.bin echo echo "=== The provenance-vs-cryptography distinction, across the real season ===" cd ~/ecosystem/muse muse shortlog --group-by model --json | python3 -c " import json, sys d = json.load(sys.stdin) for g in d['groups']: print(f\"{g['key']:<20} {g['count']}\") " echo "Demo repo built at $REPO"