feat(builder)!: self-improvement family keyless - two-step proposal tools, @ts-nocheck dropped, safety.ts deleted, custody allowlist EMPTY
Rewrites self-improvement.ts (1024 -> 556 lines): typed, no @ts-nocheck, imports build logic from gov-build.ts (Tasks 3-4). Splits the old single-shot vector_self_improvement_submit_proposal into two keyless build tools (proposal_lock, proposal_spend) since the deployed module validator requires a confirmed lock before the spend+mint step can reference it; renames critique/endorse to vector_build_self_improvement_*. browse and analyze_metrics stay behavior-identical read-only tools (render strings verified byte-for-byte against the custodial originals). Deletes safety.ts (its last importer). Removes SpendLimits/SpendStatus/ AuditEntry from shared types (grep-verified zero references first). Drops the now-dead spend-limit/audit-log env vars. Empties the custody boundary allowlist with a size-0 pin - every builder family is now keyless. Tool count 23 -> 24. Snapshot delta is surgical: 3 removed, 4 added, 19 of the other 20 byte-identical (analyze_metrics' description had to drop the literal word "mnemonic" to satisfy the custody grep - the one disclosed exception). Headline: grep -rni "mnemonic|seed|bip39|fromSeed" packages/builder/src returns zero lines. This was the last custodial family. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import { resolve } from 'node:path';
|
||||
import { startServer, stopServer, ServerContext } from '../setup.ts';
|
||||
|
||||
/**
|
||||
* Snapshot of the current tool surface (23 tools) for the non-custodial split
|
||||
* Snapshot of the current tool surface (24 tools) for the non-custodial split
|
||||
* series (see docs/architecture/non-custodial-split.md). PR 6 (Task 5) is the
|
||||
* PR that took this list from 25 to 23: it deleted `vector_get_address`
|
||||
* outright, along with the tool that reported per-transaction/daily
|
||||
@@ -13,7 +13,14 @@ import { startServer, stopServer, ServerContext } from '../setup.ts';
|
||||
* keyless equivalent — spend status is gone because the builder no longer
|
||||
* holds keys to limit) as part of making the remaining query tools
|
||||
* (`vector_get_utxos`, `vector_get_transaction_history`, `vector_dry_run`)
|
||||
* keyless. PRs 2, 6, 7 and 8 each deliberately restructure and rename tool
|
||||
* keyless. Spec PR 8 (Task 5) took it from 23 to 24: the self-improvement
|
||||
* family went keyless, removing `vector_self_improvement_submit_proposal`
|
||||
* and renaming `_critique`/`_endorse` to `vector_build_self_improvement_*`,
|
||||
* and splitting the old single-shot submit into two build_* tools
|
||||
* (`_proposal_lock` + `_proposal_spend`) since the deployed module validator
|
||||
* requires a confirmed lock before the spend+mint step can reference it.
|
||||
* This was the last custodial family - the builder now holds no key material
|
||||
* anywhere. PRs 2, 6, 7 and 8 each deliberately restructure and rename tool
|
||||
* families, and each of those PRs is expected to update this list
|
||||
* deliberately, not accidentally. No wallet, no network beyond localhost —
|
||||
* this never needs a mnemonic.
|
||||
@@ -25,6 +32,10 @@ const EXPECTED_TOOLS = [
|
||||
'vector_build_interact_contract',
|
||||
'vector_build_message_agent',
|
||||
'vector_build_register_agent',
|
||||
'vector_build_self_improvement_critique',
|
||||
'vector_build_self_improvement_endorse',
|
||||
'vector_build_self_improvement_proposal_lock',
|
||||
'vector_build_self_improvement_proposal_spend',
|
||||
'vector_build_send_apex',
|
||||
'vector_build_send_tokens',
|
||||
'vector_build_transaction',
|
||||
@@ -38,9 +49,6 @@ const EXPECTED_TOOLS = [
|
||||
'vector_get_utxos',
|
||||
'vector_self_improvement_analyze_metrics',
|
||||
'vector_self_improvement_browse',
|
||||
'vector_self_improvement_critique',
|
||||
'vector_self_improvement_endorse',
|
||||
'vector_self_improvement_submit_proposal',
|
||||
'vector_submit_transaction',
|
||||
];
|
||||
|
||||
@@ -92,11 +100,11 @@ after(async () => {
|
||||
});
|
||||
|
||||
describe('tool inventory smoke test', () => {
|
||||
test('exposes exactly 23 tools', () => {
|
||||
test('exposes exactly 24 tools', () => {
|
||||
assert.equal(
|
||||
actualNames.length,
|
||||
23,
|
||||
`expected 23 tools, got ${actualNames.length}: ${JSON.stringify(actualNames)}`
|
||||
24,
|
||||
`expected 24 tools, got ${actualNames.length}: ${JSON.stringify(actualNames)}`
|
||||
);
|
||||
});
|
||||
|
||||
@@ -132,7 +140,7 @@ describe('tool schema snapshot', () => {
|
||||
});
|
||||
|
||||
// One assertion per tool (rather than a single deepStrictEqual over the whole
|
||||
// 23-tool map) so a failure names the specific tool and shows a readable
|
||||
// 24-tool map) so a failure names the specific tool and shows a readable
|
||||
// diff of just that tool's schema, instead of "objects differ" over an
|
||||
// unreadable combined structure.
|
||||
for (const toolName of Object.keys(schemaSnapshot).sort()) {
|
||||
|
||||
@@ -243,6 +243,220 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_self_improvement_critique": {
|
||||
"description": "Build an UNSIGNED transaction that submits a critique on an improvement proposal (Supportive, Opposing, or Amendment). Requires staking at least 10 AP3X. Provide critiqueDocument for automatic IPFS upload, or critiqueHash and storageUri manually. Takes no key material. Sign it locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction. Find a proposalTxHash to critique with vector_self_improvement_browse.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "Your wallet address (holds the stake AP3X; receives change). Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agentDid": {
|
||||
"description": "Agent DID (hex)",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalTxHash": {
|
||||
"description": "TX hash of the proposal UTxO to critique",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalOutputIndex": {
|
||||
"description": "Output index of the proposal UTxO",
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"critiqueDocument": {
|
||||
"description": "Full critique document as JSON string. Uploaded to IPFS via Filebase; hash and CID computed automatically.",
|
||||
"type": "string"
|
||||
},
|
||||
"critiqueHash": {
|
||||
"description": "blake2b_256 hash of critique document (64 hex chars). Required if critiqueDocument is not provided.",
|
||||
"type": "string"
|
||||
},
|
||||
"critiqueType": {
|
||||
"description": "Type of critique",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Supportive",
|
||||
"Opposing",
|
||||
"Amendment"
|
||||
]
|
||||
},
|
||||
"storageUri": {
|
||||
"description": "Off-chain storage URI for the critique document. Required if critiqueDocument is not provided.",
|
||||
"type": "string"
|
||||
},
|
||||
"stakeApex": {
|
||||
"description": "AP3X to stake (minimum 10)",
|
||||
"type": "number",
|
||||
"minimum": 10
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"agentDid",
|
||||
"proposalTxHash",
|
||||
"critiqueType",
|
||||
"stakeApex"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_self_improvement_endorse": {
|
||||
"description": "Build an UNSIGNED transaction that endorses an improvement proposal by staking at least 5 AP3X. Endorsements signal support to the Foundation Council and are weighted by stake amount. Takes no key material. Sign it locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction. Find a proposalTxHash to endorse with vector_self_improvement_browse.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "Your wallet address (holds the stake AP3X; receives change). Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agentDid": {
|
||||
"description": "Agent DID (hex)",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalTxHash": {
|
||||
"description": "TX hash of the proposal UTxO to endorse",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalOutputIndex": {
|
||||
"description": "Output index of the proposal UTxO",
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"stakeApex": {
|
||||
"description": "AP3X to stake as endorsement (minimum 5)",
|
||||
"type": "number",
|
||||
"minimum": 5
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"agentDid",
|
||||
"proposalTxHash",
|
||||
"stakeApex"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_self_improvement_proposal_lock": {
|
||||
"description": "Build an UNSIGNED transaction that locks an improvement-proposal stake (step 1 of 2). Requires staking at least 25 AP3X. Provide proposalDocument for automatic IPFS upload, or proposalHash and storageUri manually. Takes no key material. Sign it locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction. After this confirms, call this tool's counterpart, vector_build_self_improvement_proposal_spend, with the lock transaction hash to complete the submission.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "Your wallet address (holds the stake AP3X; receives change). Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agentDid": {
|
||||
"description": "Agent DID (hex) - the asset name from Agent Registry NFT",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalType": {
|
||||
"description": "Category of the proposal",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ParameterChange",
|
||||
"TreasurySpend",
|
||||
"ProtocolUpgrade",
|
||||
"GameActivation",
|
||||
"GeneralSuggestion"
|
||||
]
|
||||
},
|
||||
"stakeApex": {
|
||||
"description": "AP3X to stake (minimum 25)",
|
||||
"type": "number",
|
||||
"minimum": 25
|
||||
},
|
||||
"typeParams": {
|
||||
"description": "Type-specific parameters (required for ParameterChange and TreasurySpend)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"paramName": {
|
||||
"type": "string"
|
||||
},
|
||||
"currentValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"proposedValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"recipientDescription": {
|
||||
"type": "string"
|
||||
},
|
||||
"upgradeHash": {
|
||||
"type": "string"
|
||||
},
|
||||
"gameId": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"description": "Priority level (Emergency requires higher stake and reputation)",
|
||||
"default": "Standard",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Standard",
|
||||
"Emergency"
|
||||
]
|
||||
},
|
||||
"proposalDocument": {
|
||||
"description": "Full proposal document as JSON string. Uploaded to IPFS via Filebase; hash and CID computed automatically. If provided, proposalHash and storageUri are ignored.",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalHash": {
|
||||
"description": "blake2b_256 hash of proposal document (64 hex chars). Required if proposalDocument is not provided.",
|
||||
"type": "string"
|
||||
},
|
||||
"storageUri": {
|
||||
"description": "Off-chain storage URI for the full proposal (IPFS CID or OriginTrail UAL). Required if proposalDocument is not provided.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"agentDid",
|
||||
"proposalType",
|
||||
"stakeApex"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_self_improvement_proposal_spend": {
|
||||
"description": "Build an UNSIGNED transaction that completes an improvement-proposal submission (step 2 of 2): spends the locked stake through the module validator and mints the proposal and activity tokens. Requires the confirmed lock transaction hash from vector_build_self_improvement_proposal_lock. Takes no key material. Sign it locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "The SAME wallet address used to build the proposal lock. Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agentDid": {
|
||||
"description": "Agent DID (hex) - must match the proposer DID in the locked proposal",
|
||||
"type": "string"
|
||||
},
|
||||
"lockTxHash": {
|
||||
"description": "The CONFIRMED transaction hash from the proposal lock step",
|
||||
"type": "string"
|
||||
},
|
||||
"lockOutputIndex": {
|
||||
"description": "Output index of the locked proposal UTxO (default: 0)",
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"agentDid",
|
||||
"lockTxHash"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_send_apex": {
|
||||
"description": "Build an UNSIGNED transaction sending AP3X to a recipient. Takes no key material - sign the returned CBOR with your local signer (vector_signer_sign), then broadcast with vector_submit_transaction and confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
@@ -589,7 +803,7 @@
|
||||
}
|
||||
},
|
||||
"vector_self_improvement_analyze_metrics": {
|
||||
"description": "Analyze proposal metrics: proposal activity, adoption rate, treasury health, and engagement statistics. Read-only - no mnemonic needed.",
|
||||
"description": "Analyze proposal metrics: proposal activity, adoption rate, treasury health, and engagement statistics. Read-only, takes no key material.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -646,189 +860,6 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_self_improvement_critique": {
|
||||
"description": "Submit a critique on an improvement proposal. Critiques can support, oppose, or propose amendments. Requires staking AP3X. Provide critiqueDocument (JSON string) for automatic IPFS upload, or critiqueHash + storageUri manually.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the wallet",
|
||||
"type": "string"
|
||||
},
|
||||
"agentDid": {
|
||||
"description": "Agent DID (hex)",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalTxHash": {
|
||||
"description": "TX hash of the proposal UTxO to critique",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalOutputIndex": {
|
||||
"description": "Output index of the proposal UTxO",
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"critiqueDocument": {
|
||||
"description": "Full critique document as JSON string. Uploaded to IPFS via Filebase; hash and CID computed automatically.",
|
||||
"type": "string"
|
||||
},
|
||||
"critiqueHash": {
|
||||
"description": "blake2b_256 hash of critique document (64 hex chars). Required if critiqueDocument is not provided.",
|
||||
"type": "string"
|
||||
},
|
||||
"critiqueType": {
|
||||
"description": "Type of critique",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Supportive",
|
||||
"Opposing",
|
||||
"Amendment"
|
||||
]
|
||||
},
|
||||
"storageUri": {
|
||||
"description": "Off-chain storage URI for the critique document. Required if critiqueDocument is not provided.",
|
||||
"type": "string"
|
||||
},
|
||||
"stakeApex": {
|
||||
"description": "AP3X to stake (minimum 10)",
|
||||
"type": "number",
|
||||
"minimum": 10
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mnemonic",
|
||||
"agentDid",
|
||||
"proposalTxHash",
|
||||
"critiqueType",
|
||||
"stakeApex"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_self_improvement_endorse": {
|
||||
"description": "Endorse an improvement proposal by staking AP3X. Endorsements signal support to the Foundation Council and are weighted by stake amount.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the wallet",
|
||||
"type": "string"
|
||||
},
|
||||
"agentDid": {
|
||||
"description": "Agent DID (hex)",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalTxHash": {
|
||||
"description": "TX hash of the proposal UTxO to endorse",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalOutputIndex": {
|
||||
"description": "Output index of the proposal UTxO",
|
||||
"default": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"stakeApex": {
|
||||
"description": "AP3X to stake as endorsement (minimum 5)",
|
||||
"type": "number",
|
||||
"minimum": 5
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mnemonic",
|
||||
"agentDid",
|
||||
"proposalTxHash",
|
||||
"stakeApex"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_self_improvement_submit_proposal": {
|
||||
"description": "Submit an improvement proposal to the Vector Self-Improvement Module. Requires staking AP3X. Provide proposalDocument (JSON string) for automatic IPFS upload via Filebase and blake2b_256 hashing, OR provide proposalHash and storageUri manually.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the wallet",
|
||||
"type": "string"
|
||||
},
|
||||
"agentDid": {
|
||||
"description": "Agent DID (hex) - the asset name from Agent Registry NFT",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalDocument": {
|
||||
"description": "Full proposal document as JSON string. Uploaded to IPFS via Filebase; hash and CID computed automatically. If provided, proposalHash and storageUri are ignored.",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalHash": {
|
||||
"description": "blake2b_256 hash of proposal document (64 hex chars). Required if proposalDocument is not provided.",
|
||||
"type": "string"
|
||||
},
|
||||
"proposalType": {
|
||||
"description": "Category of the proposal",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ParameterChange",
|
||||
"TreasurySpend",
|
||||
"ProtocolUpgrade",
|
||||
"GameActivation",
|
||||
"GeneralSuggestion"
|
||||
]
|
||||
},
|
||||
"storageUri": {
|
||||
"description": "Off-chain storage URI for the full proposal (IPFS CID or OriginTrail UAL). Required if proposalDocument is not provided.",
|
||||
"type": "string"
|
||||
},
|
||||
"stakeApex": {
|
||||
"description": "AP3X to stake (minimum 25)",
|
||||
"type": "number",
|
||||
"minimum": 25
|
||||
},
|
||||
"typeParams": {
|
||||
"description": "Type-specific parameters (required for ParameterChange and TreasurySpend)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"paramName": {
|
||||
"type": "string"
|
||||
},
|
||||
"currentValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"proposedValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"amount": {
|
||||
"type": "number"
|
||||
},
|
||||
"recipientDescription": {
|
||||
"type": "string"
|
||||
},
|
||||
"upgradeHash": {
|
||||
"type": "string"
|
||||
},
|
||||
"gameId": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"description": "Priority level (Emergency requires higher stake and reputation)",
|
||||
"default": "Standard",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Standard",
|
||||
"Emergency"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mnemonic",
|
||||
"agentDid",
|
||||
"proposalType",
|
||||
"stakeApex"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_submit_transaction": {
|
||||
"description": "Submit an already-signed transaction to Vector. Use this to broadcast CBOR signed elsewhere (for example by a local signer). Does not sign anything.",
|
||||
"inputSchema": {
|
||||
|
||||
Reference in New Issue
Block a user