- Update assistant lists (added Shawn, Watson, David, CASE, AWS SA; modified Scotty/Harper roles) - Reflect new architecture layers: Tool Prompt Snippets and Shared Context - Align repository structure diagram with current filesystem layout
3.5 KiB
Neo4j (knowledge graph + inter-agent messaging)
The Neo4j knowledge graph is shared across all assistants. Read broadly; write to nodes you own (see your team's graph context).
Writing discipline
- Always MERGE on
idto make writes idempotent. Never blind-create. - Use the canonical ID format:
{type}_{identifier}_{qualifier}(e.g.,infra_neo4j_prod,proto_mcp_dashboard,note_2026-05-20_harper_scotty_prod_handoff). Lowercase, snake_case. - Always set timestamps.
ON CREATE SET n.created_at = datetime()for new nodes;SET n.updated_at = datetime()on every write. - Check before creating. A quick
MATCHagainst the intendedidavoids duplicate nodes that diverge over time.
Parameterized queries
-
Never use
{placeholder}syntax in the Cypher body. Local models (Qwen3.5-35B) mishandle it. Pass values throughparams, and use$namein the query:// good MERGE (n:Note {id: $id}) SET n.title = $title, n.updated_at = datetime()// bad — do not do this MERGE (n:Note {id: '{id}'}) SET n.title = '{title}' -
Literal values in the query body are fine when they are actually constants in your code (
'from:harper', a node label, a relationship type). The rule is no template interpolation into the query string.
Reading discipline
- Read your own domain freely; cross-team reads are useful when you need context — don't be shy.
- Use
LIMITon exploratory queries. Returning the whole graph kills latency and burns tokens.
Common syntax pitfalls
-
Node ownership is by label, not by a
typeproperty. Harper's nodes are:Prototypeand:Experiment(label = ownership). Scotty's are:Infrastructureand:Incident. There is non.type = 'harper'filter; the label is the filter. Thetypeproperty only appears onNotenodes (e.g.,n.type = 'assistant_message'for messaging) — do not generalize that pattern. -
MATCH ... OR MATCH ...is not valid Cypher. You cannot OR-combine match patterns at the top level. To query alternative structures, useUNIONorOPTIONAL MATCH:// UNION — three separate queries, same return columns, results combined MATCH (n:Prototype)-[:DEMONSTRATES]->(t:Technology) RETURN n.id AS id, n.name AS name, t.name AS related, 'demonstrates' AS rel UNION MATCH (n:Prototype)-[:SUPPORTS]->(o:Opportunity) RETURN n.id AS id, n.name AS name, o.name AS related, 'supports' AS rel UNION MATCH (e:Experiment)-[:LED_TO]->(p:Prototype) RETURN e.id AS id, e.title AS name, p.id AS related, 'led_to' AS rel// OPTIONAL MATCH — one row per starting node, with nulls where a relationship doesn't exist MATCH (n:Prototype) OPTIONAL MATCH (n)-[:DEMONSTRATES]->(t:Technology) OPTIONAL MATCH (n)-[:SUPPORTS]->(o:Opportunity) RETURN n.id, n.name, collect(DISTINCT t.name) AS technologies, collect(DISTINCT o.name) AS opportunitiesUse
UNIONwhen you want results from any of several structures with the same shape. UseOPTIONAL MATCHwhen you want everything attached to the same starting node, with nulls/empty collections when a relationship is missing.
Error handling
If a graph query fails, continue the conversation. Mention the failure briefly. Never expose raw Cypher errors to the user.
Inter-agent messaging
Other assistants may leave you messages as Note nodes. See your team's graph context document for the exact inbox-check and send patterns, and the inbox-check prompt if a scheduler is invoking you.