Commit Graph

7 Commits

Author SHA1 Message Date
FilipBl4gojevic
0a384f44a9 docs: scope the migration-complete claim to the codebase - mainnet stays custodial until the cutover deploy
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.
2026-07-30 18:35:35 +02:00
FilipBl4gojevic
8d7d68a4d0 docs: the non-custodial migration is complete - every family keyless, server holds zero key material
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.
2026-07-30 18:08:46 +02:00
FilipBl4gojevic
d0fc86c6e0 docs: agent-registry family is keyless - tool tables, custody scope, spend-limit copy
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.
2026-07-29 19:53:25 +02:00
FilipBl4gojevic
66f6b60dbd docs: signer is in-tree - align custody claims after #7/#8 merged
#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.
2026-07-29 14:37:59 +02:00
FilipBl4gojevic
a56e70deae fix(signer): harden the boundary check's globalThis blind spot, and stop overstating it
The review verified six obfuscations that bypass boundary.test.ts's ambient-
global and forbidden-import checks: globalThis['fetch'](...), an alias
(const f = fetch; f(...)), an aliased bracket reference, the comma-operator
trick ((0, globalThis.fetch)(...)), and two dynamic import()s with a
concatenated specifier (import('node:' + 'dns'), import('child_' +
'process')). README.md called the check "the package's central security
guarantee" and boundary.test.ts's header claimed the signer "CANNOT reach
the network -- not that it chooses not to." Neither line was true of what a
text scan can actually promise.

Hardened cheaply, within reach of a text scan:
- FORBIDDEN_IMPORTS gains node:dns, node:dns/promises, node:http2,
  node:worker_threads, node:vm, each with a one-line rationale.
- AMBIENT_NETWORK_GLOBALS gains globalThisQualifiedAccess(name), matching a
  global reached via globalThis in either dot or bracket ("computed member
  access") notation, plus navigator['sendBeacon'] bracket notation.

Verified empirically against the real hardened check (temporary probe
files under src/, one per evasion, deleted immediately after -- see the
task report for the full per-file breakdown): globalThis['fetch'](...),
the aliased-bracket-reference variant, and the comma-operator
globalThis.fetch trick are now all caught. The plain-identifier alias and
both concatenated dynamic imports still pass -- those need real data-flow
tracking or evaluating an arbitrary runtime expression, neither of which a
text scan can do, and no attempt was made to chase them.

Reworded both the README section and boundary.test.ts's header comment to
say what the check actually verifies: today's shipped src/ has no
accidental or careless network capability. Deliberate obfuscation is named
as a code-review responsibility, not something this file promises to catch.

Final whole-branch review, Fix 4 of 4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 18:33:14 +02:00
FilipBl4gojevic
20dba15d63 fix(signer): gitignore the signer's audit log, matching the builder's
vector-signer-audit-log.json resolves inside the repo checkout by default,
and the README self-disclosed that it was NOT in .gitignore (unlike the
builder's vector-audit-log.json). A documented footgun is worse than no
footgun when the fix is one line. Adds the entry and updates the README
paragraph that described the gap to describe the fix instead.

Final whole-branch review, Fix 1 of 4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 18:30:43 +02:00
FilipBl4gojevic
b4038aa1f1 docs(signer): document configuration, semantics, and known limitations
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.
2026-07-28 17:44:36 +02:00