gremlin-pythonlisted
Install: claude install-skill Ybx-jp/thalamus
# Gremlin for Agents — the Details That Bite
Two query surfaces exist in this project, and they speak **different dialects**.
Most doomed queries are one dialect written on the other surface.
| | `memory_query` (MCP) | gremlin-python (code) |
|---|---|---|
| What you write | gremlin-lang **string** | Python method chain |
| Step names | camelCase: `hasLabel`, `outE`, `valueMap` | snake_case: `has_label`, `out_e`, `value_map` |
| Terminal step | **None — the server iterates** | **Required — nothing runs without one** |
| Keyword clashes | none | underscore-suffixed: `as_`, `in_`, `not_`, … |
| Guard | lexical guard in `substrate/query.py` rejects mutation *and* python dialect | `gremlin-guard.sh` PreToolUse hook blocks inline traversals with no terminal step |
For `memory_query` strategy (when to use it at all, cost discipline), see the
`recall-strategy` skill. This skill is the *authoring* reference, and its rules
below are gremlin-python's.
## Rule 1 — every traversal ends in a terminal step
gremlin-python traversals are **lazy**. `g.V().has_label('Claim')` builds
bytecode and sends **nothing** to the server. No error. Silently nothing.
Terminate every traversal with exactly one of:
- `.to_list()` — run it, return all results as a list
- `.next()` — run it, return the next (usually only) result
- `.iterate()` — run it for its effects, discard results (the writer's idiom)
- `.has_next()` — run it, return whether a result exists
- consuming it as an iterator (`for x in