Local-first engineering lineage: capture why your codebase looks the way it does.
arabian demonstrates solid tool design with clear naming (verb_noun pattern), comprehensive descriptions (avg 180 chars), and well-structured JSON schemas using Zod. All 10 tools have explicit descriptions and input schemas with type constraints and enums. However, output schemas are not formally documented, responses are JSON but the structure is not declared in tool metadata. Error handling is present but generic ('arabian error: {message}'). Parameter descriptions are generally good but some lack actionable constraints (e.g., 'Markdown' for description field). No tool annotations (readOnlyHint/destructiveHint) despite clear read/write semantics. Composition is excellent, tools chain well (e.g., get_node → get_lineage → search). Naming is consistent and unambiguous across all 10 tools.
Link two nodes with a typed directed edge. Types: led_to, considers, chooses, rejects, supersedes, implements, produces, constrains, triggers, references. The triggers edge (outcome → question) closes the lineage cycle — use it when a result raises a new question.
Create a lineage node recording a piece of engineering context. Node types: question, alternative, decision, experiment, implementation, outcome, constraint. Pair with arabian_create_edge to link it into the graph (e.g. question --led_to--> decision, decision --chooses--> alternative). Arabian is a passive recorder: you decide what to log.
Fetch the recorded engineering lineage for one or more files before touching them: decisions that shape them, the questions behind those decisions, alternatives considered, constraints, implementations and supersedes. Returns readable text. Use this proactively whenever you are about to modify code that might have recorded context.
Return the entire project graph (project meta, all nodes, all edges). Use for visualization or bulk analysis; prefer get_lineage for focused traversal.
Traverse the graph around a node: "what led to this?" (direction=up), "what came from this?" (direction=down), or both. Returns the subgraph of nodes and edges within N hops.
Output schemas not formally documented in tool metadata. Responses are JSON but structure (fields, types, required properties) is not declared. LLMs cannot reliably extract fields for downstream tool chaining.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear semantics. arabian_create_node, arabian_update_node, arabian_create_edge, arabian_supersede are destructive; arabian_get_* are read-only. Annotations enable safer agent planning.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
Fetch a single node by id, including its incoming edges (what led to this) and outgoing edges (what came from this).
List nodes, optionally filtered by type, status, or tag. Returns id, type, status, title and updatedAt for each.
Case-insensitive multi-term search across node titles, descriptions, tags and file refs. All terms must match somewhere.
Replace a decision: creates a new decision node, wires new --supersedes--> old, marks the old one superseded, and carries over its fileRefs and tags. Use when a decision changes and the history must stay intact.
Update a node's title, description, status, tags, fileRefs or metadata. Statuses: proposed, accepted, rejected, superseded, draft, completed, abandoned. Status transitions are not enforced.
Error handling is generic ('arabian error: {message}'). Does not categorize errors as retryable vs user-fixable, nor provide recovery guidance. E.g., 'Node not found' should suggest search_nodes() or list_nodes().
Parameter 'description' in arabian_create_node and arabian_update_node lacks actionable constraints. Description says 'Markdown' but does not specify length limits, required sections, or formatting rules. LLMs may generate overly long or malformed descriptions.
arabian_get_graph returns entire project graph without pagination or limit. For large projects, this could exhaust context window. Should accept optional limit parameter and return total count.