Orchestrata Ultimate › Plans › spec-audit › I-tools
Cluster I — Tools suite (greenfield tools 063–072)
Source: plans/spec-audit/I-tools.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-04 · 345 lines.
Prose pending.
Plan text
Cluster I — Tools suite (greenfield tools 063–072)
Investigation agent report. READ-ONLY audit of src/orchestrata_ultimate/ against specs
063–072. Method: plans/spec-audit/_METHOD.md. Evidence-based; requirements-checklist boxes ignored.
Headline finding
All 10 tool classes are entirely ABSENT (GAP). Not one of the spec'd tool classes exists
in the target package — and none exist in the frozen source monorepo either, so these are pure
greenfield specs, never implemented anywhere (nothing to "port"). SPEC-062
(cheetahclaws-tools-gap) is the parent gap-analysis/roadmap that enumerates these same 14
missing tools; 063–072 are the per-tool specs it spawned. The prior register note ("Greenfield
tool suite (063–072) + unified registry/ToolSearch = PENDING") is CONFIRMED.
The real architectural gap: no tool framework to build on
There is no BaseTool / AbstractTool interface anywhere (searched target + monorepo, 0
hits). Tools today are two incompatible ad-hoc patterns, neither of which is a registry:
agents/tool_registry.py— the one volks actually invoke. Module-level dict literals (READ_FILE_TOOL, … 8 total) collected inALL_TOOLS, anAGENT_TOOLS: dict[alias→[names]]allow-map, and aToolExecutor(tool_registry.py:285) that dispatches by a hardcodedif/elifchain in.execute()(tool_registry.py:329-352). Wiring point:agents/volks/base.py:255-290(_call_llm_with_tools) callsget_agent_tools(alias)+ToolExecutor.execute(). Adding a tool here = write a dict, append toALL_TOOLS, add to eachAGENT_TOOLSlist, add anelif+_handlermethod. No dynamic registration, no discovery, no metadata index.session/mcp_tools.py:SessionMCPTools/session/fireflies_tools.py:FirefliesMCPTools— a different pattern: a class exposingtool_definitions() -> list[dict]+handle_tool_call(name, args). Not connected totool_registry.ALL_TOOLS; used only in the session subsystem.
Consequence: every tool in this cluster needs a home, and SPEC-072 (ToolSearch) cannot exist
until a real registry with per-tool metadata exists to index. So the cluster has one dominant
shared prerequisite: build src/orchestrata_ultimate/tools/base.py (a BaseTool protocol/ABC +
ToolMetadata) and tools/registry.py (a ToolRegistry with register/discover/list), then
refactor ToolExecutor to dispatch through it. SPEC-062 already defines the ToolMetadata
schema + category taxonomy (file/shell/search/web/task/memory/planning/agent/config/mcp/utility)
to model this on. The src/orchestrata_ultimate/tools/ package exists but today holds only AST
helpers (ast_query.py, ast_pipeline.py) — it is the natural target dir.
Reusable primitives found (building blocks, not the tools themselves):
harness/isolation.py:WorktreeIsolation(line 31) — git worktree create/cleanup plumbing → SPEC-064.core/isolation.py:Isolation(line 13) — filesystem sandbox context manager → SPEC-063 sandbox modes.agents/task_executor.py:TaskExecutor(line 99) +agents/interfaces.py:ITaskExecutor(submit/cancel/get_task/list_tasks) → SPEC-069 (agent-task, NOT process-stdout capture — partial fit).governance/resource_access.py:ResourceAccessController(line 78, PAM++/Prolog) → authz for 063/069/070/071.agents/volks/pm/goal_registry.py:GoalRegistry(line 215) — the SPEC-023 goal system; NOT a dep of the cron/task tools (see note below).
Missing declared deps (none in pyproject.toml): croniter (068), an LSP client e.g. pygls
(065), mcp SDK (071), rapidfuzz + optional numpy/sentence-transformers (072). Already
present and reusable: httpx>=0.28 (067), redis>=5 (068/069 locks), fastapi+websockets
(063 API/WS). Per the project rule, all must be declared (optional/lazy features under
[project.optional-dependencies]) and pass check-deps.
SPEC-063 REPLTool — GAP
- Specifies: interactive multi-language (Python/JS/Bash) REPL with persistent session state,
sandbox modes (strict/standard/relaxed), resource limits, REST+WebSocket API, CLI; tool id
repl_execute. - Verified:
REPLToolclass ❌ absent —symbols --pattern REPLTool→ 0;--pattern REPL→ 0.REPLSession/ExecutionResultmodels ❌ absent —--pattern REPLSession→ 0,--pattern Sandbox→ 0.- Registry wiring ❌ — not in
tool_registry.ALL_TOOLS; norepl_executeinToolExecutor. - Nearest existing:
ToolExecutor._run_shell(tool_registry.py:441) is one-shot sandboxed subprocess exec — not a stateful REPL session; no PTY (grep pty/pexpect→ 0).
- Remaining work / plan:
- Scope:
tools/repl_tool.py—REPLTool(BaseTool)+REPLSessionManager(session_id → live interpreter/PTY), per-language backends (Python via subprocess/exec namespace, Node vianode, Bash via shell), stdout/stderr capture,resource.setrlimit/timeout enforcement, sandbox levels reusingcore/isolation.py:Isolationfor fs restriction. State persistence across expressions (in-proc namespace or persistent subprocess). Optional FastAPI router + WS for FR-021–028; register asrepl_executein the new registry (+AGENT_TOOLS). - Target files:
src/orchestrata_ultimate/tools/repl_tool.py(new); register viatools/registry.py; optionaltools/repl_api.py. Addptyprocessdep if PTY sessions required. - Approach: build the language-backend abstraction first (subprocess-per-session for isolation), layer session lifecycle + idle-timeout, then resource limits, then optional API/WS. Bash/Python testable on Linux/Incus; JS needs Node in the test env.
- Dependencies: unified registry (shared);
core/isolation.py; governanceResourceAccessControllerfortool:executepermission (SEC/governance §12). - Effort: L (>2d). Risk: med — sandbox/security correctness (SEC-001..045) and free-threaded subprocess resource limits; gVisor from spec is optional and absent here.
- Scope:
SPEC-064 Git Worktree Tools (Enter/Exit) — GAP
- Specifies:
EnterWorktreeTool(enter existing / create worktree + optional branch) &ExitWorktreeTool(return to main worktree), path validation, session CWD context update, branch protection, conflict/uncommitted-change detection. - Verified:
EnterWorktreeTool/ExitWorktreeTool❌ absent —--pattern Worktreereturns onlyharness/isolation.py:WorktreeIsolation(line 31), a test-harness isolation manager, not a volk tool.--pattern WorktreeTool→ 0.- Registry wiring ❌ — not in
ALL_TOOLS/ToolExecutor. - Reuse available:
WorktreeIsolation.create/cleanup(isolation.py:34/61) already runsgit worktree add/removevia_run_git— the exact git plumbing these tools need.
- Remaining work / plan:
- Scope:
tools/worktree_tools.py— twoBaseToolclasses wrappinggit worktreeoperations; resolve/normalize paths (FR-011..016), verify.gitgitfile points to parent + membership ingit worktree list(FR-015/016), store previous CWD in session state for Exit (FR-019), lock/uncommitted-change detection (FR-018, TR-012). Session-context update is the integration subtlety — Enter/Exit mutate the run's working dir; must plug into whatever holds volk CWD (ToolExecutor._workspace/ session state). - Target files:
src/orchestrata_ultimate/tools/worktree_tools.py(new); factor shared git helpers from/withharness/isolation.py; register in registry +AGENT_TOOLS. - Approach: extract the
_run_githelpers into a shared git utility, build Enter (validate → optional create → update CWD context), then Exit (find parent → restore CWD, idempotent from main), then guards. - Dependencies: unified registry (shared); session/CWD state ownership; git only.
- Effort: M (0.5–2d). Risk: low-med — CWD-context mutation semantics vs concurrent volks.
- Scope:
SPEC-065 LSPTool — GAP
- Specifies: full LSP integration (server auto-detect + lifecycle, completion, hover, diagnostics, goto-definition, references, code actions, formatting, rename) over JSON-RPC 2.0 stdio; multiple concurrent servers with process isolation.
- Verified:
LSPTool❌ absent —--pattern LSP→ 0;grep lspin src → 0 functional hits.- No JSON-RPC/LSP client, no
pygls/language-server dep declared (grep pygls|pylsp→ 0). - Registry wiring ❌.
- Remaining work / plan:
- Scope:
tools/lsp_tool.py—LSPTool(BaseTool)+LanguageServerManager(spawn/track per-language servers e.g.pyright/ruff/typescript-language-server), JSON-RPC 2.0 stdio transport,initializehandshake,didOpen/didChangedoc sync, and the 9 request methods. - Target files:
src/orchestrata_ultimate/tools/lsp_tool.py(new) +tools/lsp/jsonrpc.pytransport; addpygls/lsprotocol(or hand-rolled JSON-RPC) dep. Register in registry. - Approach: build the JSON-RPC stdio client + lifecycle first, then map each LSP method; use
pyright/ruff-lspfor the Python path so it's testable on Incus. External language-server binaries are a runtime prerequisite. - Dependencies: unified registry (shared); external LSP server binaries; new dep.
- Effort: L (>2d). Risk: med-high — external process orchestration, concurrency, protocol conformance; largest greenfield surface after 070.
- Scope:
SPEC-066 PowerShellTool — GAP
- Specifies: sandboxed pwsh command/script execution, command allowlist, timeout, output sanitization, cross-platform pwsh binary detection, structured output, cancellation, audit log.
- Verified:
PowerShellTool❌ absent —--pattern PowerShell/owerShell→ 0.- Registry wiring ❌. No pwsh detection code (
grep powershell→ 0).
- Remaining work / plan:
- Scope:
tools/powershell_tool.py—PowerShellTool(BaseTool)invokingpwsh/powershellvia subprocess with allowlist enforcement (mirrorToolExecutor.BLOCKED_COMMANDSpattern, but allowlist), timeout, output filtering, binary discovery (shutil.which), cancellation. - Target files:
src/orchestrata_ultimate/tools/powershell_tool.py(new); register in registry. - Approach: reuse the subprocess/timeout scaffolding from
ToolExecutor._run_shell; add allowlist + sanitization + pwsh discovery. Structurally simple. - Dependencies: unified registry (shared); no new pip deps (subprocess only).
- Effort: M (0.5–2d). Risk: med — target is Windows/pwsh; the Linux/Incus test infra has no pwsh, so real (no-mock) integration testing needs a pwsh install or is unverifiable here.
- Scope:
SPEC-067 RemoteTriggerTool — GAP
- Specifies (own spec): HTTP/HTTPS webhook/API trigger — auth schemes (API key/Bearer/Basic/ OAuth2/HMAC), retry w/ backoff, response validation/transform, TLS verify, webhook signature verification, connection pooling.
- Verified:
RemoteTriggerTool❌ absent —--pattern Trigger→ 0. Registry wiring ❌.- DIVERGENCE flag: SPEC-062 FR-006 describes this tool as SSH-based remote execution,
while SPEC-067's own spec is an HTTP webhook/API client. The two specs disagree on the
core mechanism — resolve before building (recommend following 067's HTTP framing; note SSH
would instead need
paramiko). Action: reconcile 062 vs 067.
- Remaining work / plan:
- Scope:
tools/remote_trigger_tool.py—httpx.AsyncClient-based trigger with pluggable auth (incl. HMAC signing/verification), tenacity-style retry, response schema validation. - Target files:
src/orchestrata_ultimate/tools/remote_trigger_tool.py(new); register in registry. - Approach:
httpx>=0.28already declared — build auth strategy set, then retry/backoff, then signature verify. Straightforward. - Dependencies: unified registry (shared);
httpx(present). SSH variant would addparamiko. - Effort: M (0.5–2d). Risk: low-med (mostly the 062/067 mechanism reconciliation).
- Scope:
SPEC-068 ScheduleCronTool — GAP
- Specifies: cron-expression scheduling w/ timezone support, SQLite job persistence, async
background scheduler, missed-job recovery (
MissedJobPolicyskip/run_once/run_all), concurrent- execution protection (distributed lock), retry. - Verified:
ScheduleCronTool❌ absent —--pattern Cron/CronTool/ScheduleTool→ 0.--pattern Schedulereturns onlypostman/priority.py:PriorityScheduler(a queue scheduler, unrelated).- No
croniterdep declared. Registry wiring ❌. - SPEC-023 dependency check: NOT coupled to the goal-system.
GoalRegistry(agents/volks/pm/goal_registry.py:215) is a session-backlog concern; ScheduleCron is a generic job-runtime. No hard dep — correcting the register's implied coupling.
- Remaining work / plan:
- Scope:
tools/schedule_cron_tool.py— cron parse/validate viacroniter, tz-aware next-run (zoneinfo), SQLite (aiosqlite) persistence, an async scheduler loop, missed-job policy on startup recovery, Redis-based distributed lock (redis present) for concurrency protection. - Target files:
src/orchestrata_ultimate/tools/schedule_cron_tool.py+tools/cron/store.py(new); addcroniter(+aiosqliteif SQLite chosen) deps; register in registry. - Approach: parser/validator → persistence layer → scheduler loop → recovery/locking. The background scheduler lifecycle (who owns the loop across a volk run) is the design question.
- Dependencies: unified registry (shared);
croniter,aiosqlite(new);redis(present) for locks. No SPEC-023 dep. - Effort: L (>2d). Risk: med — long-running background scheduler + persistence + tz edge cases.
- Scope:
SPEC-069 Task Management Tools (TaskStop + TaskOutput) — GAP
- Specifies:
TaskStopTool(graceful/forced stop, by id or name-pattern, batch) &TaskOutputTool(full/stream/tail/range stdout+stderr, status metrics). Extends four sibling tools TaskCreate/Update/Get/List. Redis-backed; governance-gated stop. - Verified:
TaskStopTool/TaskOutputTool❌ absent —--pattern TaskCreate→ 0,--pattern TaskManager→ 0. The referenced sibling Create/Update/Get/List tools also don't exist → the entire task-tool subsystem is greenfield.- Partial reuse:
agents/task_executor.py:TaskExecutor(line 99) +ITaskExecutor(submit/cancel/get_task/list_tasks) exist — but this is agent-task orchestration, not process-level stdout/stderr capture with tail/streaming, so it only partly fits. - Registry wiring ❌.
- SPEC-023 check: distinct from goal-system; couples to a task runtime (TaskExecutor),
not
GoalRegistry. No hard SPEC-023 dep.
- Remaining work / plan:
- Scope: decide the task runtime — either extend
TaskExecutor/ITaskExecutorto own long-running processes with captured output buffers (Redis-persisted), or build a dedicated task-process manager. Thentools/task_tools.pywith Stop (cancel + SIGTERM→SIGKILL, pattern/batch, governance check viaResourceAccessController) and Output (buffered retrieval: full/tail/range/stream). - Target files:
src/orchestrata_ultimate/tools/task_tools.py(new); extendagents/task_executor.pyor addtools/task/runtime.py; register in registry. - Approach: settle the runtime coupling first (reuse vs new — a scope decision for the owner), then the two tools on top. Redis for output persistence + status metrics.
- Dependencies: unified registry (shared); task runtime (
TaskExecutordecision); governanceResourceAccessController(SEC-REQ-003 gate);redis(present). Sibling Create/Update/Get/List tools are effectively co-requisites. - Effort: M–L (grows to L if the whole task subsystem is built). Risk: med — signal handling + output streaming + the runtime-ownership decision.
- Scope: decide the task runtime — either extend
SPEC-070 Team Tools — GAP
- Specifies:
TeamCreateTool/TeamDeleteTool/TeamUpdateTool— team entity CRUD, 3 default RBAC roles (ADMIN/MEMBER/VIEWER), hierarchical parent teams, slug uniqueness, quota, soft/hard delete with recovery window + cascade + member migration + audit trail. - Verified:
- Team tools ❌ absent —
--pattern Team/TeamTool/Teammate→ 0. Registry wiring ❌. - No team entity model, no RBAC store, no auth/JWT service in target (spec's "Integration
Points" name
orchestrata-auth+ SPEC-060 Resource Management, neither present here).
- Team tools ❌ absent —
- Remaining work / plan:
- Scope: a whole
teamsubsystem —Team/Role/Membershipmodels + persistence, RBAC permission inheritance, plus the three tools. Requires an identity/user source (JWT context) and a resource-isolation model that don't exist yet. - Target files:
src/orchestrata_ultimate/tools/team_tools.py+ ateam/domain package (models, store, rbac) (new); register in registry. - Approach: define the domain model + persistence + RBAC first, then the CRUD tools; but this is blocked on an auth/user identity source — surface that as a scope decision (build a minimal identity shim vs defer until an auth subsystem exists).
- Dependencies: unified registry (shared); auth/JWT identity (absent); SPEC-060 Resource
Management (absent); governance
ResourceAccessControllerfor RBAC enforcement. - Effort: L (>2d, largest). Risk: med-high — depends on two absent subsystems (auth, resource mgmt); most likely to need a spec-scope decision / deferral.
- Scope: a whole
SPEC-071 MCP Resource Tools (List/Read) — GAP
- Specifies:
ListMcpResourcesTool+ReadMcpResourceTool— MCP client to external MCP servers: server registry + connection pool, encrypted credential/vault, TTL resource cache, version + partial reads, Prolog/PAM++ access control. Uses themcpPython SDK. - Verified:
- MCP client tools ❌ absent —
--pattern MCPResource→ 0.nomcp` pip dep declared. - Existing
session/mcp_tools.py:SessionMCPTools+session/fireflies_tools.py:FirefliesMCPToolsare server-side tool wrappers (they exposetool_definitions()), NOT MCP-client consumers of external MCP servers — different direction; only the class shape is a reuse hint. - Registry wiring ❌.
- MCP client tools ❌ absent —
- Remaining work / plan:
- Scope:
tools/mcp_resource_tools.py— MCP client via themcpSDK,McpServerRegistry+ connection pool, credential store (vault/encrypted), TTL cache with invalidation, the two tools (list w/ metadata + status; read w/ version + partial), governed byResourceAccessControllerProlog predicates. - Target files:
src/orchestrata_ultimate/tools/mcp_resource_tools.py+tools/mcp/registry.py(new); addmcpdep (optional-dependencies, lazy-imported); register in registry. - Approach: MCP client + server registry first, then caching, then governance/credentials.
- Dependencies: unified registry (shared);
mcpSDK (new); governanceResourceAccessController(PAM++); a credential/vault store. - Effort: M–L. Risk: med — external MCP servers to test against; credential/vault piece may be under-provisioned in the target.
- Scope:
SPEC-072 ToolSearchTool — GAP (capstone / registry-blocked)
- Specifies: semantic + keyword(TF-IDF) + fuzzy search over an in-memory index of all registered tools, filters/facets/pagination, suggestions, result cache w/ TTL+LRU, index rebuild/incremental update, embeddings w/ graceful degradation to keyword-only.
- Verified:
ToolSearchTool❌ absent —--pattern ToolSearch→ 0. Registry wiring ❌.- Hard blocker: FR-011/FR-012/FR-013 require "an in-memory index of all registered tools"
synchronized with a "tool registry" — but there is no unified registry with per-tool metadata
to index (see Headline).
ALL_TOOLSis 8 static dicts with no category/tags/embeddings. - No
sentence-transformers/numpy/rapidfuzzdeps declared.
- Remaining work / plan:
- Scope: build after the unified
ToolRegistryexists.tools/tool_search_tool.py— index builder overToolRegistry.list()metadata, keyword TF-IDF +rapidfuzzfuzzy (ship first), optional embedding similarity (sentence-transformers, lazy/optional dep → graceful degradation per FR/ERR-008), facets/pagination, TTL+LRU result cache (redis or in-proc). - Target files:
src/orchestrata_ultimate/tools/tool_search_tool.py(new); depends ontools/registry.py; addrapidfuzz(+ optionalnumpy/sentence-transformers). - Approach: registry first → metadata index → keyword+fuzzy ranking → cache → optional embeddings.
- Dependencies: HARD dep on the unified
ToolRegistry(must exist first);rapidfuzz(new), optional embedding stack; the richer each other tool's metadata, the better it works. - Effort: M–L (once registry exists). Risk: med — mostly gated on the registry prerequisite; embeddings are optional-degradable.
- Scope: build after the unified
Shared dependencies / sequencing (critical for parallelism)
- Unified tool framework (prerequisite for the whole cluster; hard-blocks 072). New
src/orchestrata_ultimate/tools/base.py(BaseTool+ToolMetadata, model on SPEC-062's schema- category taxonomy) and
tools/registry.py(ToolRegistry: register/discover/list/get), then refactoragents/tool_registry.py:ToolExecutor(line 285) to dispatch through it and haveget_agent_toolsderive from registered metadata. Build this first; then 063–071 land in parallel; 072 lands last. Effort of the framework itself: M.
- category taxonomy) and
- SPEC-062
cheetahclaws-tools-gapis the parent roadmap/governance-mapping + tool taxonomy for this entire cluster (not a code dependency, but the source of truth for categories, governance predicates, and agent-distribution). Treat 062 as the umbrella. - Governance
ResourceAccessController(governance/resource_access.py:78, PAM++/Prolog) — authz for 063 (tool:execute), 069 (stop authz), 070 (RBAC), 071 (resource access). - SPEC-023 goal-system is NOT a dependency of the cron (068) or task (069) tools — those are
job/process runtimes, distinct from
GoalRegistry(the session backlog). Corrects the register's implied coupling. 069 instead couples to the task runtime (TaskExecutor,agents/task_executor.py:99) — a scope decision (reuse vs build). - New declared deps (per project rule,
check-deps-gated; optional/lazy under[project.optional-dependencies]):croniter(+aiosqlite) 068 · LSP client e.g.pygls/lsprotocol065 ·mcpSDK 071 ·rapidfuzz(+optionalnumpy/sentence-transformers) 072 ·ptyprocess063 (if PTY) ·paramiko067 (only if SSH variant chosen). Already present:httpx,redis,fastapi,websockets,pydantic. - Absent-subsystem blockers: SPEC-070 depends on an auth/JWT identity source and SPEC-060 Resource Management, both absent → most likely to need a scope decision/deferral.
Cluster summary table
| Spec | Class(es) | Class | Effort | Hard deps |
|---|---|---|---|---|
| SPEC-063 | REPLTool |
GAP | L | unified registry; core/isolation; governance |
| SPEC-064 | EnterWorktreeTool,ExitWorktreeTool |
GAP | M | unified registry; session CWD state; harness/isolation git plumbing |
| SPEC-065 | LSPTool |
GAP | L | unified registry; pygls/LSP servers (new dep) |
| SPEC-066 | PowerShellTool |
GAP | M | unified registry; pwsh binary (untestable on Linux infra) |
| SPEC-067 | RemoteTriggerTool |
GAP | M | unified registry; httpx(present); 062↔067 SSH-vs-HTTP divergence |
| SPEC-068 | ScheduleCronTool |
GAP | L | unified registry; croniter/aiosqlite(new); redis. NOT SPEC-023 |
| SPEC-069 | TaskStopTool,TaskOutputTool |
GAP | M–L | unified registry; task runtime (TaskExecutor); governance; redis. NOT SPEC-023 |
| SPEC-070 | TeamCreateTool,TeamDeleteTool,TeamUpdateTool |
GAP | L | unified registry; auth/JWT (absent); SPEC-060 (absent); governance RBAC |
| SPEC-071 | ListMcpResourcesTool,ReadMcpResourceTool |
GAP | M–L | unified registry; mcp SDK (new); governance; vault |
| SPEC-072 | ToolSearchTool |
GAP | M–L | HARD: unified ToolRegistry must exist first; rapidfuzz(new) |
Evidence log (commands run + results)
symbols --pattern {REPLTool,GitWorktree,WorktreeTool,LSPTool,PowerShell,RemoteTrigger,ScheduleTool,CronTool,TaskManagement,TeamTool,MCPResource,ToolSearch,REPLSession}→ all 0 symbols.- Broad:
symbols --pattern REPL|LSP|owerShell|Cron|Trigger|Teammate|MCP|Team→ 0 for the tool classes;Worktree→ onlyharness/isolation.py:WorktreeIsolation;Schedule→ onlypostman/priority.py:PriorityScheduler;MCP→ onlysession/{mcp_tools:SessionMCPTools, fireflies_tools:FirefliesMCPTools};Resource→ governance controllers. - Sanity:
symbols --pattern BaseAgent→ found (toolkit working). refs ToolExecutor→ 1 def (tool_registry.py:285), used only atagents/volks/base.py:268.refs get_agent_tools→ deftool_registry.py:523, usedbase.py:263. (Confirms the sole tool-invocation path.)- Read
agents/tool_registry.py(full) — 8 static dict tools,AGENT_TOOLSallow-map, if/elifToolExecutor; no BaseTool, no registry. - Read
agents/volks/base.py:240-300—_call_llm_with_toolswiring. - Monorepo grep
grep -rniE 'class (REPLTool|...|ToolSearchTool)' packages/→ 0;class BaseTool|Tool(|ToolBase|AbstractTool→ 0 (never implemented in source either). pyproject.tomlgrep:httpx>=0.28,redis>=5,fastapi,websockets,pydanticpresent;croniter/pygls/mcp/rapidfuzz/sentence-transformers/paramiko/aiosqliteabsent.grep pty|pexpect|ptyprocessin src → 0 (no PTY primitive for 063).- Read specs 063–072 (overview/FR/integration) + SPEC-062 overview (parent gap plan enumerating these 14 tools; defines
ToolMetadatacategory taxonomy; FR-006 labels RemoteTrigger as SSH — divergence vs 067). docs/spec-gap-register.mdgrep for 063–072/ToolSearch → 0 (this cluster was not in the prior 20-spec audit).