v10.0.0-rc.8
Pre-releaselibp2p reachability hardening (capacity / observability / multi-reservation series), tag-triggered npm publishing, agent-to-agent debug chat, Node UI chat panel revamp, and a Base Sepolia 7-contract redeploy. Testnet contract redeploy required — chainResetMarker bumped to v10-profilestorage-paramstore-redeploy-2026-05-14 (already on main since #511); first boot on rc.8 wipes per-node chain-derived state for any operator still on the rc.6 marker. Hub at 0xC056e67Da4F51377Ad1B01f50F655fFdcCD809F6 and Token at 0x2A58BdD13176D85906D804cdbFFA0D9119282DC8 retain their addresses.
Added
- libp2p reachability hardening PR1/3 — Core Node relay capacity + TTLs + operator knob (PR #524,
packages/core/src/node.ts,packages/core/src/types.ts,packages/cli/src/config.ts,packages/agent/src/dkg-agent.ts): Core Nodes now scalecircuitRelayServercapacity byRELAY_CAPACITY_MULTIPLIERso a node advertising itself as a relay actually accepts the reservations it gets dialed for. NewDKGNodeConfig.relayServerCapacityoperator knob (validated byvalidateRelayServerCapacity) lets large-fanout operators scalemaxReservations/maxCircuits/maxOutboundStreams/maxInboundStreamstogether; defaults stay safe for small operators. Reservation TTL extended to 2 h withdefaultDurationLimitof 30 min so long-lived edges aren't churned on every refresh cycle. - libp2p reachability hardening PR2/3 — relay observability (PR #525, new
packages/core/src/relay-metrics-adapter.ts, newpackages/core/src/relay-internal-shapes.ts,packages/core/src/node.ts,packages/node-ui/src/db.ts,packages/node-ui/src/api.ts):RelayMetricsAdapterplugs into libp2p as aMetricsimplementation and counts relay-server bytes by direction viaRELAY_V2_HOP_CODEC/RELAY_V2_STOP_CODECstream tracking (no more guessing from raw connection metadata). New/api/relay/statsendpoint surfaces{ activeReservations, activeCircuits, bytesIn, bytesOut }; values are persisted asrelay_*columns onmetric_snapshotsfor retention. Compatibility helpers (readRelayReservations,readConnectionStreams) validate libp2p internal shapes and returnnullon mismatch so the API reports a visible error rather than silently stale zeros if libp2p ever refactors. Pinned bypackages/core/test/relay-internal-shapes.test.ts(9 cases). - libp2p reachability hardening PR3/3 — edge multi-reservation tuning (PR #526,
packages/core/src/node.ts,packages/core/test/relay.test.ts): edge nodes can now hold multiple parallel relay reservations for redundancy viaDKGNodeConfig.relayReservationCount(default 3, gated to edge nodes that actually haverelayPeers). The relay watchdog enforces per-relay reservation presence when target > 1, with a per-tick forced-redial budget capped atmissingSlotsAtTickStartso a single cycle can't burn through every relay. New canonicalusableRelayCandidatespass deduplicatesrelayPeersby canonical peerId (handles mixed base58btc/base32 encodings), aggregates alternate transports for the same peer ([relayA-tcp, relayA-ws]→ oneRelayTargetwith both addrs), drops self-references, and warns on malformed entries. AutoNAT gating +/p2p-circuitlistener fallback now key offusableRelayCandidates.lengthso a node whose every configured relay is unusable falls back cleanly instead of half-configuring itself. - Agent-to-agent debug chat (PRs #510, #521,
packages/mcp-dkg/src/index.ts, newpackages/agent/src/message-outbox.ts,packages/core/src/protocol-router.ts): MCP exposesdkg_send_message/dkg_check_inbox/dkg_get_chat_history/dkg_list_agentsso two agents on different nodes can exchange threaded messages with ACL enforcement (sender-on-allowlist, no rate-limit bypass).MessageOutboxretries silent-dropped invitee deliveries with per-key inflight guard against duplicate-delivery races;ProtocolRouter.sendre-runspeerResolverper attempt so a stale handle from boot doesn't strand subsequent retries. - Node UI chat panel UX/UI revamp (PRs #503, #504, #505, #516, #528, #529,
packages/node-ui/src/components/chat/**): full chat-panel rebuild — sticky header, custom Select for project switching, drag-and-drop file composer with chip rendering, markdown + syntax highlighting in assistant turns, full-width assistant bubbles, send-button states, hover-revealed timestamps, inline streaming caret, my-projects picker, and a 404-resilient markdown viewer for imported documents. Replaces the legacy chat surface end-to-end. - Tag-triggered npm publishing (PR #522,
.github/workflows/npm-publish.yml,.github/workflows/release.yml): merging tomainno longer publishes anything to npm. Publishing now fires only on signed annotated tags matchingv<major>.<minor>.<patch>(e.g.v10.0.0-rc.8), and only when the tag is reachable frommainorv10-rc, ssh- or gpg-signed, and matches everypackage.jsonversion in the workspace. Thenpm-publishGitHub Environment requires a reviewer (5-minute wait, no self-approval) before any package is pushed. Replaces the previous continuous-publish-on-merge flow.
Fixed
relayServerCapacityvalidator silently accepted unsafe-integer values (PR #530,packages/core/src/node.ts,packages/core/test/relay-capacity.test.ts): the validator usedNumber.isIntegerwhich accepts values aboveNumber.MAX_SAFE_INTEGER(e.g.9007199254740993); multiplying byRELAY_CAPACITY_MULTIPLIERthen silently lost precision and corrupted the libp2p caps. Now usesNumber.isSafeIntegerand a newMAX_RELAY_SERVER_CAPACITYceiling that ensures every derived cap also stays within the safe range.deriveRelayCapsgot the same belt-and-braces check.- Staking-V10:
_convertToNFTleft migrated TRAC stranded inStakingStorage(PR #491,packages/evm-module/contracts/StakingV10.sol): the conviction-NFT conversion path read the migrated balance fromStakingStoragebut never transferred it onward toConvictionStakingStorage, so the underlying TRAC was unrecoverable from either side post-conversion. Now transfers the balance in the same call before minting the NFT. - Staking-V10: operator-fee lookup ignored historical epoch (PR #493,
packages/evm-module/contracts/StakingV10.sol):_getEffectiveOperatorFeeresolved against the latest fee-change rather than the epoch the lookup was for, so reward calculations against past epochs used today's fee. Now binds the lookup to the requesting epoch's timestamp. - Post-approval sync gap hid freshly-joined curated CGs (PR #517,
packages/agent/src/dkg-agent.ts): a window between approval-event arrival and_metareconciliation left the just-joined CG invisible to the invitee until the next periodic sync. Approval handling now triggers an immediate targeted sync of the new CG. - Curator reject-reason was hidden in
JoinProjectModal(PR #508,packages/node-ui/src/components/.../JoinProjectModal.tsx): the modal swallowed thereasonfield onJOIN_REQUEST_REJECTED, leaving operators with a generic "rejected" UI. Now surfaces the curator's explicit reason string. - Axiom-4 trust upgrades (PR #523): hardened trust-upgrade endpoint inputs, bounded the verify-collection timeout, fail-closed on non-quorum verify, and aligned devnet trust paths with the new gating. Companion devnet sections cover the regression surfaces.
npm-publishjob missed hidden.publish-artifactsupload (PR #515,.github/workflows/npm-publish.yml): renamed to non-hiddenpublish-artifactssoactions/upload-artifactincludes it; preceded #522 (tag-triggered publishing) and unblocked the new flow.
Changed
- Base Sepolia (chainId 84532): 7 contracts redeployed off
main@7235e669(PR #511,packages/evm-module/deployments/base_sepolia_v10_contracts.json): refresh of theProfile/ProfileStorage/ParameterStoragefamily + the staking-V10 contracts that needed the #491 / #493 fixes deployed. New addresses are committed tobase_sepolia_v10_contracts.json; agents discover them viaHub.getContractAddress(...)at runtime so nonetwork/testnet.jsonedit was needed beyond thechainResetMarkerbump (v10-rc6-pca-author-attestation-2026-05-10→v10-profilestorage-paramstore-redeploy-2026-05-14). Hub + Token addresses preserved.
Note: this release was published to npm manually due to a workflow bug (#532) that blocked the tag-triggered CI publish. All 15 public packages are at 10.0.0-rc.8 under the rc dist-tag. Future releases will go through the proper signed-tag CI flow once #532 lands.