Critical truthfulness defect found by review: README.md's security notice claimed, in
unconditional present tense, that "the non-custodial migration is complete... No tool on this
hosted server accepts a mnemonic... this server never holds one" - sitting directly below the
README's own mainnet hosted-URL connect example. Per docs/architecture/non-custodial-split.md's
own rollout section, mainnet stays on its last custodial image until a separate, deliberate
cutover deploy ships - and nothing on this branch (or the two PRs it stacks on) has even merged
yet. A reader who followed the mainnet connect line and trusted the notice as written would be
told something the repo's own architecture doc directly contradicts. The rewrite had also
dropped the prior notice's hedge ("prefer self-hosting until the migration completes") and
replaced it with a strictly stronger, zero-caveat claim - the exact failure mode this migration
exists to prevent, reproduced at the documentation layer.
Fixed by rescoping every claim to the codebase and adding an explicit deployment-status caveat:
- README.md: added a deployment-status note directly beneath the hosted-servers URL table
(before the connect command), stating plainly that testnet auto-deploys from main but mainnet
stays on its last custodial image until a separate cutover deploy, and to treat the mainnet
instance's signing tools as custodial until then. The security notice itself now says "as of
this release, the non-custodial migration is complete in this codebase" and "no server running
this release ever holds one," with an explicit closing line that this is a claim about the
code, not about every deployment of it. The "Local signer" section got the same rescoping
(it made the identical unscoped claim). The Self-Improvement Module features bullet was also
adjusted: it had "all keyless" sitting directly next to a pre-existing "(live on Vector
mainnet)" parenthetical, risking the same conflation between the on-chain module's blockchain
deployment and this codebase's MCP-server code state - now stated as two separate facts.
- packages/signer/README.md: the "keyless across the board" pairing-status bullet and the
"keeps your mnemonic off the hosted server" closing line both rescoped to "in this codebase" /
"off any server running this release," each with an explicit note that the mainnet hosted
instance is not yet running this release.
- .superpowers/sdd/pr9-body.md (gitignored, not part of this commit): opening paragraph and the
stacked-PR timing note both updated with the same scoping - merging this PR does not deploy
it anywhere, and the mainnet cutover is a separate future step.
Grepped the tree afterward for other unscoped "hosted server ... keyless"-class claims: found
none beyond what's fixed above. Pre-existing, unrelated mentions of "hosted server" in
docs/architecture/non-custodial-split.md (the historical problem statement) and README.md (a
self-hosting logistics note) were checked and left alone - correctly scoped by their own
surrounding context already.
README, packages/signer/README.md, docs/VECTOR.md, and docs/architecture/non-custodial-split.md
updated for the family-3 (self-improvement) keyless migration - the last of the three families
this migration ever touched:
- README: security notice rewritten as the migration-complete statement (zero tools accept key
material, every signing operation happens on the local signer, enforced by the now-empty,
size-zero-pinned custody boundary allowlist); tool count 23 to 24; Self-Improvement Module
table replaced with browse/analyze plus the four build_* rows, the two-step proposal pair
marked as two transactions, agent-orchestrated; features and safety copy updated to
signer-owned spend limits everywhere; Configuration table's three dead spend-limit/audit-log
rows removed (nothing reads those env vars any more); Safety Layer box removed from the
architecture diagram entirely (box-drawing alignment verified programmatically, not by eye);
Testing section names tier-1 vs gated E2E vs LEGACY_FULL for all three keyless families
including their stake costs.
- packages/signer/README.md: pairing-status bullet and closing line rewritten - all four
families are keyless now, this signer is the single signing point, nothing is left open.
- docs/VECTOR.md: four new tool sections for the self-improvement build_* family (this doc never
documented self-improvement under any name before, so these are additions, not renames - same
situation as the registry family in the prior PR's docs task); Safety Controls section's
custodial-family list corrected to reflect that none remain.
- docs/architecture/non-custodial-split.md: family-3 landed marker on the PR-sequence table,
plus the four content-alignment fixes pre-assigned to this PR by
rehaul-handoff-2026-07-30-content-alignment.md (the "governance" to "self-improvement" renames
in the two-step-flow heading, the "last family" sentence, the family table label, and the
rollout row), plus the "Float -> bigint amount math" wording fix.
- .env.example: verified Task 5's edit already states the migration-complete scope correctly
with a pointer to packages/signer/README.md; no further change needed.
Content rules followed for all new copy in this commit: no "governance" (GOV_* env-var names
exempted, pre-existing deployed config keys), no em dashes, no "funds", research-themed
examples where new examples were needed. Caught and fixed one self-introduced violation before
committing: docs/VECTOR.md's four new tool sections initially copied the file's own pre-existing
em-dash-based parameter-bullet convention; replaced with colons in exactly those new lines,
verified zero em dashes remain in the added range.
README.md Testing section claimed registry-keyless.test.ts (tier-1) builds "all five
agent-registry build_* tools" - false. Verified directly against the test source: it
successfully builds and CBOR-checks only register and message; update appears solely on
its non-owner-rejection path (no CBOR extracted); transfer and deregister don't appear in
the file at all - both are covered by the gated E2E suite and the legacy suite instead.
Reworded to state exactly what tier-1 covers and point the full lifecycle claim at the E2E
suite, where it's actually true.
docs/architecture/non-custodial-split.md:137 ("Builder — 24 tools, zero keys") is the
doc's original full-migration target table, easy to misread as current-state next to
README's "23" today. Added "at full migration" so it can't be read as stale.
Checked pr7-body.md for the same all-five-tier-1 claim per the reviewer's note - it does
not repeat it (the Tier-1 bullet only states the 6/6 pass count, no per-tool breakdown),
so no change needed there.
README, .env.example, packages/signer/README.md, and docs/architecture/non-custodial-split.md
updated for the family-2 keyless migration (agent-registry build_* tools, no mnemonic
parameters): security notice narrowed to name the Self-Improvement Module as the only
remaining custodial family; agent-registry tool table renamed to the five build_* rows;
features bullets, self-hosting copy, Configuration/spend-limit scope notes, and the
architecture diagram's Safety Layer footnote all updated to "self-improvement only"; signer
README's pairing-status bullet and closing line extended to cover wallet/tx/contract AND
agent-registry; architecture doc's PR-sequence table marks family 2 as landed.
docs/VECTOR.md gains five new tool sections (register/update/transfer/deregister/message) -
this doc never documented the registry family under any name before, so these are additions
rather than renames; keyless framing (changeAddress, no mnemonic, unsigned CBOR + 4-call flow)
matches the style of the existing wallet/tx/contract sections. Safety Controls section's
custodial-family list also corrected to self-improvement only.
Four items from the final whole-branch review, all docs-only:
1. Architecture diagram: the ASCII diagram routed every tool call through
Rate Limiter -> Safety Layer -> Lucid/Ogmios, which is false for the
keyless build_* path (safety.ts is never consulted there). Annotated the
Safety Layer box with a footnote marker instead of redrawing the diagram -
box alignment verified programmatically before and after (same column
positions for every vertical bar).
2. Configuration table: added one sentence stating VECTOR_SPEND_LIMIT_PER_TX/
DAILY govern only the still-custodial families, matching .env.example's
existing scope note.
3. Testing section: "builds every build_* tool's unsigned transaction"
overclaimed - keyless-build.test.ts covers 4 of 5 (verified directly
against the test source: vector_build_send_tokens is absent from it,
covered instead by unit tests and the legacy integration suite). Reworded
to name the gap explicitly.
4. packages/builder/test/integration/keyless-e2e.test.ts:9 (comment only):
"which lives on PR #7's branch" was stale now that #7 is merged and
packages/signer is in-tree. Reworded to name the in-tree package and be
precise about what the stand-in does and doesn't exercise (same CML
primitives, without decode/policy/audit).
#7 (signer) and #8 (builder hardening) merged into main this morning; this
branch is rebased onto the result and packages/signer is now in-tree. Three
sites still said pairing the signer with the hosted builder "does not yet
remove the custody exposure" (true when #7 was written, before this PR's
keyless build_* tools existed - now false for the wallet/tx/contract family):
- README.md's "Local signer" section: now states the 4-call non-custodial
flow (signer_get_address -> build_* -> signer_sign -> submit -> await) is
live today for that family, names the signer's four tools, and keeps the
agent-registry/self-improvement families explicitly scoped out.
- packages/signer/README.md's "Known limitations" bullet and "Running it"
closing line: same correction, with the specific now-keyless build_* tool
names and an accurate (not overclaiming) description of what the E2E test
exercises - it signs with the same CML primitives sign.ts uses, as a
stand-in for calling vector_signer_sign directly, not a call into the
signer package's own code.
Grepped case-insensitively across the repo for "does not yet remove" /
"custody exposure" / "signer half is ready" / "builder half is not yet"
before and after: exactly these 3 sites found, all corrected, zero stale
instances remain.
README, .env.example, and docs/architecture/non-custodial-split.md updated for
the family-1 keyless migration (build_* tools, no mnemonic parameters): custody
notice rewritten to describe the keyless boundary precisely, tool tables synced
to the 23-tool surface (4 renames, 4 changed in place, 2 removed), self-hosting
and testing copy updated, .env.example spend-limit scope annotated, and the
architecture doc's PR-sequence table marks family 1 as landed.
docs/VECTOR.md (flagged by Task 4 as referencing stale tool names) is also
updated: renamed/removed tool sections corrected, keyless changeAddress params
added, and the Safety Controls / Error Handling sections stop claiming
server-side spend limits and mnemonic requirements that no longer apply to the
tools this page documents. Edits confined to tool names and custody claims -
no restructuring, no wholesale ADA to AP3X pass beyond the sections touched.
The auth guidance was accurate but lived only in the Configuration
reference table, after both quickstart paths (npm start / docker run)
that a self-hoster would follow top to bottom. Following either to
completion on a public host reproduces the unauthenticated-server problem
this PR exists to fix, without ever seeing a warning at the point of
action.
Add one line after each quickstart's run command, pointing to
Configuration. The Docker line also notes that docker-compose.yml in this
repo already binds 127.0.0.1 by default, unlike the inline `docker run`
example.
Covers what Task 1 actually enforces: auth is only on when MCP_AUTH_TOKENS
is set (otherwise every caller is one anonymous, shared-bucket identity),
rate limits are per identity, and the token parser rejects empty tokens,
whitespace, duplicates, and all-blank values at startup rather than
degrading silently. Notes that vector_submit_transaction and
vector_await_transaction take no mnemonic and sign nothing. Updates the
tool count from 23 to 25 everywhere it appears in the README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Includes an opt-in testnet round-trip test (keyless build -> decode -> policy
-> sign, never submits), excluded from CI because it needs a funded wallet.
Run against the real funded testnet wallet: pass 3, fail 0, nothing submitted.
Verified every README claim against the code as implemented, not just the
brief text, and corrected several:
- VECTOR_SIGNER_AUDIT_LOG_PATH's default resolves against the package's own
install location (repo root), not the process's cwd as originally stated --
and that default filename is not yet covered by .gitignore.
- An audit-log write failure blocks ALL signing, not just accounting:
audit.append() throws by design and vector_signer_sign withholds an
already-produced signature rather than release one with no durable record.
- Documented the #private-field defense against accidental key leakage via
JSON.stringify/console.log, and the read-only/sign tool split that keeps
the signing key out of scope for get_address/decode/get_spend_limits.
- Documented that pairing this signer with the CURRENT hosted builder does
not yet remove the custody exposure it's designed to fix: no builder tool
is keyless yet, and there is no submit_transaction tool to hand a produced
signature to. That's the next stage of the migration, not shipped here.
Env-var cross-check (brief's Step 6, both directions) passes clean.
packages/builder is publishable (private:false) but depended on the
private workspace package at runtime - a published manifest would
advertise an unresolvable dependency. tsup's noExternal inlines it into
the bundle, so devDependencies is the correct home.
Also removes the root tsconfig.json, which still pointed at the deleted
src/, and corrects two README paths the move invalidated.
CI runs test:smoke on every PR but the README only listed test:unit and
test:integration, so a contributor following the README wouldn't know to
run it locally.
The Testing section still told contributors to write a real mnemonic
to mnemonic.txt and run `npm test`, then claimed the result was full
agent-lifecycle coverage against Vector testnet. Since test:unit is
now the default `test` script (five wallet-free CBOR assertions), that
instruction produced a false green and silently skipped the coverage
it advertised. Document test:unit and test:integration separately and
drop the stale VECTOR_MNEMONIC env-var alternative, which setup.ts
never reads.
PR #2 shipped 'never stored server-side', which is true but materially
incomplete - the mnemonic is a tool-call parameter, so it transits the MCP
client, the model provider, and hosted process memory. Replaced with an
accurate notice pointing at the architecture doc.
This PR adds a badge for the [Web3 MCP Server](https://glama.ai/mcp/servers/an8x6gmzdn) server listing in Glama MCP server directory.
<a href="https://glama.ai/mcp/servers/an8x6gmzdn"><img width="380" height="200" src="https://glama.ai/mcp/servers/an8x6gmzdn/badge" alt="Web3 Server MCP server" /></a>
Glama performs regular codebase and documentation scans to:
* Confirm that the MCP server is working as expected
* Confirm that there are no obvious security issues with dependencies of the server
* Extract server characteristics such as tools, resources, prompts, and required parameters.
This badge helps your users to quickly asses that the MCP server is safe, server capabilities, and instructions for installing the server.