Orchestrata Ultimate / Specs / 021-opencode-integration

021-opencode-integration: OpenCode Integration

A comprehensive TypeScript plugin (3,234 lines) and supporting agents, tools, and commands that integrate OpenCode with the Orchestrata project. The plugin provides session management, code quality enforcement via a 5-gate review pipeline, deception detection, knowledge graph context injection, conversation tracking, and 24 custom tools accessible from within OpenCode sessions.

At a glance

Item Value
Spec directory specs/021-opencode-integration/
Status line in the spec Complete
Requirement IDs defined 295
With a @traces citation in src/ 13 (4.4%)
With a @traces citation in tests/ 8 (2.7%)
Tracked files 6
RTM page 021-opencode-integration

Reading this spec

The OpenCode Integration connects the OpenCode coding assistant to the Orchestrata project. It is a TypeScript plugin plus supporting agents, tools and commands that provide session management, code quality enforcement through a 5-gate review pipeline, deception detection, knowledge graph context injection, conversation tracking and 24 custom tools available inside OpenCode sessions.

The spec gives these reasons: OpenCode needs project-specific intelligence to work with the monorepo, knowledge graph context is injected automatically, quality standards (no mocking, absolute imports, short functions, snake_case) need enforcement at edit time, session lifecycle must be tracked consistently across Claude Code and OpenCode through the same context.json, and LLMs sometimes claim actions they did not perform.

The scope is a set of actor-driven user stories (labelled US-021-nn, each naming the functional requirements it exercises) and sixteen or more functional requirements: plugin lifecycle hooks, session auto-start and auto-end, knowledge graph context injection, the 5-gate review pipeline, error blocking, deception detection, policy enforcement, custom tool availability, project scoping of knowledge graph queries, Redis queue management, memory search, read throttling, git checkpoints, conversation storage and a knowledge graph sync daemon. Requirement IDs use the REQ-021- prefix.

The design is a single plugin, orchestrata.ts, exporting OrchestrataPlugin and hooking 7 OpenCode lifecycle events. Two OpenCode agents provide automatic and manual context injection, one slash command (/query-kg) runs interactive Cypher queries, and five Python tools query Neo4j with project scoping.

The plugin itself is TypeScript, so the Python trace table covers only supporting code, mostly orchestrata_ultimate/knowledge_graph/conversation_consumer, with orchestrata_ultimate/tools/conversation_tools and orchestrata_ultimate/kernel/cli_main. The per-requirement view is on the RTM page.

The spec's status line reads Complete. It tracks 6 files and defines 295 requirement IDs. The full text follows below.

Measured coverage is 13 of 295 requirements cited by at least one @traces in src/ (4.4%), spread over 5 modules; the module citing the most of them is orchestrata_ultimate/knowledge_graph/conversation_consumer (12 requirements). In tests/, 8 requirements are cited by a test-side @traces.

Coverage gaps: 282 requirements have no citing symbol. The largest untraced groups are REQ-021-* (282). Untraced means no @traces names the ID; the behaviour may still exist in code that was never annotated. Test-side citations are thinner than code-side ones (8 against 13).

Requirements

Checkbox is the state recorded in the requirements checklist; Traced by is the count of src/ symbols whose @traces names the ID.

