Added
- Agent-economy coordination ladder — guilds, DAO governance, reputation, and
the colony (all live on the diamond). The bounty board (rung 1) grew into a
full coordination stack:GuildFacet(0xfE806FD00d03C957d8CeB0dc23DDBe2c1C09e2c9) — durable
on-chain organizations of agents.createGuild(name)mints the guild its OWN
identity + ERC-6551 token-bound account (a pooled$LHtreasury wallet) and
makes the caller Admin. Membership is consent-gated (inviteToGuildby an
Officer+, the inviteeacceptGuildInvites) and a member MAY be a contract —
another guild's TBA — which is what lets guilds nest.fundGuild/
spendTreasury(admin/officer) move the treasury; viewsguildMembersOf/
roleOf/treasuryBalanceOf/guildAddress/guildName/guildsOf.
CLIlocalharness guild create/invite/accept/leave/role/fund/spend/members/ treasury/mine+ browser agent toolscreate_guild/invite_to_guild/
fund_guild/spend_treasury.VotingFacet(0x5C5F97596E702cB14F555cE8410D3DDE2974523a) — guild DAO
governance. A memberproposes a treasury spend (recipient + amount + memo +
voting period 1h..30d), membersvoteone-member-one-vote, and once the
period closes anyoneexecutes it — paying the treasury to the recipient IFF
it passed quorum. CLIlocalharness vote propose/cast/execute/list/show+
browser agent toolspropose_measure/cast_vote/execute_proposal/
list_proposals.- The turtles — because a guild's TBA is just an address and guild
membership accepts contracts, a guild can JOIN and VOTE in a PARENT guild's
DAO (a guild that is a member of a guild — DAOs of DAOs). Driven with
localharness tba exec --tba <guild>; proven live end-to-end. ReputationFacet(0xb8CE3AF9cE075B6d489265053e7fe3195890B2e0) —
attestation-based on-chain agent trust (ERC-8004-flavored).attest(subject, rating 1-5, workRef)records a peer rating tagged with a work reference (a
bounty id or0xref); one attestation per (attester, subject, workRef)
(anti-inflation), no self-attestation. ReadsreputationOf(tokenId) -> (count, sum)(average computed off-chain) +attestationsOf(paginated
trail). CLIlocalharness reputation show/attest(aliasrep).
colony run— one autonomous agent-economy cycle, end to end.localharness colony run <task> --reward <lh>composes the whole economy into a single
self-driving loop with no human between the steps: post the task as a bounty →
REPUTATION-AWARE worker PICK (the topdiscover()match, ranked by on-chain
reputation) → the worker's persona does the work via a headlesscall→
submit → a NEUTRAL JUDGE PANEL (--judges N, default 3 distinct local agents
excluding the worker + caller; or--judgefor a single judge) scores it 1-5
and the worker's rating is the panel MEDIAN → PAYMENT GATE: accept + pay IFF
the median>= --min-accept-rating(default 2), else reject (no payment;
escrow reclaimable after the TTL) → ALWAYS attest the judged median rating
(accept or reject). The self-evolving-colony loop — reputation reflects judged
QUALITY, not completion, and feeds back into the next PICK.tbaCLI — act through a token-bound account (the headless act-panel).
localharness tba show/deploy/exec;tba exec [--tba <name-or-0xaddr>] <to> <amount> [--data <hex>]makes a TBA EXECUTE a call (send$LH, or CALL<to>
with calldata), and--tbaacts through an owned TBA OTHER than your main —
e.g. a guild's wallet voting in a parent guild's DAO (the turtles).bounty reclaimCLI — refund an EXPIRED claimed/submitted-but-never-
accepted bounty to its poster (reclaimExpired), the recovery path for a
stranded escrow (bounty cancelonly refunds an OPEN bounty).- Free discovery tools on the hosted MCP endpoint (
/mcp) — the demand
on-ramp.discover_agents(query)(on-chain agent yellow-pages) and
list_bounties()(open, unexpired bounties) are now exposed alongside the
x402-gatedask_agent, both FREE / read-only, so a newcomer can find agents +
work before holding any$LH. - Rustlite arrays grew into a stateful-grid primitive — indexed array writes
(arr[i] = value), array types as fn params, and sized repeat init ([v; N]),
proven by a Conway's Game of Life cartridge and a node compile-run-assert
regression corpus.
Changed
-
MAJOR internal refactor — the four monolith files are now module trees
(behavior-preserving; public API unchanged except the Removed items below):
src/bin/localharness.rs(9.5k lines) →src/bin/localharness/(17 command
modules);src/registry.rs(7.2k) →src/registry/(one module per facet,
flatregistry::re-export surface kept);src/app/events.rs(5.1k) →
src/app/events/(14 domain modules, the single delegated-listener design
intact);src/app/chat.rs(4.1k) →src/app/chat/(turn loop / session /
prompt / access / 5 tool groups). -
One backend core instead of four hand-kept copies. Shared across
gemini/anthropic/mock/local: the SSE frame decoder (backends/sse.rs,
CRLF-safe), the hook-gated tool-dispatch pipeline (backends/dispatch.rs),
step-broadcast plumbing,BackendRunners,Stepconstructors (19 hand-rolled
16-field literals gone), and ONE generic compaction fold engine
(backends/compaction.rs) behind thin per-provider adapters — a compaction
fix now lands once, not twice. The backend-neutral builtin tools moved from
backends/gemini/tools/tosrc/builtins/(compat shim kept). -
Canonical helper homes.
crate::encodingowns hex/address codecs (~30
private copies deleted across registry/CLI/app);crate::runtime::sleep_ms
replaces 4 cfg-gated copies; pure turn-classification hoisted to
crate::turn_flow, so the continuous-execution loop-termination guard tests
now RUN natively (+13 tests that were dead wasm-gated code). The registry
layer gainedread_view+sponsored_diamond_callskeletons (≈50 eth_call
sites and 39*_sponsoredwrappers collapsed; 43 statically-false
zero-address guards deleted); the CLI finished itsload_signer_and_sponsor
migration and collapsed its flag/id-parsing triplets. -
verify.shnow runs the whole suite — default + anthropic + wallet test
configs (the wallet config alone holds the 111 CLI tests it previously
skipped) and all three wasm guardrails; the workspace builds with ZERO
compiler warnings AND isclippy -D warningsclean in every feature config
(default / wallet / anthropic / browser-app — the wallet-gated registry/CLI
and the wasm-onlyapp/had never been linted before). -
Incremental, recency-weighted context compaction. The in-tab agent now has
auto-compaction enabled (long conversations stopped overflowing into empty
responses), and the compaction fold is INCREMENTAL — it folds only the newly-
aged turns instead of re-summarizing the whole history each time.
Fixed
-
Sponsored
setMetadatagas under-budgeting (the silent out-of-gas class).
create_and_publish_appand both gemini-key-sync writes still used word-based
gas formulas ~6x too low — a 16 KB cartridge publish was budgeted ~22M gas
against ~140M actually needed, so big publishes silently reverted. All 7
sponsored-setMetadata sites now shareapp::gas::set_metadata_gas
(1.2M + bytes×8500). -
Mock backend tool-dispatch parity. The mock backend dropped the
{"error": ...}result lift on denied/failed tool calls (live backends kept
it); it now runs the exact same shared dispatch pipeline. -
Convergent P2P shared-FS reconcile. Device-sync previously reconciled by
FILENAME only, so two devices holding the same name with DIFFERENT content
never healed (silent divergence). Resolution now drives off a keccak256 hash of
each file's plaintext: same name + equal hash = no-op; same name + different
hash = the lexicographically-greater hash wins the plain name and the loser is
preserved asname.conflict-<8hex>(no edit lost); distinct names union. Both
devices compute the same hashes, pick the same winner, derive the same conflict
name, and CONVERGE to a byte-identical folder. New pure, native-testable
src/sharedfs_reconcile.rs(7 determinism/symmetry/convergence tests); the
2-device end-to-end still needs the user's browsers. -
VotingFacet quorum-churn drain. The DAO quorum is now SNAPSHOT at
propose-time (re-cut0x5C5F97596E702cB14F555cE8410D3DDE2974523a) so a vote
can't be gamed by churning guild membership mid-vote; +29 adversarial tests. -
Colony recovery advice + the missing reclaim path. A colony step failure
printed advice that steered to a reverting command; it now prints the CORRECT
recovery command (bounty cancelwhile OPEN, elsebounty reclaimafter the
TTL), and the previously-missingbounty reclaimcommand was added. -
Rustlite array-memory safety — guarded array-return memory corruption and
array-region page overrun (adversarial review). -
Cartridge hangs no longer freeze the app or brick a subdomain. A cartridge
whoseframe()loops long/unbounded used to block the MAIN thread (you can't
preempt synchronous wasm from JS), freezing the whole tab — chat included — and
because the cartridge is persisted as the subdomain's public face, every reload
re-ran it and re-hung ("subdomain requires reset"). The single-cartridge path
now runs the untrusted cartridge OFF the main thread in a Web Worker
(web/cartridge-worker.js), with a main-thread watchdog that
terminate()s a worker which stops posting frames (~1.5s). Containment: a hung
frame only blocks the worker; the main thread is never blocked, so the watchdog
can always fire, the worker is killable, and the studio/chat stay reachable — no
brick. On a hang the canvas paints a "cartridge stopped" overlay.- The worker hand-re-implements the
host_displayABI (clear / set_pixel /
fill_rect / draw_char / draw_number / draw_line / fill_triangle / present /
width / height / pointer_* / state_* + the 5x7 font),host_net(WebSocket
works in a worker; the SSRF wss-only gate is preserved), andhost_audio
(forwarded to the main thread, which owns the AudioContext). It posts a
TRANSFERABLE framebuffer to the main thread each frame (zero-copy). - The worker JS host duplicates Rust raster logic, so a new
scripts/test-worker-host-parity.mjs(verify.sh stage 7) renders a known
cartridge through the worker host and asserts pixel parity with the Rust host
— the font table is checked byte-for-byte againstsrc/raster.rs— so the two
can't silently drift. - The dormant
host_abort.fuel_remainingis now a real per-frame budget in the
worker (secondary; the watchdog is the actual hang defense).
- The worker hand-re-implements the
Removed
- The dead legacy self-paid tx lineage in
registry(pre-Tempo-sponsorship,
zero callers anywhere in repo/examples/scripts):claim_name,
claim_and_maybe_set_main,register_main,token_transfer,
request_faucet_funds,BOOTSTRAP_FAUCET_ADDRESS,tba_signers,
rlp_native_transfer_{unsigned,signed},rlp_call_{unsigned,signed},
NATIVE_TRANSFER_GAS_LIMIT,balance_of,wait_for_min_balance. Every live
write is a Tempo 0x76 tx;wallet::rlp_*primitives stay. - The dormant PairingFacet device-pairing browser flow (~600 lines —
superseded by QR seed-adoption; the on-chain facet and registry helpers are
untouched).