localharness provides 9 tools with mostly complete schemas and descriptions. Naming is verb-forward (agent, bash_exec, chunk, edit, glob, grep, load_document, memory_search, remember). Descriptions range 50 - 400 chars, meeting the 10 - 1024 baseline. All tools have input schemas with typed parameters and descriptions. However, output schemas are not documented, LLMs cannot predict return structure. Error handling is minimal; most tools lack recovery guidance. The agent tool's description is exceptionally detailed (400+ chars, includes examples and subagent creation instructions), but others are terse. bash_exec and edit lack explicit error classification (retryable vs fatal). memory_search and remember lack examples of fact naming conventions. No tool declares permissions or audit requirements.
Delegate a task to a subagent. Available agents: {agent_list}. Use this when a specialized agent would handle the task better than you. Returns the agent's summary response. You can also BUILD a new specialist: write ~/.localharness/agents/<name>.yaml (fields: name, role, tools: {add: [tool names]}, permissions: {budget: {max_actions, max_duration_minutes}}), then delegate to that name immediately. If you only hold a LARGE document as a handle (you saw a stub like "[tool result evicted — call tool_result_get('<id>')]" or a 'pg-N' page), pass that id in grant_handles to let the subagent read the full body by handle — the bytes never enter your or its prompt. Delegate over-window analysis to 'cruncher'.
Execute bash commands.
Split a large body you hold as a handle (an eviction-stub id, a 'pg-N' page, or a granted handle) into smaller numbered pieces, each retained under its own handle. Use when a body is too big to read in one go: chunk it, then read each piece with tool_result_get('<handle>'), summarize each independently, and combine. Pieces reconstruct the original exactly; origin taint is preserved.
Make a surgical edit to a file by replacing an exact string. Prefer this over `write` for changing an existing file — you emit only the changed snippet, not the whole file. `old_string` must match exactly (including whitespace) and be unique unless replace_all=true. Returns the number of replacements and a unified diff of the change.
Output schemas not documented. LLMs cannot predict return structure (fields, types, pagination). Affects all 9 tools.
bash_exec and edit lack error classification (retryable vs fatal). Agents cannot determine whether to retry on failure.
bash_exec description (50 chars) is minimal. Does not explain when to use it vs agent delegation, timeout behavior, or shell environment.
memory_search and remember lack examples of valid fact names and content format. LLMs may invent non-idempotent names or multi-sentence content.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | <=2025-11-25 | v2 |
Find files matching a glob pattern. Returns newline-separated absolute paths. Use ** for recursive matching (a trailing bare '**' matches files too, not only directories). '~' is expanded automatically; a relative pattern roots at the process's current working directory — pass base_dir or an absolute/'~' pattern to search elsewhere.
Search LOCAL FILE contents on disk for a regex pattern. Returns matching lines with file path and line number. Searches recursively if path is a directory. For information that is not in local files, use web_search.
Load a large local document and retain its FULL text under a handle WITHOUT pulling it into context. Returns the handle + a short stub. Use for a document too big to read inline: load it, then delegate analysis to the cruncher — agent('cruncher', task='<your question>', grant_handles=['<handle>']) — which reads the body by handle, splits it, and returns a faithful answer.
Search your persistent memory by meaning for a query string. Returns the most resonant fact names with a short snippet. Use memory_get(name) for a match's full body. The system prompt shows only an index, so search when you need detail that isn't already inlined. Supports time filters — e.g. since='yesterday' answers 'what did we learn yesterday?'.
Save one durable fact to your persistent memory so future sessions can use it. Use a short stable name (e.g. 'deploy-requires-vpn') and a self-contained content sentence. Writing an existing name with new content supersedes the old version (history is kept). Use for things worth knowing NEXT session — not scratch state for the current task.
No tool declares permissions, audit requirements, or scope (read:file, write:memory, exec:bash). Agents cannot reason about least-privilege configuration.