You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adversarial pass on the funds-moving code — no exploit, 3 hardening fixes. A
review of the $LH-moving paths (CLI send/redeem/the per-request meter
funding + the x402 /mcp proxy) confirmed no exploitable bypass or fund
theft (the x402 gate, EIP-712 digest, replay/nonce, payment-redirection all
verified safe). Fixed: (1) $LH transfers to the zero address are now refused
— 0x0…0 is valid 40-hex and would irrecoverably burn funds; the shared classify_recipient choke point protects CLI send, the browser send_lh tool,
and mcp-call; (2) the proxy rejects high-s x402 signature malleability
(the contract rejects high-s, so the proxy was "verifying" a malleated auth then
submitting a doomed settle — wasted gas + a confusing 402); (3) a uint256
overflow guard in the proxy's EIP-712 digest reconstruction. +12 hostile-input
tests (amount parsing, recipient classification, calldata layout, discover rank).
Daily $LH allowance disabled (setDailyAllowance(0), on-chain). It was a
sybil hole — free sponsored registration × a free daily mint = unbounded credits
across throwaway accounts. The CreditsFacet stays cut/wired (re-enable by
setting an allowance); credit funding is now the controlled paths — redeem codes
agent-to-agent send_lh — until Tempo mainnet adds real ETH/USD + Stripe.
Free sessions closed (setSessionPrice(1e18), was 0). The credit proxy
gates on an active session OR a meter balance; with sessionPrice=0any
sponsored account could openSession() for free → free Gemini/Claude with no
redeem code, defeating the gate above. Sessions now cost 10 $LH/hr, so both
proxy paths require $LH. Consequence: call / browser chat now need funding
(redeem / send_lh) for unfunded identities. Reversible (setSessionPrice(0)).
Fixed
Contract: register() validates names as DNS labels (1-63) — was wrongly
3-32. The deployed LocalharnessRegistryFacet's _isValidName bound (3-32)
didn't match the CLI's name_is_valid (1-63), so 33-63-char names the CLI
accepts were rejected on-chain (and a direct contract call could otherwise mint
unreachable "ghost" names). Corrected to mirror the Rust rule exactly; reverts InvalidName before any mint. Cut live (surgical Replace of register; +12
Foundry tests). juno-qa fleet feedback.
call now pays PER REQUEST, not by the hour. A headless call to another
agent was opening a coarse SessionFacet session (now 10 $LH/hr,
all-you-can-use) just to make one request — wasteful + wrong semantics. It now
funds the per-request CreditMeterFacet (the proxy debits ~0.01 $LH/call),
topping up a small buffer (~20 calls) only when the meter can't cover a call.
Proven live: a fresh identity's call left sessionExpiry=0, meter 0.19, a 1000× cost drop (0.01 vs 10 $LH). The session command still opens a
session for interactive all-you-can-use windows.
Added
Hosted MCP-over-HTTP endpoint gated by true x402 (proxy/api/mcp.ts, live
at /mcp) — the networked counterpart to the stdio localharness mcp. A remote
MCP client calls ask_agent(name, message) and settles per-call in $LH over
REAL x402: the EIP-712 PaymentAuthorization is verified against the live x402DomainSeparator() (typehash + raw-digest ecrecover mirror registry::x402_digest), payee = the target agent's TBA, used/expired nonces
rejected (authorizationState), then X402Facet.settle(...) is submitted and
the receipt awaited before the agent runs. Persona-aware. Crypto cross-checked
against the pinned Rust domain-separator vector.
send_lh agent tool — transfer real $LH to a subdomain's owner or a raw 0x… address from natural-language chat (the "Bankr-style" wallet-control
capability). Resolves a name → on-chain owner; sponsored ERC-20 transfer from
the owner's wallet; owner-only, not granted to subagents; amount must be > 0.
Colony rung-2: verify-gated issue→PR harness (scripts/issue-to-pr.sh) —
turns a GitHub issue into a pull request that opens ONLY IF scripts/verify.sh
passes (the immune system that makes an agent-authored change trustworthy).
Fix-generation is pluggable via $FIX_CMD; never an empty PR or a PR on red.
localharness mcp-call + redeem CLI commands.mcp-call [--as me] [--pay amt] <target> <message> is the client for the hosted /mcp x402 endpoint —
signs the payment, auto-approves the diamond, calls the agent, prints the reply
(proven live end-to-end: a 0.001 $LH settlement returned a real answer and
the wallet decremented on-chain). redeem <code> mints $LH into the caller's
wallet (the funding path now that the daily allowance is off).
Tiered redeem codes (scripts/add-redeem-codes.sh, 10 / 100 / 1000 $LH) —
owner tool that generates + registers redeem codes (hashing matches RedeemFacet.redeem; plaintext stays gitignored, only hashes go on-chain).
CLI send + session — send [--as me] <recipient> <amount> transfers $LH to a 0x… address or a name's owner (the native twin of the browser send_lh — agent-to-agent funding, same effect as a redeem code); session
opens a proxy session (spends sessionPrice$LH). Both proven live. Completes
the CLI funding surface (redeem → wallet; send → fund others; session/topup →
access; mcp-call → x402).
Actor model on subdomain creation — create_subdomain(name, persona?, prefund_lh?) + create_and_publish_app(name, source, persona?, prefund_lh?):
spawn a new agent WITH its on-chain persona + $LH operating funds (to its TBA)
in one sponsored call. Backward-compatible.
No-$LH onboarding banner — a credits-mode identity holding zero $LH now
sees a clear "redeem a code to start" CTA above the prompt (self-clears once
funded); the ?invite=CODE flow reconciles the funded state on landing.
Invite system deep-plan (design/invites.md, design only) — a permissionless InviteFacet: escrow your own $LH to back a tiered bearer code, expiry refunds
the funder, supply-neutral (no sybil hole).
Agent discovery (discover) — localharness discover <query> + a browser discover_agents(query) tool search the on-chain registry by capability (name +
persona match, ranked), so a coordinator agent can FIND a peer then call / mcp-call it — the A2A "Agent Yellow Pages" (sol-qa fleet feedback). Proven
live: claude discovered a "security" agent and called it.
Agent-scheduling deep-plan (design/agent-scheduling.md, design only) — an
on-chain ScheduleFacet (job + escrowed $LH budget survives any tab dying) +
a Vercel-Cron worker on the proxy firing due jobs through the headless call
path, with budget-bounded recursion for "agent ping-pong". Bakes /loop + /schedule into the agents themselves.
Changed
README reframed around the "one identity, many faces" model (browser / CLI
/ MCP / agent↔agent all reach the same loop + the same on-chain identity) and
modernized (0.25, Gemini + Claude, x402/wallet rails).