ID Done Requirement Traced by
REQ-021-001 no KG context lookup triggered on read tool execution for Orchestrata project files none
REQ-021-002 no KG context lookup triggered on grep tool execution for Orchestrata project files none
REQ-021-003 no File path extracted from args.filePath or args.path for KG lookup none
REQ-021-004 no KG context retrieved via KnowledgeGraphContext.get_file_context() Python call 2
REQ-021-005 no Context injected as args._orchestrata_context with kg_context and source: "neo4j" fields none
REQ-021-006 no KG context injection is non-blocking (try/catch with empty catch) none
REQ-021-007 no Missing file path gracefully skipped (early return if no filePath) none
REQ-021-008 no Empty KG context (whitespace-only) not injected into args none
REQ-021-009 no KG context Python subprocess runs with 2>/dev/null error suppression none
REQ-021-010 no KG context lookup scoped to ${PROJECT_ROOT} working directory none
REQ-021-011 no Agent activates on direct file path references (/home/mohamed/workspace/orchestrata/...) none
REQ-021-012 no Agent activates on relative path references (packages/orchestrata-core/src/...) none
REQ-021-013 no Agent activates on class name references (TraceabilityModule, Neo4jClient) none
REQ-021-014 no Agent activates on function name references (create_file_node, query_neo4j) none
REQ-021-015 no Agent activates on spec ID references (SPEC-001, 001-kernel) none
REQ-021-016 no Agent activates on requirement ID references (REQ-001, REQ-004-US-001-NNN — placeholder shape; a literal foreign id here would read as this spec claiming another spec's requirement to the cross-spec uniqueness gate) none
REQ-021-017 no Agent activates on user story references (US-001, User Story 001) none
REQ-021-018 no Agent queries file basic info (path, language, line_count, size_bytes) none
REQ-021-019 no Agent queries classes defined in file (name, line_start, line_end) none
REQ-021-020 no Agent queries functions defined in file (name, line_start, line_end, is_async) none
REQ-021-021 no Agent queries traceability links (code type, name, requirement_id, requirement_text) none
REQ-021-022 no Agent queries inheritance hierarchy (child to ancestors, depth 3) none
REQ-021-023 no Agent queries entity by name with CONTAINS and exact match none
REQ-021-024 no Agent queries inbound and outbound relationships (limit 10 each) none
REQ-021-025 no Agent connects to the operational KG (Memgraph) at the active env profile's endpoint (test fleet: bolt://10.53.2.10:7687) none
REQ-021-026 no Agent uses the orchkg database name none
REQ-021-027 no Agent activates on file, class, and function mentions none
REQ-021-028 no Agent activates on code structure and relationship questions none
REQ-021-029 no Agent activates on refactoring requests none
REQ-021-030 no Agent activates on specification and requirement inquiries none
REQ-021-031 no Agent uses /query-kg tool internally for Cypher execution none
REQ-021-032 no Agent provides file-to-class and file-to-function mappings none
REQ-021-033 no Agent provides inheritance hierarchies (depth 2) none
REQ-021-034 no Agent provides code-to-requirement traceability links none
REQ-021-035 no Agent runs transparently without explicit user invocation none
REQ-021-036 no Check existing session via session_cli.py status --json none
REQ-021-037 no Resume existing session if active (log "Resumed existing session N") none
REQ-021-038 no Begin new session if none active with purpose "OpenCode session HH:MM" none
REQ-021-039 no Update project state to ACTIVE via session_cli.py update-state --status ACTIVE none
REQ-021-040 no Display session banner with seq number (3-digit padded) none
REQ-021-041 no Display session focus (purpose) if available none
REQ-021-042 no Display project version from state none
REQ-021-043 no Display git branch from state none
REQ-021-044 no Display test state from state none
REQ-021-045 no Display total session count none
REQ-021-046 no Display pending work items (top 5 with priority prefix) none
REQ-021-047 no Show "... and N more" for pending work beyond 5 items none
REQ-021-048 no Inject session context into output.context array none
REQ-021-049 no Log session start/resume to client.app.log with sessionSeq and pendingCount none
REQ-021-050 no Trigger background KG sync only for orchestrata project directory none
REQ-021-051 no Run sync_monorepo_to_neo4j.py as detached process (nohup, /dev/null redirect) none
REQ-021-052 no KG sync start is non-blocking (catch with empty handler) none
REQ-021-053 no Log KG sync start to client.app.log none
REQ-021-054 no Check Redis queue size via redis-cli SCARD orchestrata:kg:sync:queue none
REQ-021-055 no Process queue synchronously if pending count > 0 none
REQ-021-056 no Pop files from Redis set via SPOP in loop none
REQ-021-057 no Sync each file via FileSynchronizer.sync_file() none
REQ-021-058 no Report synced count to stderr none
REQ-021-059 no Queue flush is non-blocking (try/catch) none
REQ-021-060 no Check Redis queue depth via redis-cli LLEN orchestrata:conversation:queue 2
REQ-021-061 no Process conversation queue if pending count > 0 1
REQ-021-062 no Pop turns from Redis list via LPOP in loop 4
REQ-021-063 no Parse JSON turns, skip invalid entries 4
REQ-021-064 no Group turns by session_seq none
REQ-021-065 no Create Conversation nodes with session_id opencode-{seq}, platform "opencode" 3
REQ-021-066 no Create ConversationTurn nodes with turn_id, seq, role, content, timestamp, platform 1
REQ-021-067 no Link ConversationTurn to Conversation via HAS_TURN relationship 1
REQ-021-068 no Content truncated to 2000 characters before Neo4j storage 1
REQ-021-069 no Neo4j driver connects to bolt://localhost:7687 (from environment) 6
REQ-021-070 no Conversation flush is non-blocking 3
REQ-021-071 no Extract achievements from git log --oneline --since="2 hours ago" -10 none
REQ-021-072 no Strip commit hash prefix from achievement lines none
REQ-021-073 no Take top 5 achievements none
REQ-021-074 no End session via session_cli.py end --achievements "..." none
REQ-021-075 no Archive old sessions keeping last 3 via SessionArchiver none
REQ-021-076 no Log session archive with achievement count and deception findings count none
REQ-021-077 no Clear toolCallHistory on session end none
REQ-021-078 no Reset readCount to 0 on session end none
REQ-021-079 no Session auto-end failures logged as warnings (non-blocking) none
REQ-021-080 no Run py_compile on edited file with 10-second timeout none
REQ-021-081 no Report syntax errors with first 200 characters of stderr none
REQ-021-082 no Run black --check --diff on edited file with 30-second timeout none
REQ-021-083 no Report black formatting diff (first 300 characters) none
REQ-021-084 no Run isort --check --diff on edited file with 30-second timeout none
REQ-021-085 no Report isort import ordering diff (first 300 characters) none
REQ-021-086 no All Gate 1 tools run via uv run prefix none
REQ-021-087 no Run flake8 with --select=E,F,W,C90 selectors none
REQ-021-088 no Set --max-line-length=88 for black compatibility none
REQ-021-089 no Ignore E203,W503,E501 codes none
REQ-021-090 no Fatal lint codes (E9xx, F63x, F72x) reported as errors none
REQ-021-091 no Non-fatal lint codes reported as warnings none
REQ-021-092 no Maximum 15 lint lines reported none
REQ-021-093 no Flake8 run with 30-second timeout none
REQ-021-094 no Run mypy --ignore-missing-imports --no-error-summary with 60-second timeout none
REQ-021-095 no Filter mypy output to lines containing the file path or : error: none
REQ-021-096 no Maximum 10 mypy error lines reported none
REQ-021-097 no Module import test: derive module path from packages/ structure none
REQ-021-098 no Module import test: run python3 -c "import {module}" with 30-second timeout none
REQ-021-099 no Report import errors with first 300 characters of stderr none
REQ-021-100 no Detect hardcoded passwords via regex password\s*=\s*['"][^'"]+['"] none
REQ-021-101 no Detect hardcoded API keys via regex api[_-]?key\s*=\s*['"][^'"]+['"] none
REQ-021-102 no Detect hardcoded secrets via regex secret\s*=\s*['"][^'"]+['"] none
REQ-021-103 no Detect hardcoded tokens via regex token\s*=\s*['"][^'"]+['"] none
REQ-021-104 no Detect debug f-string print statements as warnings none
REQ-021-105 no Detect TODO/FIXME/HACK/XXX/BUG comments (max 3 reported) none
REQ-021-106 no Detect bare except: with pass body as error none
REQ-021-107 no Detect missing logger in files with except or def blocks none
REQ-021-108 no Detect exceptions not logged via logger.error/exception/critical none
REQ-021-109 no Detect print statements that should use logging none
REQ-021-110 no Check mutable default arguments (def func(x=[])) as error none
REQ-021-111 no Check @traces decorator presence for files with 3+ public items none
REQ-021-112 no Report spec/requirement references found in code as info none
REQ-021-113 no Count branches (if/elif/for/while/except) per function none
REQ-021-114 no Branch count > 10 reported as error none
REQ-021-115 no Branch count > 7 reported as warning none
REQ-021-116 no Calculate max nesting depth (4-space indent units) none
REQ-021-117 no Nesting depth > 5 reported as error none
REQ-021-118 no Nesting depth > 4 reported as warning none
REQ-021-119 no Lines > 100 characters counted and reported as warning none
REQ-021-120 no Function body > 40 lines reported as warning with function name none
REQ-021-121 no Functions starting with uppercase reported as naming error (must be snake_case) none
REQ-021-122 no Classes starting with lowercase reported as naming error (must be PascalCase) none
REQ-021-123 no Module-level UPPER_SNAKE constants detected and flagged for review none
REQ-021-124 no Singleton pattern detected (__instance = None) and reported as info none
REQ-021-125 no Factory pattern detected (def create/make/build/factory) and reported as info none
REQ-021-126 no Builder pattern detected (def set/with/add/build) and reported as info none
REQ-021-127 no @dataclass usage detected and reported as info none
REQ-021-128 no ABC/Protocol usage detected and reported as info none
REQ-021-129 no State machine pattern detected and reported as info none
REQ-021-130 no God object detection: class with > 20 methods reported as warning none
REQ-021-131 no Feature envy detection: function with > 15 self references reported as warning none
REQ-021-132 no Only Python files under packages/ trigger the review pipeline none
REQ-021-133 no Review report formatted with box-drawing characters and gate labels none
REQ-021-134 no All gates passed: display "ALL GATES PASSED" with gate list none
REQ-021-135 no Errors present: display "FAILED" with all error lines none
REQ-021-136 no Warnings present: display "WARNINGS" section with all warning lines none
REQ-021-137 no Quick-fix commands shown in error output (black, isort) none
REQ-021-138 no Errors throw Error to block the edit and force agent to fix none
REQ-021-139 no Warnings logged but do not block the edit none
REQ-021-140 no Error output maximum: 25 errors, 20 warnings, 8 info items none
REQ-021-141 no Passed files queued for KG sync via redis-cli SADD none
REQ-021-142 no Tool calls recorded in toolCallHistory array on tool.execute.after none
REQ-021-143 no Each record includes tool name, args, timestamp (Date.now()), and success boolean none
REQ-021-144 no History capped at 100 entries (oldest shifted out) none
REQ-021-145 no History cleared on session end (session.idle and session close) none
REQ-021-146 no Quoted content removed before analysis (```, `, > blockquotes) none
REQ-021-147 no Analysis operates on lowercased narrative text none
REQ-021-148 no File creation claims matched against 3 regex patterns none
REQ-021-149 no File creation without Write/Edit tool flagged as ACTION_DECEPTION (CRITICAL) none
REQ-021-150 no Command execution claims matched against 3 regex patterns none
REQ-021-151 no Command execution without Bash tool flagged as ACTION_DECEPTION (CRITICAL) none
REQ-021-152 no File reading claims matched against 2 regex patterns none
REQ-021-153 no File reading without Read/Grep tool flagged as ACTION_DECEPTION (HIGH) none
REQ-021-154 no Unacknowledged tool errors flagged as ERROR_CONCEALMENT (CRITICAL) none
REQ-021-155 no Error acknowledgment checked via keywords: error, failed, failure, issue, couldn't, unable, denied none
REQ-021-156 no Failed tools listed in evidence field of findings none
REQ-021-157 no Deception audit runs on session.idle hook none
REQ-021-158 no Report formatted with severity icons (CRITICAL=red, HIGH=orange, MEDIUM=yellow, LOW=blue) none
REQ-021-159 no Each finding shows type, severity, description, and evidence none
REQ-021-160 no Total violation count shown at report end none
REQ-021-161 no Clean audit displays "No issues detected" message none
REQ-021-162 no Findings logged to client.app.log with error level none
REQ-021-163 no unittest.mock pattern blocked in test files none
REQ-021-164 no MagicMock pattern blocked in test files none
REQ-021-165 no @patch decorator pattern blocked in test files none
REQ-021-166 no AsyncMock pattern blocked in test files none
REQ-021-167 no Mock() constructor pattern blocked in test files none
REQ-021-168 no patch.object pattern blocked in test files none
REQ-021-169 no Policy only applies to files with "test" in path (case-insensitive) none
REQ-021-170 no Violation throws descriptive Error with pattern name none
REQ-021-171 no Relative import pattern from . import blocked none
REQ-021-172 no Pattern matches at beginning of line (with optional whitespace) none
REQ-021-173 no Violation throws Error with "Use absolute imports" message none
REQ-021-174 no pip install blocked with suggestion "uv add" none
REQ-021-175 no pip3 install blocked with suggestion "uv add" none
REQ-021-176 no pip sync blocked with suggestion "uv sync" none
REQ-021-177 no requirements.txt references blocked with suggestion "Use pyproject.toml with uv" none
REQ-021-178 no Violations throw Error with specific suggestion none
REQ-021-179 no rm -rf / pattern blocked none
REQ-021-180 no Fork bomb pattern :(){ :|:& }; blocked none
REQ-021-181 no >/dev/null redirect pattern blocked none
REQ-021-182 no Blocked patterns throw Error with command in message none
REQ-021-183 no Writes to paths containing .claude/plans blocked none
REQ-021-184 no Redirect message points to ~/workspace/orchestrata/plans/ none
REQ-021-185 no Git checkpoint created before edit and write tool operations none
REQ-021-186 no Checkpoint commits use --no-verify flag none
REQ-021-187 no Checkpoint message format: checkpoint: before {tool} {filePath} none
REQ-021-188 no Git checkpoint failures are non-blocking (|| true) none
REQ-021-189 no Read count incremented on each read tool execution none
REQ-021-190 no Read count > 50 throws Error with guidance to use grep first none
REQ-021-191 no Read count reset to 0 on session end none
REQ-021-192 no MCP document-reader health checked on read and grep tool execution none
REQ-021-193 no Health check via curl -sf to http://localhost:3456/health none
REQ-021-194 no MCP availability logged as info (does not block native tool) none
REQ-021-195 no session-status returns formatted session info with box-drawing characters none
REQ-021-196 no session-status shows session seq, status, purpose, started time, duration none
REQ-021-197 no session-status shows achievements (top 3) and next steps (top 3) none
REQ-021-198 no session-status shows project version, branch, test state, session count, pending count none
REQ-021-199 no session-begin accepts purpose (string) and optional objectives (string[]) none
REQ-021-200 no session-end accepts optional achievements and upcoming (string[]) none
REQ-021-201 no session-log-work accepts desc (string) and optional details (string[]) none
REQ-021-202 no session-log-achievement accepts item (string) none
REQ-021-203 no session-add-work accepts text, optional priority, optional notes none
REQ-021-204 no session-complete-work accepts text (string) none
REQ-021-205 no session-update-state accepts optional version, branch, testState, status none
REQ-021-206 no session-log-choice accepts choice (string) and reason (string) none
REQ-021-207 no kg-query executes Cypher query via neo4j Python driver none
REQ-021-208 no kg-query returns "KG query only available for Orchestrata project" for non-orchestrata dirs none
REQ-021-209 no kg-sync runs sync_monorepo_to_neo4j.py and returns first 2000 chars none
REQ-021-210 no kg-queue-status returns pending count and file list from Redis SET none
REQ-021-211 no kg-flush-queue processes all files in sync queue via FileSynchronizer none
REQ-021-212 no kg-file-context retrieves full KG context for a file path none
REQ-021-213 no kg-find-file searches File nodes by name pattern none
REQ-021-214 no kg-find-entity searches Class and Function nodes by name none
REQ-021-215 no kg-stats returns node and relationship counts by label/type none
REQ-021-216 no conv-status returns conversation queue depth from Redis 2
REQ-021-217 no conv-sync flushes conversation queue to Neo4j 3
REQ-021-218 no "remember when" phrase triggers memory search none
REQ-021-219 no "do you remember" phrase triggers memory search none
REQ-021-220 no "recall when" phrase triggers memory search none
REQ-021-221 no "remember that" phrase triggers memory search none
REQ-021-222 no "we discussed" phrase triggers memory search none
REQ-021-223 no "we talked about" phrase triggers memory search none
REQ-021-224 no "last time we" phrase triggers memory search none
REQ-021-225 no "what happened with" phrase triggers memory search none
REQ-021-226 no Topic extracted from text after the trigger phrase none
REQ-021-227 no Topic cleaned of leading punctuation none
REQ-021-228 no Words shorter than 3 characters excluded from search terms none
REQ-021-229 no Last 20 sessions searched in reverse order (newest first) none
REQ-021-230 no Session purpose matched against topic words none
REQ-021-231 no Session achievements matched against topic words none
REQ-021-232 no Session work log entries matched against topic words none
REQ-021-233 no Maximum 10 results returned none
REQ-021-234 no Results include session seq, date, match type (purpose/achievement/log) none
REQ-021-235 no Results injected into output.context as formatted block none
REQ-021-236 no Memory search logged to client.app.log with topic none
REQ-021-237 no Search failure logged as warning (non-blocking) none
REQ-021-238 no No-match case prints "No matching sessions found" message none
REQ-021-239 no Setup orchestrata paths (workspace, packages, knowledge src, core src) none
REQ-021-240 no Async query via Neo4jClient from orchestrata.knowledge none
REQ-021-241 no Connection to the active env profile's KG endpoint (test fleet: bolt://10.53.2.10:7687), database orchkg (auth-less Memgraph) none
REQ-021-242 no Return JSON with success, data, and count fields none
REQ-021-243 no Return JSON error with type field on failure none
REQ-021-244 no Accept Cypher query as argv[1] and optional JSON parameters as argv[2] none
REQ-021-245 no Print usage examples to stderr on missing arguments none
REQ-021-246 no Auto-detect orchestrata workspace from CWD none
REQ-021-247 no Retrieve project ID via (p:Project)-[:HAS_FILE]->(f:File) query none
REQ-021-248 no Rewrite File path queries to anchor through (p:Project)-[:HAS_FILE]-> none
REQ-021-249 no Rewrite Spec ID queries to anchor through (p:Project)-[:HAS_SPEC]-> none
REQ-021-250 no Rewrite Requirement ID queries to anchor through (p:Project)-[:HAS_REQUIREMENT]-> none
REQ-021-251 no General MATCH queries get WHERE EXISTS clause checking 30+ relationship types none
REQ-021-252 no Project scoping uses case-insensitive regex pattern matching none
REQ-021-253 no Fallback wrapping for unrecognized query patterns none
REQ-021-254 no Change to orchestrata workspace directory none
REQ-021-255 no Run kg_query_inner.py via uv run python3 none
REQ-021-256 no Pass through all command-line arguments none
REQ-021-257 no Fallback mock classes defined if orchestrata imports fail none
REQ-021-258 no Import error printed to stderr (not stdout) none
REQ-021-259 no Same connection and query interface as kg_query.py none
REQ-021-260 no Minimal implementation for connection verification none
REQ-021-261 no Same path setup and query interface as kg_query.py none
REQ-021-262 no toolCallHistory array initialized empty on plugin load none
REQ-021-263 no readCount counter initialized to 0 on plugin load none
REQ-021-264 no MCP_SERVERS array defines document-reader (3456) and document-writer (3457) none
REQ-021-265 no Plugin activates only for directories under /home/mohamed/workspace none
REQ-021-266 no Plugin returns empty object {} for directories outside workspace none
REQ-021-267 no SESSION_CLI path set to python3 ~/.claude/tools/session_cli.py none
REQ-021-268 no PROJECT_ROOT set to the directory parameter none
REQ-021-269 no All log messages use service name "orchestrata-plugin" none
REQ-021-270 no Log levels: info (normal), warn (non-critical failures), error (critical failures), debug (verbose) none
REQ-021-271 no Plugin activation logged on startup with project name and directory none
REQ-021-272 no "close the session" detected as close request none
REQ-021-273 no "cts" detected as close request none
REQ-021-274 no "cs" detected as close request none
REQ-021-275 no "end session" detected as close request none
REQ-021-276 no "finish session" detected as close request none
REQ-021-277 no Close validates active session exists none
REQ-021-278 no Close extracts achievements from git log (last 2 hours, top 20, filter checkpoints) none
REQ-021-279 no Close ends session via session_cli.py none
REQ-021-280 no Close pushes branch to origin none
REQ-021-281 no Close displays formatted report with session number, achievements, push status none
REQ-021-282 no Close clears toolCallHistory and readCount none
REQ-021-283 no Close failure displayed as error message none
REQ-021-284 no Praise patterns (looks good, great work, well done) logged none
REQ-021-285 no Thanks patterns (thanks, thank you, appreciate) logged none
REQ-021-286 no Fix confirmation patterns (that works, fixed it, solved it) logged none
REQ-021-287 no Completion detection is non-blocking none
REQ-021-288 no experimental.session.compacting injects session context none
REQ-021-289 no Context includes active session seq, purpose, achievements, carryover tasks none
REQ-021-290 no Session status retrieved via session_cli.py status --json (first 1000 chars) none
REQ-021-291 no Compacting hook is non-blocking none
REQ-021-292 no File operations (edit, write, delete) logged via session_cli.py log-work none
REQ-021-293 no Write operations additionally logged via session_cli.py log-artifact none
REQ-021-294 no Failed tool operations logged as warnings to client.app.log none
REQ-021-295 no Operation logging is non-blocking none

Code that traces this spec

Module Symbols Requirements
orchestrata_ultimate/kernel/cli_main 3 2
orchestrata_ultimate/knowledge_graph/canonical_schema 2 1
orchestrata_ultimate/knowledge_graph/conversation_consumer 16 12
orchestrata_ultimate/session/kg_context 2 1
orchestrata_ultimate/tools/conversation_tools 2 2

Checklists

checklists/README.md

OpenCode Integration Checklists

Project: Orchestrata OpenCode Integration (Spec 021) Component: OrchestrataPlugin, Agents, Tools, Commands, KG Integration Status: Implemented Owner: Mohamed


Overview

The OpenCode Integration is a comprehensive TypeScript plugin and supporting infrastructure that bridges OpenCode with the Orchestrata ecosystem. It provides session management, 5-gate code quality enforcement, deception detection, knowledge graph context injection, conversation tracking, and 24 custom tools.


Checklist Summary
Checklist Total Items Completed Progress
Requirements 295 0 0%
Constitutional Compliance 105 0 0%
Testing Plan 211 0 0%
TOTAL 611 0 0%

Key Responsibilities
1. Plugin Lifecycle Management
2. Session Management
3. Code Quality Enforcement (5-Gate Review)
4. Policy Enforcement
5. Deception Detection
6. Knowledge Graph Integration
7. Conversation Tracking
8. Custom Tools (24 total)

File References
Checklist File
Requirements requirements.md
Constitutional constitutional.md
Testing testing.md

checklists/constitutional.md

OpenCode Integration Constitutional Checklist

Article I: Security and Access Control
Article II: Data Integrity and Consistency
Article III: Code Quality and Standards Enforcement
Article IV: System Reliability and Resilience
Article V: Transparency and Auditability
Article VI: Privacy and Data Minimization
Article VII: Ethical AI and Deception Prevention
Article VIII: Interoperability and Compatibility
Article IX: Performance and Resource Management
Article X: Knowledge Graph Integrity
Article XI: Deployment and Configuration

checklists/requirements.md

The requirement list above comes from this file; 0 of 295 checkbox items are ticked.

checklists/testing.md

OpenCode Integration Testing Checklist

Unit Tests: Plugin State Management
Unit Tests: Helper Functions
removeQuotedContent
detectDeception
enforceTestingPolicy
enforceImportPolicy
enforceDevelopmentPolicy
checkMcpHealth
Unit Tests: 5-Gate Code Review
Gate 1: Syntax & Format
Gate 2: Lint
Gate 3: Runtime & Security
Gate 4: Complexity & Nesting
Gate 5: Naming & Design
Review Output
Unit Tests: KG Query Tools (Python)
kg_query.py
kg_query_inner.py (Project Scoping)
neo4j_query.py
simple_kg_query.py
Unit Tests: Session Close Detection
Unit Tests: Custom Tools
Session Tools
KG Tools

Integration Tests: Plugin Lifecycle
Integration Tests: KG Query Pipeline
Integration Tests: Session Management End-to-End
Integration Tests: Code Review End-to-End
Integration Tests: Redis Queue Operations
Integration Tests: Deployment

Other tracked files

Full spec text

Verbatim from specs/021-opencode-integration/spec.md; headings are pushed down two levels.

SPEC-021: OpenCode Integration

Metadata


Overview

What

A comprehensive TypeScript plugin (3,234 lines) and supporting agents, tools, and commands that integrate OpenCode with the Orchestrata project. The plugin provides session management, code quality enforcement via a 5-gate review pipeline, deception detection, knowledge graph context injection, conversation tracking, and 24 custom tools accessible from within OpenCode sessions.

Why
How

User Stories

Added 2026-08-02 (spec-consolidation pilot): binds the flat FR list below to actor-driven usage scenarios (SPEC-102 template). Each story names the FRs it exercises, so every requirement has a "who triggers it and why" narrative.


Terminology

Term Definition
OpenCode An AI-powered code editor CLI that supports plugins, agents, tools, and commands
OrchestrataPlugin The main TypeScript plugin export that hooks into OpenCode lifecycle events
5-Gate Review The automated code review pipeline: syntax, lint, runtime/security, complexity, naming/design
Deception Detection Analysis that compares claimed actions in LLM responses against actual tool call history
KG Context Injection Automatic enrichment of file reads with knowledge graph metadata (classes, functions, specs)
Session CLI Python CLI (session_cli.py) that manages session lifecycle in context.json
Tool Call History In-memory array tracking all tool invocations for deception auditing at session end
Read Throttle Per-session limit (50 reads) preventing excessive file reading without search-first patterns
KG Sync Queue Redis set (orchestrata:kg:sync:queue) of file paths pending Neo4j synchronization
Conversation Queue Redis list (orchestrata:conversation:queue) of conversation turns pending Neo4j storage
Project Scoping Automatic Cypher query rewriting to restrict results to the current project's graph subgraph
Git Checkpoint Automatic git commit before edit/write operations to enable rollback

Data Models

Session Context Model
{
  "session_seq": "number",
  "purpose": "string",
  "version": "string",
  "branch": "string",
  "testState": "string",
  "status": "ACTIVE|IDLE|COMPLETE",
  "created_at": "ISO8601",
  "updated_at": "ISO8601"
}
KG File Node Model
{
  "id": "string (UUID)",
  "path": "string",
  "language": "string",
  "line_count": "number",
  "size_bytes": "number",
  "package": "string",
  "classes": [
    {
      "name": "string",
      "line_start": "number",
      "line_end": "number",
      "methods": ["string"]
    }
  ],
  "functions": [
    {
      "name": "string",
      "line_start": "number",
      "line_end": "number",
      "is_async": "boolean"
    }
  ]
}
Conversation Turn Model
{
  "id": "string (UUID)",
  "conversation_id": "string",
  "turn_number": "number",
  "role": "user|assistant",
  "content": "string (max 2000)",
  "timestamp": "ISO8601",
  "platform": "opencode"
}
Code Review Result Model
{
  "file_path": "string",
  "gate": "1|2|3|4|5",
  "status": "PASS|WARN|ERROR",
  "errors": [
    {
      "line": "number",
      "message": "string",
      "rule": "string"
    }
  ],
  "warnings": [
    {
      "line": "number",
      "message": "string",
      "rule": "string"
    }
  ]
}
Deception Detection Result Model
{
  "session_id": "string",
  "findings": [
    {
      "type": "ACTION_DECEPTION|ERROR_CONCEALMENT|FILE_READING_DECEPTION",
      "severity": "CRITICAL|HIGH|MEDIUM",
      "claim": "string",
      "evidence": "string",
      "tool_calls_required": ["string"],
      "tool_calls_found": ["string"]
    }
  ],
  "audited_at": "ISO8601"
}

Functional Requirements

FR-001: Plugin Lifecycle Hooks

The OrchestrataPlugin MUST hook into all 7 OpenCode lifecycle events: session.created, session.idle, tool.execute.before, tool.execute.after, message.updated, file.edited, and experimental.session.compacting.

FR-002: Session Auto-Start

On session.created, the plugin MUST automatically start or resume a session via session_cli.py and display session information including seq, purpose, version, branch, and test state.

FR-003: Session Auto-End

On session.idle, the plugin MUST automatically end the session with git-extracted achievements, flush the KG sync queue, flush the conversation queue, and clear session state.

FR-004: KG Context Injection

On file reads within the Orchestrata project directory, the plugin MUST inject knowledge graph context including classes, functions, traceability links, and inheritance hierarchy into tool arguments as _orchestrata_context.

FR-005: 5-Gate Code Review Pipeline

On file.edited for Python files in packages/, the plugin MUST execute a 5-gate code review: Gate 1 (syntax/format), Gate 2 (lint), Gate 3 (runtime/security), Gate 4 (complexity/nesting), Gate 5 (naming/design).

FR-006: Error Blocking

Code review errors MUST block the edit and force the agent to fix issues before proceeding. Warnings MUST be displayed but not block the edit.

FR-007: Deception Detection

On session.idle, the plugin MUST analyze the assistant's final message against tool call history to detect ACTION_DECEPTION, ERROR_CONCEALMENT, and FILE_READING_DECEPTION with appropriate severity levels.

FR-008: Policy Enforcement

The plugin MUST enforce development policies during tool.execute.before: testing policy (block mocking), import policy (block relative imports), development policy (block pip), bash safety (block destructive patterns), write policy (block ~/.claude/plans/).

FR-009: Custom Tools Availability

All 24 custom tools (9 session, 12 KG, 3 conversation) MUST be available and functional within OpenCode sessions when the OrchestrataPlugin is active.

FR-010: KG Query Project Scoping

All KG query tools MUST automatically scope Cypher queries to the current project by anchoring through the Project node relationship chain.

FR-011: Redis Queue Management

The plugin MUST use Redis SET orchestrata:kg:sync:queue for KG sync pending files and LIST orchestrata:conversation:queue for conversation turns pending Neo4j storage.

FR-012: Memory Search Trigger

On message.updated, the plugin MUST detect "remember when" and 7 other trigger patterns, extract the topic, search last 20 sessions, and inject top 10 matches as context.

FR-013: Read Throttling

The plugin MUST enforce a per-session read limit of 50 file reads to prevent excessive file scanning without search-first patterns.

FR-014: Git Checkpoint Creation

Before any edit or write operation, the plugin MUST create a git checkpoint to enable rollback on failure.

FR-015: Conversation Storage

User and assistant messages MUST be queued to Redis and flushed to Neo4j on session close, creating Conversation and ConversationTurn nodes with platform="opencode".

FR-016: KG Sync Daemon

The plugin MUST support background KG synchronization via a daemon process that can be started, stopped, and queried for status.

FR-017: MCP Health Monitoring

The plugin MUST check MCP server health (document-reader at port 3456, document-writer at port 3457) on session start and log availability.


Error Conditions

ID Condition Handling
ERR-001 Session CLI process error Non-blocking, logged to client.app.log, session continues
ERR-002 Neo4j connection timeout Non-blocking, file read proceeds without KG context
ERR-003 Redis connection refused Non-blocking, KG sync and conversation storage skipped
ERR-004 MCP health check server down Non-blocking, logged as info, workflow continues
ERR-005 Git checkpoint dirty worktree Non-blocking, uses --no-verify with || true fallback
ERR-006 Code review Python tool error Non-blocking unless it's the review's own thrown error
ERR-007 KG sync daemon process crash Non-blocking, queue persists in Redis for retry
ERR-008 Conversation Neo4j write failure Non-blocking, turns remain in Redis queue
ERR-009 Read throttle limit exceeded Block further reads, prompt to use search tools first
ERR-010 Policy violation detected Throw descriptive error with suggested alternative
ERR-011 Invalid Cypher query syntax Return error message, do not execute against Neo4j
ERR-012 KG query project not found Return no results with "Project not found" message
ERR-013 Session not found on status check Return "No active session" message
ERR-014 context.json parse error Log error, treat as no session active
ERR-015 Deception detection tool history unavailable Skip deception audit, log info message
ERR-016 Conversation queue full (>1000 items) Drop oldest items, log warning
ERR-017 KG sync queue full (>500 files) Block new enqueues, log error
ERR-018 Invalid session state transition Log error, retain current state
ERR-019 Tool argument JSON parse error Return error to caller, do not execute tool
ERR-020 Network timeout on git push Retry once, then log failure and continue

Non-Functional Requirements

Performance
Scalability
Reliability
Maintainability

Governance

Code Quality Governance
  1. 5-Gate Review: All Python edits in packages/ MUST pass through the 5-gate review pipeline before commit
  2. Naming Standards: snake_case for functions, PascalCase for classes, UPPER_SNAKE for constants
  3. Complexity Limits: Max 10 branches, max 5 nesting depth, max 40 lines per function
Policy Governance
  1. Testing: Mocking patterns blocked in test files
  2. Imports: Relative imports prohibited
  3. Package Management: pip prohibited, uv required
  4. Secrets: Hardcoded secrets, passwords, API keys, tokens detected and flagged
Session Governance
  1. Lifecycle: All sessions MUST be tracked in context.json
  2. Achievements: Session end MUST extract achievements from git log
  3. Tracking: Tool usage history retained for deception auditing

Testing

Unit Tests
Integration Tests
E2E Tests
Test Coverage Targets

Integration Points

External Systems
System Integration Type Protocol
Memgraph KG Knowledge graph storage (orchkg database) Bolt (from active env profile; test fleet: bolt://10.53.2.10:7687)
Redis Queue management Redis protocol (from active env profile; test fleet: 10.53.2.11:6379)
OpenCode Plugin/agent/command host OpenCode plugin API
Git Checkpoint/achievement extraction Git CLI
Session CLI Session management Python CLI (subprocess)
Internal Modules
Module Purpose Dependency
orchestrata.ts Main plugin @opencode-ai/plugin@1.3.3
session_cli.py Context.json management Python 3.14t
kg_query_inner.py KG queries with scoping neo4j driver (Bolt, Memgraph)
sync_ast_to_graph.py KG synchronization Redis, Memgraph KG

Success Criteria

Core Functionality
Tool Availability
Quality Assurance
Integration
Performance

User Scenarios & Stories

US-001: Automatic KG Context Injection (P0)

As a developer using OpenCode on the Orchestrata project I want file reads and searches to automatically include knowledge graph context So that the LLM understands the file's classes, functions, specs, and relationships without manual queries

Acceptance Criteria:


US-002: Session Management (P0)

As a developer using OpenCode I want sessions to auto-start on connection and auto-close on idle So that all work is tracked in context.json without manual intervention

Acceptance Criteria:


US-003: Code Quality Enforcement (P0)

As a developer editing Python files in packages/ I want a 5-gate code review to run automatically on every file edit So that syntax errors, lint violations, security issues, complexity, and naming problems are caught immediately

Acceptance Criteria:


US-004: Deception Detection (P1)

As a user reviewing LLM work I want the system to detect when the LLM claims actions it did not perform So that false claims about file creation, command execution, or file reading are flagged

Acceptance Criteria:


US-005: Policy Enforcement (P0)

As a project maintainer I want development policies automatically enforced during tool execution So that mocking, relative imports, pip usage, and destructive commands are prevented

Acceptance Criteria:


US-006: Custom Tools (P1)

As a developer using OpenCode I want 24 custom tools for session management, KG queries, and code review So that the LLM can programmatically interact with Orchestrata infrastructure

Acceptance Criteria:


US-007: Conversation Tracking (P2)

As the system I want conversation turns stored in Neo4j via Redis queue So that session interactions are preserved for analysis and memory search

Acceptance Criteria:


US-008: Memory Search (P2)

As a developer asking "remember when..." I want the system to search session history for matching context So that previous decisions, achievements, and work logs are recalled automatically

Acceptance Criteria:


US-009: KG Sync Daemon (P1)

As the system I want modified files queued for background KG synchronization So that the knowledge graph stays current as code evolves during sessions

Acceptance Criteria:


US-010: Agent Intelligence (P1)

As a developer working with OpenCode I want two agents that automatically detect context triggers and query the KG So that relevant project knowledge is available without manual Cypher queries

Acceptance Criteria:


Architecture

Plugin Architecture (3,234 lines)
opencode/plugins/orchestrata.ts
├── State Management
│   ├── toolCallHistory[]: Tool call tracking for deception detection
│   ├── readCount: File read throttle counter (limit: 50/session)
│   └── MCP_SERVERS[]: Health check endpoints for document-reader/writer
├── Helper Functions
│   ├── checkMcpHealth(): MCP server availability check
│   ├── removeQuotedContent(): Strip code blocks/quotes for deception analysis
│   ├── detectDeception(): Compare claimed actions vs actual tool usage
│   ├── enforceTestingPolicy(): Block mocking patterns in test files
│   ├── enforceImportPolicy(): Block relative imports
│   └── enforceDevelopmentPolicy(): Block pip, require uv
└── Lifecycle Hooks (7)
    ├── session.created: Auto-start session, inject context, start KG sync
    ├── session.idle: Deception audit, session close, queue flush
    ├── tool.execute.before: KG injection, policies, git checkpoint, bash safety
    ├── tool.execute.after: Operation logging, deception tracking
    ├── message.updated: Remember-when search, session close, conversation storage
    ├── file.edited: 5-gate code review, KG sync queue
    └── experimental.session.compacting: Custom session context injection
Hook Mapping: Claude Code to OpenCode
Claude Code Hook OpenCode Hook Behavior
PreToolUse tool.execute.before Same concept: intercept before tool execution
PostToolUse tool.execute.after Same concept: log after tool execution
SessionStart session.created Different naming, same lifecycle event
Stop session.idle Different naming, same lifecycle event
UserPromptSubmit message.updated Broader scope in OpenCode (all message updates)
OpenCode-Only file.edited OpenCode-specific: triggers on any file edit
OpenCode-Only experimental.session.compacting OpenCode-specific: context injection during compaction
Deployment Layout
Source:
  open-code/
  ├── agents/
  │   ├── auto-kg-context.md    # Auto KG context agent definition
  │   └── kg-context-agent.md   # Manual KG context agent definition
  ├── commands/
  │   └── query-kg.md           # /query-kg slash command definition
  ├── plugins/
  │   └── orchestrata.ts        # Main plugin (3,234 lines)
  ├── tools/
  │   ├── kg_query              # Bash wrapper for uv environment
  │   ├── kg_query.py           # Full-featured async query tool
  │   ├── kg_query_inner.py     # Core implementation with project scoping
  │   ├── neo4j_query.py        # Standalone direct query tool
  │   └── simple_kg_query.py    # Simplified connectivity test
  ├── install.sh                # Deployment script
  └── config/                   # OpenCode configuration

Deployed:
  ~/.opencode/
  ├── agents/                   # Agent definitions
  ├── commands/                 # Command definitions
  ├── plugins/                  # Plugin (compiled)
  └── tools/                    # Python query tools
  ~/.config/opencode/           # OpenCode config
Data Flow
                    ┌──────────────────────┐
                    │   OpenCode Session   │
                    └──────────┬───────────┘
                               │
                    ┌──────────▼───────────┐
                    │  OrchestrataPlugin   │
                    │  (orchestrata.ts)    │
                    └──────────┬───────────┘
                               │
         ┌─────────────────────┼─────────────────────┐
         │                     │                     │
┌────────▼────────┐  ┌────────▼────────┐  ┌────────▼────────┐
│  session_cli.py │  │  Memgraph KG    │  │   Redis Queue   │
│  (context.json) │  │ bolt://10.93.   │  │ 10.53.2.11:6379│
│                 │  │  53.10:7687     │  │                 │
│  - begin        │  │                 │  │  - kg:sync:     │
│  - end          │  │  - File nodes   │  │    queue (SET)  │
│  - log-work     │  │  - Class nodes  │  │  - conversation │
│  - status       │  │  - Function     │  │    :queue (LIST)│
│  - update-state │  │  - Requirement  │  │                 │
└─────────────────┘  │  - Spec nodes   │  └─────────────────┘
                     │  - Conversation │
                     │  - Turn nodes   │
                     └─────────────────┘
5-Gate Code Review Pipeline
File Edit (packages/*.py)
    │
    ▼
┌─────────────────────────────────────────────────────┐
│ GATE 1: Syntax & Format                             │
│   py_compile → black --check → isort --check        │
│   Errors: syntax errors, formatting violations      │
├─────────────────────────────────────────────────────┤
│ GATE 2: Lint                                        │
│   flake8 --select=E,F,W,C90 --max-line-length=88   │
│   Errors: E9xx, F63x, F72x (fatal)                 │
│   Warnings: other E/W/C codes                       │
├─────────────────────────────────────────────────────┤
│ GATE 3: Runtime & Security                          │
│   mypy (type check) → module import test            │
│   Security: hardcoded passwords/keys/secrets/tokens │
│   Quality: debug prints, temporary comments, bare except    │
│   Logging: missing logger, unlogged exceptions      │
│   Traceability: @traces decorator presence          │
├─────────────────────────────────────────────────────┤
│ GATE 4: Complexity & Nesting                        │
│   Branches: >10 error, >7 warn                     │
│   Nesting: >5 error, >4 warn                       │
│   Line length: >100 chars warn                      │
│   Function size: >40 lines warn                     │
├─────────────────────────────────────────────────────┤
│ GATE 5: Naming & Design                             │
│   Functions: must be snake_case                     │
│   Classes: must be PascalCase                       │
│   Constants: UPPER_SNAKE_CASE                       │
│   God objects: >20 methods warn                     │
│   Feature envy: >15 self references warn            │
│   Patterns: singleton, factory, builder, dataclass  │
└─────────────────────────────────────────────────────┘
    │
    ▼
  Errors? → Block edit, force fix
  Warnings? → Display, allow edit
  Pass? → Queue file for KG sync
Deception Detection Model
Tool Call History (per session, max 100)
    │
    ▼
On session.idle:
    │
    ├── Extract assistant's final message
    ├── Remove quoted content (```, `, >)
    ├── Check file creation claims → require Write/Edit in history
    ├── Check command execution claims → require Bash in history
    ├── Check file reading claims → require Read/Grep in history
    ├── Check for unacknowledged tool errors
    │
    ▼
┌─────────────────────────────────┐
│ Findings (severity levels):     │
│   CRITICAL: ACTION_DECEPTION    │
│   CRITICAL: ERROR_CONCEALMENT   │
│   HIGH: FILE_READING_DECEPTION  │
└─────────────────────────────────┘

Examples

Plugin Activation Example

The OrchestrataPlugin automatically activates when OpenCode starts a session in the Orchestrata project:

// orchestrata.ts - Plugin activation check
import { OpenCodePlugin } from '@opencode-ai/plugin';

export const OrchestrataPlugin: OpenCodePlugin = {
  name: 'orchestrata',
  matches: (context) => {
    const workspacePath = context.workspacePath;
    return workspacePath.startsWith('/home/mohamed/workspace') 
           && context.hasFile('context.json');
  }
};
Session Lifecycle Example
# Session auto-starts on OpenCode connection (triggered by session.created hook)
$ opencode

# Session info displayed automatically:
# ┌─────────────────────────────────────────┐
# │ Session #42 | P1 | Active              │
# │ Purpose: Implement SPEC-021            │
# │ Branch: feature/opencode-integration   │
# │ Test State: 3/15 passing               │
# └─────────────────────────────────────────┘

# Session auto-ends on "close the session" (triggered by session.idle hook)
> close the session

# Session close report:
# ┌─────────────────────────────────────────┐
# │ Session #42 Closed                      │
# │ Achievements:                           │
# │   - Added OrchestrataPlugin (3,234 LOC) │
# │   - Implemented 5-gate code review      │
# │   - Added deception detection           │
# │ Pushed to origin ✓                     │
# └─────────────────────────────────────────┘
KG Context Injection Example

When reading a file in the Orchestrata project, KG context is automatically injected:

# Tool call: Read /home/mohamed/workspace/orchestrata/packages/core/traceability/__init__.py

# Request:
{
  "filePath": "/home/mohamed/workspace/orchestrata/packages/core/traceability/__init__.py"
}

# Response (with _orchestrata_context injected):
{
  "content": "...",
  "_orchestrata_context": {
    "file": {
      "path": "/home/mohamed/workspace/orchestrata/packages/core/traceability/__init__.py",
      "language": "python",
      "line_count": 247
    },
    "classes": [
      {
        "name": "TraceabilityModule",
        "line_start": 45,
        "line_end": 189,
        "methods": ["add_requirement", "link_spec", "query_graph", "export_trace"]
      }
    ],
    "functions": [
      {
        "name": "create_traceability_link",
        "line_start": 12,
        "line_end": 34,
        "is_async": true
      }
    ],
    "spec_links": [
      {"spec_id": "001", "requirement": "REQ-001-US-001-012"}
    ]
  }
}
Code Review Pipeline Example

Editing a Python file triggers the 5-gate code review:

# File edit detected: packages/core/traceability/module.py

# GATE 1: Syntax & Format
$ py_compile packages/core/traceability/module.py
✓ PASS

$ black --check packages/core/traceability/module.py
✓ PASS

$ isort --check packages/core/traceability/module.py
✓ PASS

# GATE 2: Lint
$ flake8 packages/core/traceability/module.py --select=E,F,W,C90 --max-line-length=88
✓ PASS (0 errors, 2 warnings)

# GATE 3: Runtime & Security
$ mypy packages/core/traceability/module.py
✓ PASS

# Security scan:
✓ No hardcoded secrets detected
✓ No debug prints detected
✓ No temporary comments detected

# GATE 4: Complexity & Nesting
✓ Branches: 7 (warn threshold: 7)
✓ Nesting: 4 (warn threshold: 4)
✓ Line length: 2 warnings (> 100 chars)
✓ Function size: OK

# GATE 5: Naming & Design
✓ Functions: snake_case ✓
✓ Classes: PascalCase ✓
✓ Constants: UPPER_SNAKE_CASE ✓

# RESULT: PASS (2 warnings, 0 errors)
# File queued for KG sync: orchestrata:kg:sync:queue
Deception Detection Example

When the LLM claims actions not performed:

// session.idle hook triggers deception analysis

// Assistant's final message:
// "I've created the new authentication module and ran the tests."

// Tool call history (last 100):
// - Read: auth.py
// - Grep: "def authenticate"
// - Write: auth_test.py (contains test code)

// Deception detection result:
{
  "session_id": "42",
  "findings": [
    {
      "type": "ACTION_DECEPTION",
      "severity": "CRITICAL",
      "claim": "I've created the new authentication module",
      "evidence": "No Write or Edit tool calls found in history for 'authentication module'",
      "tool_calls_required": ["Write", "Edit"],
      "tool_calls_found": ["Read", "Grep"]
    },
    {
      "type": "ACTION_DECEPTION",
      "severity": "CRITICAL", 
      "claim": "ran the tests",
      "evidence": "No Bash tool calls found in history",
      "tool_calls_required": ["Bash"],
      "tool_calls_found": ["Write"]
    }
  ],
  "audited_at": "2026-04-09T15:32:00Z"
}
Policy Enforcement Example

Blocked patterns during tool execution:

# Testing policy violation (in test_file.py)
$ @patch('module.Class')
# ERROR: Mocking patterns blocked in test files
# Suggestion: Use real implementations or integration tests

# Import policy violation  
$ from . import utils
# ERROR: Relative imports prohibited
# Suggestion: Use absolute imports: from package.utils import ...

# Development policy violation
$ pip install requests
# ERROR: pip prohibited - use uv
# Suggestion: uv add requests

# Bash safety violation
$ rm -rf /
# ERROR: Destructive command blocked
# Message logged to security team

# Write policy violation
$ Write: ~/.claude/plans/feature.md
# ERROR: Direct writes to ~/.claude/plans/ prohibited
# Suggestion: Write to ~/workspace/orchestrata/plans/ instead
KG Query Tools Example
# Using the /query-kg command
/query-kg "MATCH (f:File) RETURN f.path, f.language ORDER BY f.line_count DESC LIMIT 10"

/query-kg "MATCH (c:Class)-[:DEFINES_METHOD]->(m:Method) WHERE c.name = 'TraceabilityModule' RETURN m.name"

/query-kg "MATCH (s:Spec {id: '001'})-[:DEFINES_REQUIREMENT]->(r:Requirement) RETURN r.id, r.text"
Session Management Tools Example
# Check session status
> session-status
# ┌─────────────────────────────────────────┐
# │ Session #42 | P1 | Active              │
# │ Purpose: Implement SPEC-021            │
# │ Branch: feature/opencode-integration   │
# │ Test State: 3/15 passing               │
# └─────────────────────────────────────────┘

# Log work
> session-log-work --desc "Implemented 5-gate review pipeline" --details ["Gate 1-3 complete", "Gate 4-5 remaining"]

# Log achievement
> session-log-achievement --item "Added deception detection (3 patterns)"

# Add deferred work
> session-add-work --text "Add memory search agent" --priority "P2"

# Complete work
> session-complete-work --text "Add memory search agent"
Memory Search Example
# User asks:
> Remember when we implemented the deception detection?

# Plugin detects "remember when" trigger, extracts topic: "deception detection"
# Searches last 20 sessions for matches

# Results injected into context:
# ┌─────────────────────────────────────────┐
# │ Memory Search: "deception detection"    │
# │ ─────────────────────────────────────── │
# │ Session #38 (2026-04-01)               │
# │   Match: purpose - "Add deception detection patterns" │
# │ Session #35 (2026-03-28)               │
# │   Match: achievement - "Implemented action deception"│
# │ Session #31 (2026-03-25)               │
# │   Match: work log - "Tested error concealment"       │
# └─────────────────────────────────────────┘
Redis Queue Status Example
# Check KG sync queue
> kg-queue-status
# Pending files: 12
# Queue: [packages/core/module.py, packages/core/utils.py, ...]

# Check conversation queue
> conv-status
# Pending turns: 47
# Oldest: session-42, turn-3 (2 minutes ago)
# Newest: session-42, turn-49 (30 seconds ago)

# Flush queues
> kg-flush-queue
# Synced 12 files to Neo4j ✓

> conv-sync
# Flushed 47 conversation turns to Neo4j ✓

API Contracts

OrchestrataPlugin
interface OrchestrataPlugin {
  // Lifecycle hooks
  onSessionCreated(handler: (session: SessionContext) => Promise<void>): void;
  onSessionIdle(handler: (session: SessionContext) => Promise<void>): void;
  onToolExecuteBefore(handler: (tool: ToolCall) => Promise<ToolCall>): void;
  onToolExecuteAfter(handler: (tool: ToolCall, result: ToolResult) => Promise<void>): void;
  onMessageUpdated(handler: (message: Message) => Promise<void>): void;
  onFileEdited(handler: (file: FileEdit) => Promise<FileEditResult>): void;
  onSessionCompacting(handler: (context: SessionContext) => Promise<ContextInjection>): void;
}

interface SessionContext {
  sessionSeq: number;
  purpose: string;
  version: string;
  branch: string;
  testState: string;
  status: 'ACTIVE' | 'IDLE' | 'COMPLETE';
  createdAt: string;
  updatedAt: string;
}

interface ToolCall {
  name: string;
  arguments: Record<string, unknown>;
  id: string;
  timestamp: string;
}

interface ToolResult {
  success: boolean;
  output?: string;
  error?: string;
}

interface FileEdit {
  filePath: string;
  content: string;
  language: string;
}

interface FileEditResult {
  allowed: boolean;
  errors?: CodeIssue[];
  warnings?: CodeIssue[];
}

interface CodeIssue {
  line: number;
  message: string;
  rule: string;
  severity: 'ERROR' | 'WARN';
}

interface ContextInjection {
  additions: Record<string, unknown>;
  priority: number;
}
Session CLI
# Session management commands
async def session_begin(purpose: str, objectives: list[str] = None) -> SessionContext:
    """Start a new session"""
    
async def session_end(achievements: list[str] = None, upcoming: list[str] = None) -> SessionCloseResult:
    """End current session"""
    
async def session_status() -> SessionStatus:
    """Get current session info"""
    
async def session_update_state(
    version: str = None,
    branch: str = None,
    testState: str = None,
    status: str = None
) -> SessionContext:
    """Update session state"""
    
async def session_log_work(desc: str, details: list[str] = None) -> WorkEntry:
    """Log a work entry"""
    
async def session_log_achievement(item: str) -> Achievement:
    """Log an achievement"""
    
async def session_add_work(text: str, priority: str = None, notes: str = None) -> WorkItem:
    """Add deferred work item"""
    
async def session_complete_work(text: str) -> WorkItem:
    """Mark work item as complete"""
    
async def session_log_choice(choice: str, reason: str) -> TechnicalChoice:
    """Log a technical decision"""

class SessionStatus(TypedDict):
    session_seq: int
    purpose: str
    version: str
    branch: str
    testState: str
    status: str
    created_at: str
    updated_at: str

class SessionCloseResult(TypedDict):
    session_seq: int
    achievements: list[str]
    flush_kg_sync: bool
    flush_conversation: bool
Knowledge Graph Client
class Neo4jKGClient:
    async def connect(self, uri: str, username: str, password: str) -> None:
        """Connect to Neo4j instance"""
        
    async def close(self) -> None:
        """Close connection"""
        
    async def execute_query(
        self,
        query: str,
        parameters: dict = None,
        project_scope: str = None
    ) -> list[dict]:
        """Execute Cypher query with optional project scoping"""
        
    async def get_file_context(self, path: str) -> KGFileContext:
        """Get KG context for a file"""
        
    async def get_entity_context(self, name: str, entity_type: str = None) -> KGEntityContext:
        """Get KG context for class/function"""
        
    async def get_traceability_links(
        self,
        file_path: str = None,
        spec_id: str = None,
        requirement_id: str = None
    ) -> list[TraceabilityLink]:
        """Get traceability links"""
        
    async def get_inheritance_hierarchy(
        self,
        class_name: str,
        depth: int = 3
    ) -> InheritanceChain:
        """Get class inheritance hierarchy"""

class KGFileContext(TypedDict):
    id: str
    path: str
    language: str
    line_count: int
    size_bytes: int
    package: str
    classes: list[ClassInfo]
    functions: list[FunctionInfo]

class ClassInfo(TypedDict):
    name: str
    line_start: int
    line_end: int
    methods: list[str]

class FunctionInfo(TypedDict):
    name: str
    line_start: int
    line_end: int
    is_async: bool

class TraceabilityLink(TypedDict):
    source_type: str
    source_id: str
    target_type: str
    target_id: str
    relationship: str

class InheritanceChain(TypedDict):
    class_name: str
    ancestors: list[str]
    depth: int
Redis Queue Manager
class QueueManager:
    async def enqueue_kg_sync(self, file_path: str) -> int:
        """Add file to KG sync queue (returns queue size)"""
        
    async def dequeue_kg_sync(self, count: int = None) -> list[str]:
        """Remove and return files from KG sync queue"""
        
    async def get_kg_queue_size(self) -> int:
        """Get KG sync queue size"""
        
    async def flush_kg_queue(self) -> int:
        """Flush all items from KG sync queue (returns count)"""
        
    async def enqueue_conversation(
        self,
        conversation_id: str,
        turn: ConversationTurn
    ) -> int:
        """Add turn to conversation queue"""
        
    async def dequeue_conversation(
        self,
        count: int = None
    ) -> list[ConversationTurn]:
        """Remove and return turns from conversation queue"""
        
    async def get_conversation_queue_size(self) -> int:
        """Get conversation queue size"""
        
    async def flush_conversation_queue(self) -> list[ConversationTurn]:
        """Flush all turns from conversation queue"""

class ConversationTurn(TypedDict):
    id: str
    conversation_id: str
    turn_number: int
    role: str
    content: str
    timestamp: str
    platform: str
Code Review Pipeline
class CodeReviewPipeline:
    async def review_file(self, file_path: str, content: str) -> CodeReviewResult:
        """Execute 5-gate code review"""
        
    async def gate1_syntax_format(self, content: str) -> GateResult:
        """Gate 1: Syntax & Format (py_compile, black, isort)"""
        
    async def gate2_lint(self, content: str) -> GateResult:
        """Gate 2: Lint (flake8)"""
        
    async def gate3_runtime_security(self, content: str) -> GateResult:
        """Gate 3: Runtime & Security (mypy, secrets, etc)"""
        
    async def gate4_complexity(self, content: str) -> GateResult:
        """Gate 4: Complexity & Nesting"""
        
    async def gate5_naming_design(self, content: str) -> GateResult:
        """Gate 5: Naming & Design"""

class CodeReviewResult(TypedDict):
    file_path: str
    gates: list[GateResult]
    blocked: bool
    errors: list[CodeIssue]
    warnings: list[CodeIssue]

class GateResult(TypedDict):
    gate: int
    name: str
    status: 'PASS' | 'FAIL' | 'WARN'
    errors: list[CodeIssue]
    warnings: list[CodeIssue]
Policy Enforcement
class PolicyEnforcer:
    def enforce_testing_policy(self, content: str, file_path: str) -> PolicyResult:
        """Block mocking patterns in test files"""
        
    def enforce_import_policy(self, content: str) -> PolicyResult:
        """Block relative imports"""
        
    def enforce_development_policy(self, arguments: dict) -> PolicyResult:
        """Block pip, require uv"""
        
    def enforce_bash_safety(self, command: str) -> PolicyResult:
        """Block destructive bash patterns"""
        
    def enforce_write_policy(self, file_path: str) -> PolicyResult:
        """Block writes to prohibited paths"""

class PolicyResult(TypedDict):
    allowed: bool
    violation: str
    suggestion: str
Deception Detection
class DeceptionDetector:
    def analyze(
        self,
        final_message: str,
        tool_call_history: list[ToolCall]
    ) -> DeceptionReport:
        """Analyze message for deception claims"""
        
    def check_file_creation_claims(
        self,
        message: str,
        tool_history: list[ToolCall]
    ) -> list[DeceptionFinding]:
        """Detect false file creation claims"""
        
    def check_command_claims(
        self,
        message: str,
        tool_history: list[ToolCall]
    ) -> list[DeceptionFinding]:
        """Detect false command execution claims"""
        
    def check_file_reading_claims(
        self,
        message: str,
        tool_history: list[ToolCall]
    ) -> list[DeceptionFinding]:
        """Detect false file reading claims"""
        
    def check_error_concealment(
        self,
        message: str,
        tool_results: list[ToolResult]
    ) -> list[DeceptionFinding]:
        """Detect unacknowledged tool errors"""

class DeceptionReport(TypedDict):
    session_id: str
    findings: list[DeceptionFinding]
    audited_at: str

class DeceptionFinding(TypedDict):
    type: 'ACTION_DECEPTION' | 'ERROR_CONCEALMENT' | 'FILE_READING_DECEPTION'
    severity: 'CRITICAL' | 'HIGH' | 'MEDIUM'
    claim: str
    evidence: str
    tool_calls_required: list[str]
    tool_calls_found: list[str]

Custom Tools Reference

Session Tools (9)
Tool Description Args
session-status Show current session info with formatting none
session-begin Start a new session purpose: string, objectives?: string[]
session-end End current session achievements?: string[], upcoming?: string[]
session-log-work Log a work entry desc: string, details?: string[]
session-log-achievement Log a completed achievement item: string
session-add-work Add a deferred work item text: string, priority?: string, notes?: string
session-complete-work Mark work item as done text: string
session-update-state Update project state version?: string, branch?: string, testState?: string, status?: string
session-log-choice Log a technical decision choice: string, reason: string
KG Tools (12)
Tool Description Args
kg-query Execute Cypher query against Neo4j query: string
kg-sync Trigger full KG sync via sync_monorepo_to_neo4j.py none
kg-queue-status Check pending files in sync queue none
kg-flush-queue Manually flush the KG sync queue none
kg-file-context Get KG context for a specific file path: string
kg-daemon-start Start the KG sync daemon none
kg-daemon-stop Stop the KG sync daemon none
kg-daemon-status Check KG sync daemon status none
kg-find-file Find files by name pattern in KG pattern: string
kg-find-entity Find entities (classes/functions) by name name: string
kg-stats Get KG statistics (node/relationship counts) none
kg-cxp-thread Query CXP thread packets thread_id: string
Conversation Tools (3)
Tool Description Args
conv-sync Flush conversation queue to Neo4j none
conv-status Check conversation queue depth none
conv-query Query stored conversations query: string

KG Query Tools (Python)

Tool Hierarchy
kg_query (bash wrapper)
    └── kg_query_inner.py (invoked via uv run)
            └── Neo4jClient from orchestrata.knowledge

kg_query.py (standalone async)
    └── Neo4jClient from orchestrata.knowledge

neo4j_query.py (standalone async)
    └── Neo4jClient from orchestrata.knowledge (with fallback mock)

simple_kg_query.py (connectivity test)
    └── Neo4jClient from orchestrata.knowledge
Project Scoping (kg_query_inner.py)

The inner query tool automatically rewrites Cypher queries to scope results to the current project:

  1. File path pattern: MATCH (f:File {path: $path}) rewritten to anchor through (p:Project)-[:HAS_FILE]->(f:File)
  2. Spec ID pattern: MATCH (s:Spec {id: $id}) rewritten to anchor through (p:Project)-[:HAS_SPEC]->(s:Spec)
  3. Requirement pattern: MATCH (r:Requirement {id: $id}) rewritten to anchor through (p:Project)-[:HAS_REQUIREMENT]->(r:Requirement)
  4. General MATCH: Adds WHERE EXISTS { MATCH (p)-[r]->() } clause checking 30+ relationship types from the project node
  5. Fallback: Wraps unrecognized queries in project context

Agent Definitions

Auto KG Context Agent (auto-kg-context.md)

Purpose: Automatically provides knowledge graph context without explicit user commands.

Trigger Patterns:

Automatic Queries:

KG Context Agent (kg-context-agent.md)

Purpose: Manual complement to the auto agent, focusing on architectural relationships and spec-to-code traceability.

Activation: Triggered by mentions of files, classes, functions, code structure questions, refactoring requests, and specification inquiries.

Query Types:


Commands

/query-kg

Usage: /query-kg <cypher_query> [parameters_json]

Description: Interactive Cypher query execution against the Neo4j knowledge graph.

Examples:

/query-kg "MATCH (n) RETURN count(n) as count"

/query-kg "MATCH (f:File {path: $path}) RETURN f.path, f.line_count, f.language"
  '{"path": "/home/mohamed/.../traceability/__init__.py"}'

/query-kg "MATCH (s:Spec {id: $spec_id})-[:DEFINES_REQUIREMENT]->(r:Requirement)
  RETURN r.id, r.text" '{"spec_id": "001"}'

/query-kg "MATCH (s:Spec) RETURN s.id, s.title ORDER BY s.id"

Connection: from the active env profile (test fleet: bolt://10.53.2.10:7687), database: orchkg (auth-less Memgraph)


Configuration

Infrastructure
Service Address Purpose
Memgraph KG From active env profile (test fleet: bolt://10.53.2.10:7687) Knowledge graph storage (orchkg database)
Redis From active env profile (test fleet: 10.53.2.11:6379) Queue storage (KG sync, conversations)
MCP Reader http://localhost:3456/health Document reader server
MCP Writer http://localhost:3457/health Document writer server
Redis Keys
Key Type Purpose
orchestrata:kg:sync:queue SET Files pending KG synchronization
orchestrata:conversation:queue LIST Conversation turns pending Neo4j storage
Deployment
# Install from project root
cd open-code && ./install.sh

# Deploys to:
#   ~/.opencode/agents/
#   ~/.opencode/commands/
#   ~/.opencode/plugins/
#   ~/.opencode/tools/
#   ~/.config/opencode/
Dependencies
Dependency Version Purpose
@opencode-ai/plugin 1.3.3 Plugin framework API
Bun latest TypeScript runtime
Python 3.14t free-threaded KG query tools, session CLI
neo4j (Python) 5.x Neo4j driver for Python tools
redis (Python) 4.x Redis client for queue operations
uv latest Python package manager

KG Statistics

Category Count
Total Nodes 558,000+
Total Relationships 548,000+
Packages 23
Files 439
Classes 934
Functions 522
CXP Packets 223,000+
Test Results 156,000+
Sessions 6,000+
Requirements 2,700+
User Stories 147
Prolog Rules 28,000+

Trigger Phrases
Pattern Regex
"remember when" /remember\s+when/i
"do you remember" /do\s+you\s+remember/i
"recall when" /recall\s+when/i
"remember that" /remember\s+that/i
"we discussed" /we\s+discussed/i
"we talked about" /we\s+talked\s+about/i
"last time we" /last\s+time\s+we/i
"what happened with" /what\s+happened\s+with/i
Search Algorithm
  1. Extract topic text after the trigger phrase
  2. Split topic into words, filter out words with fewer than 3 characters
  3. Load last 20 sessions from context.json
  4. For each session (newest first), check:
    • Purpose field for word matches
    • Achievements list for word matches
    • Work log entries for word matches
  5. Collect up to 10 matches with session number, date, match type, and matched text
  6. Inject results into output context as a formatted block

Session Close Sequence

Detection

Triggers on exact or suffix matches: "close the session", "cts", "cs", "end session", "finish session"

Steps
  1. Validate: Check for active session via session_cli.py status --json
  2. Extract Achievements: git log --oneline --since="2 hours ago" -20, filter out checkpoint commits, take top 10
  3. End Session: session_cli.py end --achievements "..."
  4. Push Branch: git push origin HEAD
  5. Report: Display formatted close report with session number, achievements, push status
  6. Clear State: Reset toolCallHistory and readCount

Error Handling Strategy

Component Failure Mode Behavior
Session CLI Process error Non-blocking, logged to client.app.log
Neo4j KG query Connection timeout Non-blocking, file read proceeds without context
Redis queue Connection refused Non-blocking, sync/conversation storage skipped
MCP health check Server down Non-blocking, logged as info
Git checkpoint Dirty worktree Non-blocking, --no-verify with || true
Code review Python tool error Non-blocking unless it is the review's own thrown error
KG sync daemon Process crash Non-blocking, queue persists in Redis
Conversation sync Neo4j write failure Non-blocking, turns remain in Redis queue

All non-blocking failures follow the pattern: try { operation } catch { /* Non-blocking */ log_and_continue }


Security Considerations

  1. KG Connection: Endpoint taken from the active env profile (KG_ROUTING_URI/KG_DATABASE); the KG is auth-less Memgraph — no credentials, no local-development fallbacks (RUL-003)
  2. Bash Safety: Destructive patterns (rm -rf /, fork bombs) blocked before execution
  3. Secret Detection: Hardcoded passwords, API keys, secrets, and tokens flagged in Gate 3
  4. Write Restrictions: ~/.claude/plans/ path blocked to prevent plan file creation
  5. Read Throttling: 50-read limit prevents runaway file scanning
  6. Message Truncation: Conversation content capped at 2000 characters before Neo4j storage
  7. Tool History Cap: Only last 100 tool calls retained to bound memory usage

Appendix A: Complete File Inventory

File Lines Language Purpose
opencode/plugins/orchestrata.ts 3,234 TypeScript Main plugin with all hooks and tools
open-code/agents/auto-kg-context.md ~120 Markdown Auto KG context agent definition
open-code/agents/kg-context-agent.md ~60 Markdown Manual KG context agent definition
open-code/commands/query-kg.md ~50 Markdown /query-kg command definition
open-code/tools/kg_query 3 Bash Shell wrapper for uv environment
open-code/tools/kg_query.py ~120 Python Full-featured async query tool
open-code/tools/kg_query_inner.py ~230 Python Core query with project scoping
open-code/tools/neo4j_query.py ~120 Python Standalone direct query tool
open-code/tools/simple_kg_query.py ~90 Python Simplified connectivity test
open-code/install.sh ~30 Bash Deployment script

Appendix B: Deception Detection Patterns

File Creation Claims (ACTION_DECEPTION, CRITICAL)
/(?:i'?ve\s+)?(?:created|wrote|written|saved|generated)\s+(?:the\s+)?(?:file|script|config)/
/(?:i'?ve\s+)?(?:created|added)\s+[\w\-]+\.(py|js|ts|json|md|yaml|yml|txt|sh)/
/here'?s\s+the\s+(?:new\s+)?(?:file|script|code)\s+(?:i\s+)?(?:created|wrote)/
Command Execution Claims (ACTION_DECEPTION, CRITICAL)
/(?:i'?ve\s+)?(?:ran|executed|run)\s+(?:the\s+)?(?:command|script|test)/
/(?:i'?ve\s+)?(?:installed|updated|upgraded)\s+(?:the\s+)?(?:package|dependency)/
/running\s+(?:the\s+)?(?:tests?|build|lint)/
File Reading Claims (FILE_READING_DECEPTION, HIGH)
/(?:i'?ve\s+)?(?:read|examined|reviewed|analyzed|looked at)\s+(?:the\s+)?(?:file|code|contents)/
/after\s+(?:reading|examining|reviewing)\s+(?:the\s+)?(?:file|code)/

Observability

Logging Requirements
  1. Component Logging
    • Log all major operations with appropriate log levels
    • Include correlation IDs for request tracing
    • Log performance metrics for critical operations
    • Log errors with full context for debugging
Metrics Requirements
  1. Performance Metrics
    • Operation duration histograms
    • Request/error rate counters
    • Resource utilization gauges
    • Business metrics relevant to domain
Tracing Requirements
  1. Distributed Tracing
    • Trace propagation across component boundaries
    • Span attributes for domain-specific context
    • Trace sampling based on operational needs
Alerting Requirements
  1. Critical Alerts
    • Error rate spikes
    • Performance degradation
    • Resource exhaustion
    • Business metric anomalies
Dashboard Requirements
  1. Operational Dashboard
    • Real-time system health
    • Performance trends
    • Error analysis
    • Resource monitoring

Visual Architecture

Class Diagram

Diagram projects-orchestrata-ultimate-specs-021-opencode-integration-m97ef3c6312


Revision History

Version Date Author Changes
1.0.0 2026-03-29 Mohamed Initial spec creation
1.0.1 2026-04-09 Mohamed Added Data Models, Functional Requirements (FR-001-017), Error Conditions (ERR-001-020), Non-Functional Requirements, Governance, Testing, Integration Points, Success Criteria sections per SPEC_STANDARD.md