Files
koios/prompts/tools/neo4j.md
Robert Helewka 703b3402d4 docs(readme): update assistant roster, prompt layers, repo structure
- 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
2026-05-20 22:50:22 -04:00

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 id to 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 MATCH against the intended id avoids 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 through params, and use $name in 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 LIMIT on exploratory queries. Returning the whole graph kills latency and burns tokens.

Common syntax pitfalls

  • Node ownership is by label, not by a type property. Harper's nodes are :Prototype and :Experiment (label = ownership). Scotty's are :Infrastructure and :Incident. There is no n.type = 'harper' filter; the label is the filter. The type property only appears on Note nodes (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, use UNION or OPTIONAL 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 opportunities
    

    Use UNION when you want results from any of several structures with the same shape. Use OPTIONAL MATCH when 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.