Skill: NONE | Type: troubleshooting Summary: EPISODIO S07 — NEO4J: apostrophe plus-sign at-sign in entity names break Cypher
2.6 KiB
| episode_id | puente_flat | session_code | acto_dialogico | actor_flujo | criticidad_aegis | skill_dominante | fase_proyecto | tipo_semantico | summary_one_line | source_type | trust_boundary | created_at | relectura_tagged | forgejo_commit_sha |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 7df3e811-e95a-474f-a896-73bcf70cbeba | TRAZA_neo4j-special-chars-cypher-merge_S20260413.R7_FJ.imp.3.hot_arg.pr.cc.en.DR0.MPQ_J.PFDFK_E.SGNZD | S20260413 | argumentar | multi_actor | moderate | NONE | implementation | troubleshooting | EPISODIO S07 — NEO4J: apostrophe plus-sign at-sign in entity names break Cypher | chat_ember | private | 2026-04-13T12:55:32.036742+00:00 | false | pending |
The CRISOL F5b phase creates Neo4j graph nodes for canonical entities mentioned in each episode. The current implementation uses Cypher MERGE statements to create or match entity nodes. A design decision is needed about how to handle entity names that contain characters requiring escaping in Cypher query language.
Three test entities expose the problem. First, the entity O'Reilly Media contains an apostrophe. When the F5b code generates MERGE (e:Entity {name: 'O'Reilly Media'}), the unescaped apostrophe terminates the string literal prematurely, causing a Cypher SyntaxError. Second, the entity C++ Runtime contains plus signs which are valid in Cypher strings but could cause issues in URL-encoded graph API calls. Third, the entity test@ember.ai contains an at-sign which is valid in Cypher but triggers email detection heuristics in some NLP preprocessing pipelines.
The design decision evaluates three approaches. Approach A: escape special characters in entity names before MERGE, using Neo4j parameter binding ($props.name instead of string interpolation). This is the recommended approach because it delegates escaping to the Neo4j driver, handles all edge cases, and follows the same principle as parameterized SQL queries. Approach B: normalize entity names by stripping special characters before storing in Neo4j. Rejected because it loses information and creates a divergence between Neo4j entity names and LEXICON preferred_labels. Approach C: URL-encode entity names. Rejected because it makes graph queries unreadable and breaks pattern matching.
Decision: Implement Approach A. The F5b code in crisol_run.py should use Neo4j driver parameter binding for all MERGE operations. The Cypher template becomes: MERGE (e:Entity {name: $name}) with parameters passed as a dictionary. This handles apostrophes, plus signs, at-signs, backslashes, and any other special character without manual escaping. The LEXICON preferred_label remains the authoritative name; Neo4j stores exact copies.