
memory-coordination
by krzemienski
SKILL.md
name: memory-coordination description: | Coordinates Serena MCP knowledge graph operations for Shannon Framework. Enforces standardized entity naming (shannon/* namespace), relation creation patterns, search protocols, and observation management. Prevents orphaned entities, naming chaos, and broken context lineage. Use when: storing specs/waves/goals/checkpoints, querying Shannon history, managing knowledge graph structure, ensuring cross-wave context preservation.
skill-type: PROTOCOL shannon-version: ">=4.0.0"
mcp-requirements: required: - name: serena version: ">=2.0.0" purpose: Knowledge graph storage for Shannon context fallback: none degradation: critical recommended: []
required-sub-skills: [] optional-sub-skills: []
allowed-tools: Serena
Memory Coordination
Overview
Purpose: Memory Coordination is Shannon's protocol for structured Serena MCP operations. It enforces standardized entity naming (shannon/* namespace), mandatory relation creation, consistent search patterns, and proper observation management to maintain a clean, queryable knowledge graph across all waves and sessions.
When to Use:
- Storing ANY Shannon artifact (spec, wave, goal, checkpoint, SITREP)
- Querying Shannon history (waves, checkpoints, specs)
- Creating entities for Shannon context preservation
- Updating existing entities with new information
- Establishing relations between Shannon entities
- Searching Shannon knowledge graph
Expected Outcomes:
- Standardized entity names with shannon/* namespace
- Complete relational graph (no orphaned entities)
- Efficient queries using consistent patterns
- Cross-wave context preservation
- Zero data duplication via observations
- Clean knowledge graph structure
Duration: 10-30 seconds per operation
Anti-Rationalization (From Baseline Testing)
CRITICAL: Agents systematically rationalize skipping memory-coordination protocols. Below are the 6 most common rationalizations detected in baseline testing, with mandatory counters.
Rationalization 1: "Entity name seems fine"
Example: Agent creates entity named "spec_data" or "MyAnalysis" without shannon/ prefix
COUNTER:
- ❌ NEVER create Shannon entities without shannon/* namespace
- ✅ ALL Shannon entities MUST start with shannon/
- ✅ Use standard namespaces: shannon/specs/, shannon/waves/, shannon/goals/, shannon/checkpoints/, shannon/sitreps/
- ✅ If name lacks shannon/ prefix, it's WRONG
Rule: All Shannon entities have shannon/* namespace. No exceptions.
Rationalization 2: "Relations not needed for this entity"
Example: Agent creates wave entity without relating it to spec
COUNTER:
- ❌ NEVER create standalone Shannon entities
- ✅ EVERY entity has at least 1 relation (usually to parent or creator)
- ✅ Spec -> spawns -> Wave, Wave -> contains -> Task, Wave -> created_checkpoint -> Checkpoint
- ✅ Orphaned entities = broken context lineage
Rule: Create relations. Every entity connects to graph.
Rationalization 3: "Search query seems reasonable"
Example: Agent searches with random queries: "wave", "Wave 1", "waves", "show waves"
COUNTER:
- ❌ NEVER use free-form search queries for Shannon entities
- ✅ Use EXACT search patterns defined in this skill
- ✅ Search specs: search_nodes("shannon/specs/")
- ✅ Search waves: search_nodes("shannon/waves/")
- ✅ Consistency = efficiency
Rule: Use protocol search patterns. Not creative queries.
Rationalization 4: "Create new entity for update"
Example: Agent creates "spec_002" to update "spec_001" instead of adding observations
COUNTER:
- ❌ NEVER create new entity to update existing entity
- ✅ Use add_observations for updates
- ✅ Creating duplicate entities = data chaos
- ✅ Example: WRONG: create_entities("spec_002"), RIGHT: add_observations("spec_001", ["new info"])
Rule: Updates use add_observations, not create_entities.
Rationalization 5: "Namespace collision unlikely"
Example: Agent creates "goal" entity in root namespace (not shannon/goals/)
COUNTER:
- ❌ NEVER create Shannon entities in root namespace
- ✅ shannon/* namespace prevents collision with user project entities
- ✅ User might have "goal" entity for their app -> collision = corruption
- ✅ shannon/goals/goal_001 = isolated, safe
Rule: shannon/* namespace mandatory. Prevents collisions.
Rationalization 6: "Manual filtering faster than search"
Example: Agent calls read_graph() then manually filters for waves
COUNTER:
- ❌ NEVER read full graph then filter manually
- ✅ Use search_nodes() with namespace prefix (efficient, targeted)
- ✅ read_graph() loads ENTIRE graph (100-1000+ entities)
- ✅ search_nodes("shannon/waves/") returns only waves (5-20 entities)
- ✅ Manual filtering = wasted tokens + time
Rule: Use search_nodes with namespace. Never read_graph for queries.
Detection Signal
If you're tempted to:
- Create entity without shannon/ prefix
- Skip creating relations
- Use custom search query
- Create new entity for update
- Use root namespace
- Read full graph then filter
Then you are rationalizing. Stop. Apply the protocol. Follow the rules.
When to Use
Use this skill when:
- Storing Shannon artifacts: Specs, waves, goals, checkpoints, SITREPs
- Querying Shannon history: "Show me all waves", "Find spec for this wave"
- Creating Shannon entities: Any Shannon data needs persistence
- Updating Shannon entities: Wave status change, checkpoint metadata update
- Establishing relations: Link wave to spec, checkpoint to wave, goal to spec
- Searching Shannon graph: Find entities by namespace, type, or timestamp
- Context preservation: Before wave transitions, session end, context limits
- SITREP coordination: Storing multi-agent progress reports
DO NOT use when:
- Storing user project data (use user namespace, not shannon/*)
- Non-Shannon workflows (generic Serena operations)
- Temporary data that doesn't need persistence
- Data that should be in project files instead of knowledge graph
Inputs
Required:
operation_type(string): Serena operation to perform- Options:
"create","read","update","search","relate","delete"
- Options:
entity_data(object): Data for the operation{ "type": "spec" | "wave" | "goal" | "checkpoint" | "sitrep" | "task", "data": { "complexity_score": 0.68, "domain_percentages": {...}, "execution_strategy": "wave-based" }, "timestamp": "20250104_143022" }
Optional (operation-specific):
entity_name(string): For read/update/delete operations- Example:
"shannon/specs/spec_20250104_143022"
- Example:
search_pattern(string): For search operations- Example:
"shannon/waves/"(all waves) - Example:
"shannon/checkpoints/cp_20250104"(date-filtered)
- Example:
parent_entity(string): For create operations (establishes relation)- Example:
"shannon/specs/spec_001"(wave's parent)
- Example:
relation_type(string): For relate operations- Options:
"spawns","contains","tracks","created_checkpoint","implements","reports_on","relates_to"
- Options:
observations(array): For create/update operations- Example:
["type: spec_analysis", "created: 2025-01-04T14:30:22Z", "complexity_score: 0.68"]
- Example:
Core Competencies
1. Shannon Namespace Management
- Namespace Structure: shannon/specs/, shannon/waves/, shannon/goals/, shannon/checkpoints/, shannon/sitreps/
- Entity Naming: Standardized formats with timestamps or IDs
- Collision Prevention: shannon/* isolates Shannon entities from user project
- Queryability: Namespace prefix enables efficient targeted searches
- Organization: Clear hierarchy (specs -> waves -> tasks -> checkpoints)
2. Entity CRUD Operations
- Create: create_entities with shannon/* namespace, initial observations
- Read: search_nodes or open_nodes with specific entity names
- Update: add_observations to existing entities (NEVER create new entity)
- Delete: delete_entities (rare, only for cleanup or mistakes)
- Validation: Verify entity name format before creation
3. Relation Management
- Standard Relations: spawns, contains, tracks, created_checkpoint, implements, relates_to
- Mandatory Relations: EVERY entity connects to at least 1 other entity
- Relation Naming: Active voice (spec "spawns" wave, wave "contains" task)
- Bidirectional Context: Relations enable traversal (wave -> spec, checkpoint -> wave)
- Orphan Prevention: No standalone entities
4. Search Patterns
- Namespace Search: search_nodes("shannon/specs/") for all specs
- Specific Entity: open_nodes(["shannon/specs/spec_001"]) for exact entity
- Pattern Matching: search_nodes("shannon/waves/wave_2025") for date-filtered waves
- Never Full Graph: Avoid read_graph() except for full visualization
- Result Limits: Use search efficiently, narrow queries
5. Observation Management
- Initial Observations: Include type, creation_date, purpose, metadata
- Updates: add_observations for new information (status, progress, notes)
- No Duplicates: Never create new entity to update (use observations)
- Structured Data: Store JSON or key-value pairs in observations
- Timestamped: Include timestamp in observation content
Workflow
Step 1: Determine Entity Type
Input: Data to store (spec, wave, goal, checkpoint, SITREP)
Processing:
-
Identify entity type from data structure or user intent
- If ambiguous, check context:
- In spec analysis phase? -> shannon/specs/
- Tracking wave progress? -> shannon/waves/
- Setting goals? -> shannon/goals/
- If still unclear, ASK USER: "Should I store this as spec, wave, goal, or checkpoint?"
- NEVER default to root namespace or random name
- If ambiguous, check context:
-
Map to Shannon namespace:
- Specification -> shannon/specs/
- Wave -> shannon/waves/
- Goal -> shannon/goals/
- Checkpoint -> shannon/checkpoints/
- SITREP -> shannon/sitreps/
- Task -> shannon/tasks/ (usually nested under wave)
-
Generate timestamp (MANDATORY FORMAT):
- Format: YYYYMMdd_HHmmss
- Example: 20250104_143022 (2025-01-04 14:30:22)
- WHY: Sortable (alphabetical = chronological), consistent, query-safe
const timestamp = new Date().toISOString() .replace(/[-:]/g, '') .replace('T', '_') .split('.')[0]; // Result: 20250104_143022- NEVER use: ISO 8601 in name, human-readable dates, Unix timestamps
-
Sanitize entity name:
- Replace spaces with underscores: "E-commerce / Payment" -> "E-commerce_Payment"
- Remove forward slashes: "/" -> ""
- Lowercase: "Gateway" -> "gateway"
- Final: shannon/specs/e-commerce_payment_gateway_20250104_143022
- NEVER include spaces or "/" in entity names (breaks queries)
Output: Full entity name (e.g., shannon/specs/spec_20250104_143022)
Duration: 1 second
Step 2: Create Entity with Standard Format
Input: Entity name, entity type, data
Processing:
- Structure observations as list of strings:
[ "type: [entity_type]", "created: [ISO timestamp]", "purpose: [description]", "[key]: [value]", "[serialized JSON if complex data]" ] - Call create_entities:
create_entities({ entities: [{ name: "shannon/specs/spec_20250104_143022", entityType: "Specification", observations: [ "type: spec_analysis", "created: 2025-01-04T14:30:22Z", "complexity_score: 0.68", "domain: Frontend 38%, Backend 35%, Database 27%", "execution_strategy: wave-based", "JSON: {...full analysis...}" ] }] }) - Verify creation successful
Output: Entity created, entity name
Duration: 2-3 seconds
Step 3: Create Mandatory Relations
Input: New entity name, related entities
Processing:
-
Identify parent or related entities:
- Spec -> None (root entity)
- Wave -> Spec (spawned from)
- Task -> Wave (contained in)
- Checkpoint -> Wave (created during)
- Goal -> Spec (implements)
- SITREP -> Wave (reports on)
-
Determine relation type (active voice) with VALIDATION: APPROVED RELATION TYPES:
- spawns (spec -> wave)
- contains (wave -> task)
- created_checkpoint (wave -> checkpoint)
- implements (goal -> spec)
- reports_on (sitrep -> wave)
- tracks (goal -> wave)
- relates_to (general purpose)
VALIDATION (prevent typos):
const approved = ["spawns", "contains", "created_checkpoint", "implements", "reports_on", "tracks", "relates_to"]; if (!approved.includes(relationType)) { throw Error(`Invalid relationType: ${relationType}. Use one of: ${approved.join(', ')}`); } -
Call create_relations: For SINGLE entity:
create_relations({ relations: [{ from: "shannon/specs/spec_001", to: "shannon/waves/wave_001", relationType: "spawns" }] })For BULK operations (50+ entities):
// Create ALL relations in ONE call (not 50 separate calls) create_relations({ relations: [ {from: "shannon/waves/wave_001", to: "shannon/tasks/task_001", relationType: "contains"}, {from: "shannon/waves/wave_001", to: "shannon/tasks/task_002", relationType: "contains"}, // ... 48 more relations ] }) -
Verify relation created
Output: Relations established, connected graph
Duration: 1-2 seconds
Step 4: Search Using Standard Patterns
Input: Query intent (e.g., "find all waves", "get spec_001", "list checkpoints")
Processing:
-
Map intent to search pattern:
- "All [type]" -> search_nodes("shannon/[type]s/")
- "Specific entity" -> open_nodes(["shannon/[type]s/[name]"])
- "Recent [type]" -> search_nodes("shannon/[type]s/[date_pattern]")
-
Execute search with NAMESPACE PRECISION:
// CORRECT: Full namespace search_nodes("shannon/waves/") open_nodes(["shannon/specs/spec_20250104_143022"]) // CORRECT: Recent checkpoints (2025-01-04) search_nodes("shannon/checkpoints/cp_20250104") // WRONG: Partial match (might hit user entities) search_nodes("spec_") // ❌ Could match user project entity "spec_data" search_nodes("wave") // ❌ Ambiguous, no namespace // WRONG: Root namespace query search_nodes("spec_001") // ❌ Missing shannon/specs/ prefixRULE: Always use FULL shannon/* path. Never partial match.
-
Parse results
Output: Matching entities with observations
Duration: 1-2 seconds
Step 5: Update via Observations
Input: Entity name, new information
Processing:
-
MANDATORY VERIFICATION (prevent errors):
// ALWAYS verify entity exists BEFORE add_observations const entity = open_nodes(["shannon/waves/wave_001"]); if (!entity || entity.length === 0) { throw Error("Cannot update: entity shannon/waves/wave_001 not found"); }If entity missing:
- Create it first (if should exist)
- Report error to user (if unexpected)
-
Structure new observations:
[ "updated: [ISO timestamp]", "status: [new status]", "[new_key]: [new_value]" ] -
Call add_observations:
add_observations({ observations: [{ entityName: "shannon/waves/wave_001", contents: [ "updated: 2025-01-04T15:00:00Z", "status: Phase 2 complete", "progress: 60%", "next_action: Begin Phase 3 implementation" ] }] }) -
OBSERVATION LIMITS (prevent overflow):
- Maximum ~100 observations per entity (guideline)
- If approaching limit, consider:
- Creating checkpoint entity (snapshot current state)
- Creating sub-entities (wave_001_phase2, wave_001_phase3)
- Archiving old observations (delete_observations)
- WHY: Large lists slow queries, hard to parse
- Better: Structured sub-entities with relations
-
Verify update successful
Output: Entity updated with new observations
Duration: 2-3 seconds
Step 6: Validate Graph Structure
Input: Recent operations
Processing:
-
Check entity naming:
- All Shannon entities have shannon/* prefix? ✅
- No typos in namespace (shannon/spec/ instead of shannon/specs/)? ✅
-
Check relations:
- Every new entity has >=1 relation? ✅
- Relations use active voice? ✅
- No orphaned entities? ✅
-
Check operations:
- Used add_observations for updates (not create_entities)? ✅
- Used search_nodes (not read_graph) for queries? ✅
- No duplicate entities? ✅
Output: Validation pass/fail, corrections if needed
Duration: 5 seconds
MCP Integration
Required MCPs
Serena MCP (MANDATORY)
- Purpose: Shannon's primary context preservation mechanism; stores all specs, waves, goals, checkpoints in persistent knowledge graph
- Usage:
// Create entity create_entities({ entities: [{ name: "shannon/specs/spec_001", entityType: "Specification", observations: ["type: spec_analysis", "created: 2025-01-04T14:30:22Z"] }] }) // Create relation create_relations({ relations: [{ from: "shannon/specs/spec_001", to: "shannon/waves/wave_001", relationType: "spawns" }] }) // Search const specs = search_nodes("shannon/specs/") const wave = open_nodes(["shannon/waves/wave_001"]) // Update add_observations({ observations: [{ entityName: "shannon/waves/wave_001", contents: ["status: Phase 2 complete", "progress: 60%"] }] }) - Fallback: NONE (Serena is mandatory for Shannon)
- Degradation: CRITICAL (Shannon cannot function without context preservation)
- Verification: Test with search_nodes("shannon/") - should return Shannon entities
Examples
Example 1: Store Spec Analysis
Input: Spec analysis complete (complexity 0.68, Frontend 38%, Backend 35%, Database 27%)
Execution:
Step 1: Determine entity type
-> Type: Specification
-> Namespace: shannon/specs/
-> Entity name: shannon/specs/spec_20250104_143022
Step 2: Create entity
-> create_entities({
entities: [{
name: "shannon/specs/spec_20250104_143022",
entityType: "Specification",
observations: [
"type: spec_analysis",
"created: 2025-01-04T14:30:22Z",
"complexity_score: 0.68",
"interpretation: Complex",
"domains: Frontend 38%, Backend 35%, Database 27%",
"execution_strategy: wave-based",
"recommended_waves: 3-7",
"recommended_agents: 8-15",
"timeline: 2-4 days",
"JSON: {\"complexity_score\":0.68,\"dimensions\":{...},\"domain_percentages\":{...}}"
]
}]
})
Step 3: Create relations
-> No parent (spec is root entity)
-> Relations will be created when waves spawn from this spec
Step 4: Verify creation
-> open_nodes(["shannon/specs/spec_20250104_143022"])
-> ✅ Entity exists with all observations
Output: Spec stored as shannon/specs/spec_20250104_143022, ready to spawn waves
Example 2: Create Wave from Spec
Input: Starting Wave 1 for spec_20250104_143022
Execution:
Step 1: Determine entity type
-> Type: Wave
-> Namespace: shannon/waves/
-> Entity name: shannon/waves/wave_20250104_150000
Step 2: Create entity
-> create_entities({
entities: [{
name: "shannon/waves/wave_20250104_150000",
entityType: "Wave",
observations: [
"type: wave",
"wave_number: 1",
"created: 2025-01-04T15:00:00Z",
"spec_id: shannon/specs/spec_20250104_143022",
"phase: Phase 2 - Architecture & Design",
"status: in_progress",
"agents: 8",
"start_time: 2025-01-04T15:00:00Z"
]
}]
})
Step 3: Create relations
-> Parent: shannon/specs/spec_20250104_143022
-> Relation: spec "spawns" wave
-> create_relations({
relations: [{
from: "shannon/specs/spec_20250104_143022",
to: "shannon/waves/wave_20250104_150000",
relationType: "spawns"
}]
})
Step 4: Verify
-> open_nodes(["shannon/waves/wave_20250104_150000"])
-> search_nodes("shannon/waves/") shows wave_20250104_150000
-> ✅ Wave created and linked to spec
Output: Wave 1 created, linked to spec via "spawns" relation
Example 3: Query Wave History
Input: User asks "Show me all waves for current project"
Execution:
Step 1: Map query to search pattern
-> Intent: All waves
-> Pattern: search_nodes("shannon/waves/")
Step 2: Execute search
-> search_nodes("shannon/waves/")
-> Returns:
- shannon/waves/wave_20250104_150000
- shannon/waves/wave_20250104_170000
- shannon/waves/wave_20250105_090000
Step 3: Fetch details (if needed)
-> open_nodes([
"shannon/waves/wave_20250104_150000",
"shannon/waves/wave_20250104_170000",
"shannon/waves/wave_20250105_090000"
])
Step 4: Parse observations
-> Wave 1: Phase 2, status: complete
-> Wave 2: Phase 3, status: complete
-> Wave 3: Phase 4, status: in_progress
Step 5: Format output
-> "Wave History:
- Wave 1 (2025-01-04 15:00): Phase 2 complete
- Wave 2 (2025-01-04 17:00): Phase 3 complete
- Wave 3 (2025-01-05 09:00): Phase 4 in progress"
Output: Complete wave history with status, fetched efficiently using namespace search
Example 4: Update Wave Status
Input: Wave 1 completed Phase 2, moving to Phase 3
Execution:
Step 1: Identify entity
-> Entity: shannon/waves/wave_20250104_150000
Step 2: Structure update observations
-> [
"updated: 2025-01-04T16:30:00Z",
"status: complete",
"phase_completed: Phase 2 - Architecture & Design",
"next_phase: Phase 3 - Implementation",
"deliverables: Architecture diagrams, API specs, DB schemas",
"validation_gate: ✅ Design approved, patterns established"
]
Step 3: Add observations (NOT create new entity)
-> add_observations({
observations: [{
entityName: "shannon/waves/wave_20250104_150000",
contents: [
"updated: 2025-01-04T16:30:00Z",
"status: complete",
"phase_completed: Phase 2 - Architecture & Design",
"next_phase: Phase 3 - Implementation",
"deliverables: Architecture diagrams, API specs, DB schemas",
"validation_gate: ✅ Design approved, patterns established"
]
}]
})
Step 4: Verify update
-> open_nodes(["shannon/waves/wave_20250104_150000"])
-> ✅ Entity has new observations appended
-> ✅ NO duplicate entity created
Output: Wave 1 updated with completion status, no data duplication
Example 5: Create Checkpoint with Relations
Input: Create checkpoint at end of Wave 1
Execution:
Step 1: Determine entity type
-> Type: Checkpoint
-> Namespace: shannon/checkpoints/
-> Entity name: shannon/checkpoints/cp_20250104_163000
Step 2: Create entity
-> create_entities({
entities: [{
name: "shannon/checkpoints/cp_20250104_163000",
entityType: "Checkpoint",
observations: [
"type: checkpoint",
"created: 2025-01-04T16:30:00Z",
"wave_id: shannon/waves/wave_20250104_150000",
"phase: Phase 2 complete",
"status: Validated",
"files: [list of checkpoint files]",
"context: Architecture design complete, moving to implementation"
]
}]
})
Step 3: Create relations
-> Parent: shannon/waves/wave_20250104_150000
-> Relation: wave "created_checkpoint" checkpoint
-> create_relations({
relations: [{
from: "shannon/waves/wave_20250104_150000",
to: "shannon/checkpoints/cp_20250104_163000",
relationType: "created_checkpoint"
}]
})
Step 4: Verify
-> open_nodes(["shannon/checkpoints/cp_20250104_163000"])
-> ✅ Checkpoint created
-> ✅ Relation exists: wave -> checkpoint
-> ✅ Can trace checkpoint -> wave -> spec lineage
Output: Checkpoint created and linked to wave, context lineage preserved
Outputs
Operation result object:
{
"operation": "create" | "read" | "update" | "search" | "relate" | "delete",
"success": true,
"entity_name": "shannon/specs/spec_20250104_143022",
"entity_type": "Specification",
"observations": [
"type: spec_analysis",
"created: 2025-01-04T14:30:22Z",
"complexity_score: 0.68",
"domains: Frontend 40%, Backend 35%, Database 25%"
],
"relations": [
{
"from": "shannon/specs/spec_20250104_143022",
"to": "shannon/waves/wave_20250104_150000",
"type": "spawns"
}
],
"validation": {
"namespace_correct": true,
"relations_exist": true,
"format_valid": true,
"no_duplicates": true
},
"lineage": {
"parent": "shannon/specs/spec_20250104_143022",
"children": ["shannon/waves/wave_20250104_150000"],
"depth": 2
}
}
Success Criteria
Successful when:
- ✅ All Shannon entities have shannon/* namespace prefix
- ✅ Entity names follow standard format (shannon/[type]s/[name]_[timestamp])
- ✅ Every entity has at least 1 relation (no orphans)
- ✅ Relations use active voice (spawns, contains, tracks)
- ✅ Updates use add_observations (not create_entities)
- ✅ Searches use namespace prefix (search_nodes("shannon/specs/"))
- ✅ No duplicate entities (same data in multiple entities)
- ✅ Graph structure supports lineage queries (checkpoint -> wave -> spec)
- ✅ Observations structured with timestamps and key-value pairs
- ✅ Validation confirms all protocols followed
Fails if:
- ❌ Entity created without shannon/ prefix (namespace violation)
- ❌ Entity created without relations (orphaned)
- ❌ Relations use passive voice or unclear naming
- ❌ Update creates new entity instead of add_observations (duplication)
- ❌ Search uses read_graph() for targeted query (inefficiency)
- ❌ Duplicate entities exist for same data
- ❌ Cannot trace lineage (broken relations)
- ❌ Observations unstructured or missing timestamps
- ❌ Namespace collision with user project entities
- ❌ Custom entity naming breaks conventions
Validation Code:
def validate_memory_coordination(result):
"""Verify memory coordination followed protocols"""
# Check: shannon/* namespace
entity_name = result.get("entity_name", "")
assert entity_name.startswith("shannon/"), \
f"VIOLATION: Entity missing shannon/ prefix: {entity_name}"
# Check: Standard namespace (specs, waves, goals, checkpoints, sitreps, tasks)
valid_namespaces = ["shannon/specs/", "shannon/waves/", "shannon/goals/",
"shannon/checkpoints/", "shannon/sitreps/", "shannon/tasks/"]
assert any(entity_name.startswith(ns) for ns in valid_namespaces), \
f"VIOLATION: Invalid namespace: {entity_name}"
# Check: Relations exist (unless root spec)
if result.get("operation") == "create" and "specs" not in entity_name:
relations = result.get("relations", [])
assert len(relations) >= 1, \
"VIOLATION: Entity created without relations (orphaned)"
# Check: Relations use approved types
approved_relations = ["spawns", "contains", "created_checkpoint",
"implements", "reports_on", "tracks", "relates_to"]
for relation in result.get("relations", []):
assert relation["type"] in approved_relations, \
f"VIOLATION: Invalid relation type: {relation['type']}"
# Check: Observations have timestamps
observations = result.get("observations", [])
has_timestamp = any("created:" in obs or "updated:" in obs for obs in observations)
assert has_timestamp, \
"VIOLATION: Observations missing timestamp"
# Check: No duplicate entities (same data in multiple entities)
validation = result.get("validation", {})
assert validation.get("no_duplicates") == True, \
"VIOLATION: Duplicate entities detected"
# Check: Lineage traceable
lineage = result.get("lineage", {})
if "specs" not in entity_name: # Non-root entities
assert lineage.get("parent") is not None, \
"VIOLATION: Cannot trace lineage (broken relations)"
return True
Common Pitfalls
Pitfall 1: Missing shannon/ Prefix
Problem: Agent creates "spec_001" instead of "shannon/specs/spec_001"
Why It Fails:
- Namespace collision with user project entities (user might have "spec_001" entity)
- Cannot query all Shannon entities efficiently (search_nodes("shannon/") fails)
- Breaks Shannon isolation from project
Solution: ALWAYS prefix with shannon/[type]s/ (specs, waves, goals, checkpoints, sitreps)
Prevention: Validation rejects entities without shannon/ prefix
Pitfall 2: Orphaned Entities
Problem: Agent creates wave entity but forgets to link to parent spec
Why It Fails:
- Cannot trace wave -> spec lineage
- Cannot answer "which spec spawned this wave?"
- Context restoration impossible
Solution: EVERY entity MUST have >=1 relation (except root specs)
Prevention: Step 3 mandatory relation creation, validation checks
Pitfall 3: Update Creates Duplicate
Problem: Agent creates "spec_002" to update "spec_001" instead of adding observations
Why It Fails:
- Data duplication (two entities with overlapping information)
- Queries return multiple results (which is correct?)
- Graph pollution
Solution: Use add_observations for updates, NOT create_entities
Prevention: Skill emphasizes update protocol, anti-rationalization section
Pitfall 4: Inefficient Search
Problem: Agent calls read_graph() then manually filters for waves
Why It Fails:
- Loads entire graph (100-1000+ entities) when only need 5-20 waves
- Wastes tokens and time
- Unnecessary network traffic
Solution: Use search_nodes("shannon/waves/") for targeted query
Prevention: Step 4 search patterns, avoid read_graph() for queries
Pitfall 5: Inconsistent Entity Naming
Problem: Agent creates shannon/specs/spec_001, shannon/specs/specification_002, shannon/specs/my_spec_3
Why It Fails:
- Inconsistent patterns hard to query (search_nodes("shannon/specs/spec_") misses "specification_")
- Breaks naming conventions
- Confusion about entity type
Solution: Standardize: shannon/specs/spec_[timestamp] or shannon/specs/spec_[id]
Prevention: Step 1 entity naming protocol, examples show standard format
Pitfall 6: Missing Timestamps
Problem: Agent creates observations without timestamps (["status: complete", "progress: 100%"])
Why It Fails:
- Cannot determine WHEN update happened
- Cannot trace progress timeline
- Loses historical context
Solution: ALWAYS include timestamp in observations: ["updated: 2025-01-04T16:30:00Z", "status: complete"]
Prevention: Step 2 and Step 5 observation format includes timestamps
Validation
How to verify memory-coordination executed correctly:
-
Check Entity Names:
- search_nodes("shannon/") returns only Shannon entities ✅
- All entity names have shannon/[type]s/ prefix ✅
- No entities in root namespace with Shannon data ✅
-
Check Relations:
- Query entity -> Verify >=1 relation exists ✅
- Relations use active voice (spawns, contains, tracks) ✅
- Can trace lineage: checkpoint -> wave -> spec ✅
-
Check Operations:
- Updates used add_observations (not create_entities) ✅
- No duplicate entities (same data in multiple entities) ✅
- Searches used namespace prefix (not read_graph()) ✅
-
Check Observations:
- All observations have timestamps ✅
- Observations structured as key-value or JSON ✅
- Latest observations at end of list ✅
-
Test Queries:
- search_nodes("shannon/specs/") returns only specs ✅
- search_nodes("shannon/waves/") returns only waves ✅
- open_nodes(["shannon/specs/spec_001"]) returns specific spec ✅
- Queries execute in <2 seconds ✅
-
Test Lineage:
- Given checkpoint -> Can find parent wave ✅
- Given wave -> Can find parent spec ✅
- Given wave -> Can find all child tasks ✅
- Given spec -> Can find all spawned waves ✅
Progressive Disclosure
SKILL.md (This file): ~600 lines
- Overview, when to use, expected outcomes
- Anti-rationalization (6 violations with counters)
- 5 core competencies (namespace, CRUD, relations, search, observations)
- 6-step workflow (determine type, create, relate, search, update, validate)
- 5 examples (store spec, create wave, query history, update status, checkpoint)
- Success criteria, common pitfalls, validation
references/: No deep references needed (protocol is self-contained)
Claude loads references/ when: N/A (all protocol details in SKILL.md)
References
- Serena MCP documentation: https://github.com/cyanheads/serena-mcp
- Shannon context management: shannon-plugin/core/CONTEXT_MANAGEMENT.md
- Checkpoint protocols: shannon-plugin/skills/context-preservation/SKILL.md
- Wave orchestration: shannon-plugin/skills/wave-orchestration/SKILL.md
Metadata
Version: 4.0.0 Last Updated: 2025-11-04 Author: Shannon Framework Team License: MIT Status: Core (Protocol skill, mandatory for Serena MCP operations)
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon