Orchestrata Ultimate / RTM / 020-claude-code-harness
RTM: 020-claude-code-harness
Requirement to symbol to test rows for 020-claude-code-harness: Claude Code Harness.
At a glance
| Item | Value |
|---|---|
| Requirement IDs | 246 |
Traced from src/ |
9 (3.7%) |
| Untraced | 237 |
Cited from tests/ |
1 (0.4%) |
Traced in src/ but not cited from tests/ |
9 |
Reading this matrix
This matrix lists each of the 246 requirement IDs of spec 020-claude-code-harness with the src/ symbols that cite it and the tests that cite it. 9 of them (3.7%) have at least one citing symbol and 237 have none.
1 requirement is also cited from tests/, and 9 are traced in code but never named by a test. A test citation is a @traces on a test function; it shows intent to cover, not that the test runs or reaches the symbol.
Rows showing none in the symbols column are the gaps to close first. The densest untraced groups are REQ-020-* (237).
Requirement to symbols to tests
| Requirement | Symbols in src/ |
Tests citing it |
|---|---|---|
REQ-020-001 session_auto_start.py fires on SessionStart event |
none | none |
REQ-020-002 Hook only runs for projects with "orchestrata" in the path |
none | none |
REQ-020-003 Hook imports SessionController from ~/.claude/tools/session/ |
none | none |
REQ-020-004 Hook checks if last session has no length field (still active) and skips creation |
none | none |
REQ-020-005 Hook checks if last session was created <300 seconds ago and skips creation |
none | none |
REQ-020-006 Hook calls SessionController.begin() with timestamped purpose string |
none | none |
REQ-020-007 Hook outputs session number, start time, and purpose to stdout |
none | none |
REQ-020-008 Hook handles ImportError gracefully (prints error, does not crash) |
none | none |
REQ-020-009 Hook handles SessionController initialization failure gracefully |
none | none |
REQ-020-010 Hook reads cwd from JSON stdin input |
none | none |
REQ-020-011 session_close_hook.py fires on UserPromptSubmit event |
none | none |
REQ-020-012 Hook detects "cts" trigger (case-insensitive, trimmed) |
none | none |
REQ-020-013 Hook detects "cs" trigger (case-insensitive, trimmed) |
none | none |
REQ-020-014 Hook detects "close the session" trigger (case-insensitive, trimmed) |
none | none |
REQ-020-015 Hook finds project root by walking up from cwd looking for context.json |
none | none |
REQ-020-016 Hook generates RTM from @traces decorators via subprocess calls |
none | none |
REQ-020-017 Hook extracts achievements from git log since session start |
none | none |
REQ-020-018 Hook calls SessionController.end() to update context.json |
none | none |
REQ-020-019 Hook creates annotated git tag in format session-NNN-YYYY-MM-DD-HHMM |
orchestrata_ultimate/session/controller/_git _create_session_tag L134 |
none |
REQ-020-020 Hook updates CHANGELOG.md with categorized achievements |
orchestrata_ultimate/session/controller/_changelog _append_remaining_categories L216orchestrata_ultimate/session/controller/_changelog _categorize_achievements L135orchestrata_ultimate/session/controller/_changelog _category_for_header L158+6 more |
none |
REQ-020-021 Hook pushes session tag to origin via git push origin |
orchestrata_ultimate/session/controller/_git _git_env L16orchestrata_ultimate/session/controller/_git _push_session_tag L165 |
none |
REQ-020-022 Hook pushes current branch to origin via git push origin HEAD |
orchestrata_ultimate/session/controller/_git _commit_and_push_changes L39orchestrata_ultimate/session/controller/_git _current_branch L118orchestrata_ultimate/session/controller/_git _git_env L16 |
none |
REQ-020-023 Hook injects close summary into additionalContext |
none | none |
REQ-020-024 RTM generation failures are logged but do not block session close |
none | none |
REQ-020-025 Hook does not block (Claude still sees the prompt) |
none | none |
REQ-020-026 session_open_hook.py fires on UserPromptSubmit event |
none | none |
REQ-020-027 Hook detects "sns" and "start new session" triggers |
none | none |
REQ-020-028 Hook displays pending deferred work items grouped by priority |
none | none |
REQ-020-029 Hook injects project metrics into additionalContext |
none | none |
REQ-020-030 session_context_hook.py fires on SessionStart event |
none | none |
REQ-020-031 Hook injects session context into conversation on startup |
none | none |
REQ-020-032 error_gate_hook.py fires on Stop event |
none | none |
REQ-020-033 Hook delegates to error_gate package main() function |
none | none |
REQ-020-034 error_gate.__init__ runs all 6 check categories sequentially |
none | none |
REQ-020-035 Check order: syntax, lint, stubs, nesting, god objects, tests |
none | none |
REQ-020-036 If any errors found, Stop is blocked with decision: block |
none | none |
REQ-020-037 Error report includes numbered fix instructions (6 steps) |
none | none |
REQ-020-038 Error report printed to stderr for operator visibility |
none | none |
REQ-020-039 If no errors, empty JSON {} returned (allow stop) |
none | none |
REQ-020-040 Hook reads and discards stdin JSON (not used) |
none | none |
REQ-020-041 checks_syntax.py finds modified .py files via `git diff --name-only --diff-filter=M... |
none | none |
REQ-020-042 Each modified .py file parsed with ast.parse() via subprocess |
none | none |
REQ-020-043 Syntax errors reported with file path and error message (truncated to 200 chars) |
none | none |
REQ-020-044 Non-existent files (deleted after diff) are skipped |
none | none |
REQ-020-045 Git command failure returns empty error list (not crash) |
none | none |
REQ-020-046 checks_lint.py finds modified .py files via git diff |
none | none |
REQ-020-047 Runs uv run flake8 --select=E9,F82,F83,F84 --max-line-length=120 |
none | none |
REQ-020-048 Modified files capped at 30 per run to avoid timeout |
none | none |
REQ-020-049 Lint errors reported up to 10 per run |
none | none |
REQ-020-050 Empty file list results in no flake8 invocation |
none | none |
REQ-020-051 Uses shutil.which("uv") with fallback to ~/.local/bin/uv |
none | none |
REQ-020-052 checks_test.py finds changed test files via git diff --name-only HEAD~1 |
none | none |
REQ-020-053 Only files under tests/ ending in .py are selected |
none | none |
REQ-020-054 Files with "prolog" in name are excluded |
none | none |
REQ-020-055 Files importing pyswip or GovernanceEngine are excluded |
none | none |
REQ-020-056 Files importing orchestrata.governance or PrologBridge are excluded |
none | none |
REQ-020-057 If tests/conftest.py uses pyswip, all tests are skipped |
none | none |
REQ-020-058 Test file count capped at 10 per run |
none | none |
REQ-020-059 Runs uv run pytest -x -q --no-header on selected files |
none | none |
REQ-020-060 Test timeout is 300 seconds |
none | none |
REQ-020-061 Exit code 139 (SIGSEGV) treated as infrastructure issue, not test failure |
none | none |
REQ-020-062 Only lines containing "FAILED" reported as test failures |
none | none |
REQ-020-063 checks_structure.py scans non-test modified .py files for stubs |
none | none |
REQ-020-064 Stub defined as function body with only logging, local assigns, pass, docstrings |
none | none |
REQ-020-065 __init__, __del__, __enter__, __exit__, close, cleanup excluded |
none | none |
REQ-020-066 Private functions (starting with _) excluded from stub detection |
none | none |
REQ-020-067 await expressions are NOT classified as stubs |
none | none |
REQ-020-068 self.x += 1 (augmented assignment on attributes) is NOT a stub |
none | none |
REQ-020-069 Log calls detected via dotted name resolution (logger.info, log.debug, etc.) |
none | none |
REQ-020-070 List appends (.append()) treated as logging-equivalent for stub detection |
none | none |
REQ-020-071 return None and bare return treated as trivial returns in stubs |
none | none |
REQ-020-072 raise in first 2 statements treated as guard clause, not real work |
none | none |
REQ-020-073 Nesting measured for all functions in modified .py files |
none | none |
REQ-020-074 Nesting types: if, for, while, with, try, async for, async with |
none | none |
REQ-020-075 Functions exceeding 4 levels of nesting are flagged |
none | none |
REQ-020-076 Error message includes function name, line number, actual depth, and max allowed |
none | none |
REQ-020-077 Classes exceeding 300 lines flagged (end_lineno - lineno + 1) |
none | none |
REQ-020-078 Classes with >15 public methods flagged (not starting with _) |
none | none |
REQ-020-079 Files exceeding 500 lines flagged |
none | none |
REQ-020-080 Only source files checked (test files excluded) |
none | none |
REQ-020-081 Generated directories (spike/, iterations/, ci/) excluded |
none | none |
REQ-020-082 utils.py provides run_command() with subprocess timeout handling |
none | none |
REQ-020-083 utils.py provides get_modified_py_files() with git diff discovery |
none | none |
REQ-020-084 utils.py provides parse_file() with safe AST parsing (returns None on failure) |
none | none |
REQ-020-085 PROJECT_ROOT configurable via ORCHESTRATA_ROOT environment variable |
orchestrata_ultimate/core/paths get_project_root L23orchestrata_ultimate/core/paths resolve_project_root L46 |
none |
REQ-020-086 CHECK_TIMEOUT set to 30 seconds per check |
none | none |
REQ-020-087 FileNotFoundError from missing tools treated as skip (returns exit 0) |
none | none |
REQ-020-088 stop_auditor.py fires on Stop event |
none | none |
REQ-020-089 Hook reads JSON from stdin with session_id and transcript_path |
none | none |
REQ-020-090 Hook detects SubagentStop events and delegates to subagent handler |
none | none |
REQ-020-091 Hook extracts assistant messages from JSONL transcript |
none | none |
REQ-020-092 Hook loads tool calls from session JSONL file |
none | none |
REQ-020-093 Hook calls detect_deception() with assistant message and tool calls |
none | none |
REQ-020-094 Hook logs findings to deception_log.jsonl |
none | none |
REQ-020-095 Hook archives session JSONL to dated directory |
none | none |
REQ-020-096 Hook formats findings as severity-colored report (CRITICAL/HIGH/MEDIUM/LOW) |
none | none |
REQ-020-097 Hook outputs report via additionalContext if findings exist |
none | none |
REQ-020-098 Hook prints "No issues detected" to stderr if clean |
none | none |
REQ-020-099 deception.py strips code blocks (triple backtick) before analysis |
none | none |
REQ-020-100 Strips inline code (single backtick) before analysis |
none | none |
REQ-020-101 Strips blockquotes (lines starting with >) before analysis |
none | none |
REQ-020-102 Strips HTML pre/code tags before analysis |
none | none |
REQ-020-103 File creation claims flagged as CRITICAL if Write/Edit not in tools_used |
none | none |
REQ-020-104 Command execution claims flagged as CRITICAL if Bash not in tools_used |
none | none |
REQ-020-105 File reading claims flagged as HIGH if Read/Grep not in tools_used |
none | none |
REQ-020-106 Tool errors (has_error=True) not mentioned in response flagged as CRITICAL |
none | none |
REQ-020-107 Error concealment checked against 11 error-related terms |
none | none |
REQ-020-108 Sessions with >10 tool calls but <100 char response flagged as MEDIUM |
none | none |
REQ-020-109 Tool output >500 chars with <3 overlapping 6+ char words flagged as MEDIUM |
none | none |
REQ-020-110 Findings include type, severity, description, evidence fields |
none | none |
REQ-020-111 Action deception findings include pattern_matched field |
none | none |
REQ-020-112 Error concealment findings include tool_name field |
none | none |
REQ-020-113 Result hiding findings include tool_name field |
none | none |
REQ-020-114 transcript.py reads JSONL file line by line |
none | none |
REQ-020-115 Extracts entries with message.role == "assistant" |
none | none |
REQ-020-116 Handles string content (direct text) |
none | none |
REQ-020-117 Handles list content with typed blocks (type == "text") |
none | none |
REQ-020-118 Corrupt JSON lines skipped with warning to stderr |
none | none |
REQ-020-119 Missing or empty transcript returns empty string |
none | none |
REQ-020-120 IOError/OSError on file read returns empty list |
none | none |
REQ-020-121 stop_auditor_subagent.py detects SubagentStop events |
none | none |
REQ-020-122 Parses subagent transcript for tool usage and text content |
none | none |
REQ-020-123 Runs same detect_deception() logic on subagent sessions |
none | none |
REQ-020-124 Logs subagent findings to ~/.claude/audit/subagent_findings/ |
none | none |
REQ-020-125 stop_audit/subagent.py re-exports from stop_auditor_subagent.py |
none | none |
REQ-020-126 Findings logged with timestamp (epoch and ISO format) |
none | none |
REQ-020-127 Log entry includes session_id and findings_count |
none | none |
REQ-020-128 Log entry includes tools_used set and tool_calls_count |
none | none |
REQ-020-129 Log entry includes assistant_message_length and preview (500 chars) |
none | none |
REQ-020-130 Findings directory auto-created with parents=True, exist_ok=True |
none | none |
REQ-020-131 intercept_bash.py fires on PreToolUse(Bash) |
none | none |
REQ-020-132 rm command detected via regex \brm\s |
none | none |
REQ-020-133 rm with flags detected via regex \brm\s+- |
none | none |
REQ-020-134 unlink command detected via regex \bunlink\s |
none | none |
REQ-020-135 rmdir command detected via regex \brmdir\s |
none | none |
REQ-020-136 shred command detected via regex \bshred\s |
none | none |
REQ-020-137 Redirect to ~/.claude/ detected (> and >> patterns) |
none | none |
REQ-020-138 cat >, echo >, cp, mv, touch, mkdir to ~/.claude/ detected |
none | none |
REQ-020-139 Full path patterns (/home/*/\.claude/) also detected |
none | none |
REQ-020-140 Blocked commands logged with operation type "Bash-Delete-Blocked" |
none | none |
REQ-020-141 Claude-dir blocks logged with operation type "Bash-Claude-Dir-Blocked" |
none | none |
REQ-020-142 Allowed commands return {"decision": "allow"} |
none | none |
REQ-020-143 Block response includes the original command for manual execution |
none | none |
REQ-020-144 intercept_write.py fires on PreToolUse(Write) |
none | none |
REQ-020-145 Files that already exist are blocked with "use Edit tool" message |
none | none |
REQ-020-146 Writes to ~/.claude/plans/ blocked with redirect to project plans/ |
none | none |
REQ-020-147 Writes to context.md blocked with session CLI instructions |
none | none |
REQ-020-148 Writes to context.json blocked with session CLI instructions |
none | none |
REQ-020-149 New file creation to valid paths returns {"decision": "allow"} |
none | none |
REQ-020-150 Missing file_path returns block with error message |
none | none |
REQ-020-151 All operations (allowed and blocked) logged to file_operations.log |
none | none |
REQ-020-152 Log entries include timestamp, operation, file_path, status, message |
none | none |
REQ-020-153 intercept_edit.py fires on PreToolUse(Edit) |
none | none |
REQ-020-154 Git checkpoint created before edits |
none | none |
REQ-020-155 Edit operations logged to audit file |
none | none |
REQ-020-156 block_except_pass.py fires on PreToolUse(Write|Edit) |
none | none |
REQ-020-157 Bare except: (no exception type) detected via AST |
none | none |
REQ-020-158 except ...: pass (single-statement pass body) detected via AST |
none | none |
REQ-020-159 Detection uses ast.parse() not regex |
none | none |
REQ-020-160 Only .py files checked (non-Python files pass through) |
none | none |
REQ-020-161 Violation message includes line number |
none | none |
REQ-020-162 Violation message suggests specific exception type with logging |
none | none |
REQ-020-163 For tuple exception types, all types listed in message |
none | none |
REQ-020-164 SyntaxError in content does not crash the hook (returns empty) |
none | none |
REQ-020-165 Non-Python files return empty JSON (allow) |
none | none |
REQ-020-166 block_file_tools.py fires on PreToolUse(Read|Grep) when active |
none | none |
REQ-020-167 Queries Neo4j for file-scoped entities (classes, functions) |
none | none |
REQ-020-168 Queries Neo4j for specification traceability |
none | none |
REQ-020-169 Queries Neo4j for related nodes via full-text search |
none | none |
REQ-020-170 Results injected as additionalContext in hook output |
none | none |
REQ-020-171 context.json is never trimmed or truncated |
none | none |
REQ-020-172 All sessions recorded in session_history array |
orchestrata_ultimate/session/context _parse_session_record L987orchestrata_ultimate/session/context _parse_session_records L1032orchestrata_ultimate/session/context add_session L382+3 more |
none |
REQ-020-173 state object tracks current session number, version, branch, test count, status |
orchestrata_ultimate/session/context read_state L346orchestrata_ultimate/session/context update_state L352orchestrata_ultimate/session/models ProjectState L168 |
none |
REQ-020-174 deferred_work array tracks pending tasks with priority and notes |
orchestrata_ultimate/session/context _parse_carryover_tasks L939orchestrata_ultimate/session/context add_work_item L423orchestrata_ultimate/session/context complete_work_item L483+6 more |
none |
REQ-020-175 Direct writes to context.json blocked by intercept_write.py |
none | none |
REQ-020-176 Direct writes to context.md blocked by intercept_write.py |
none | none |
REQ-020-177 sync_context_md.py fires on PostToolUse(Write|Edit) |
none | none |
REQ-020-178 Hook only acts when modified file is context.json |
none | none |
REQ-020-179 Hook imports ContextManager from ~/.claude/tools/session/ |
none | none |
REQ-020-180 Hook calls ContextManager.write() to regenerate context.md |
none | none |
REQ-020-181 context.md shows only last 3 sessions (SESSION_LIMIT) |
none | none |
REQ-020-182 Regeneration failure logged but does not block |
none | none |
REQ-020-183 Non-context.json files result in empty JSON (pass through) |
none | none |
REQ-020-184 read_throttle.py fires on PreToolUse(Read|Grep) |
none | none |
REQ-020-185 Read timestamps tracked in /tmp/claude-read-tracker.json |
none | none |
REQ-020-186 Maximum 3 reads allowed per 30-second sliding window |
none | none |
REQ-020-187 Expired timestamps pruned on each check (window filter) |
none | none |
REQ-020-188 Reads of context.json exempted from throttle |
none | none |
REQ-020-189 Reads of .env exempted from throttle |
none | none |
REQ-020-190 Reads of settings.json exempted from throttle |
none | none |
REQ-020-191 Reads of CLAUDE.md exempted from throttle |
none | none |
REQ-020-192 Throttled reads blocked with {"decision": "block", "reason": "..."} |
none | none |
REQ-020-193 Block message includes Neo4j query examples (/code commands) |
none | none |
REQ-020-194 Block message includes raw Cypher query example |
none | none |
REQ-020-195 Non-Read/Grep tools pass through with empty JSON |
none | none |
REQ-020-196 JSON parse error on stdin returns empty JSON (no crash) |
none | none |
REQ-020-197 File save failure logged to stderr (no crash) |
none | none |
REQ-020-198 posttool_auditor.py fires on PostToolUse(.*) |
none | none |
REQ-020-199 Records tool_name, has_error, tool_output, tool_output_length |
none | none |
REQ-020-200 Records written to session JSONL in ~/.claude/audit/sessions/ |
none | none |
REQ-020-201 log_operation.py fires on PostToolUse(Write|Edit|Bash|Read|Glob|Grep) |
none | none |
REQ-020-202 Log entries include timestamp, operation, file_path/command, status, message |
none | none |
REQ-020-203 Logs written to ~/.claude/logs/file_operations.log as JSONL |
none | none |
REQ-020-204 Active sessions stored in ~/.claude/audit/sessions/{session_id}.jsonl |
none | none |
REQ-020-205 Completed sessions moved to ~/.claude/audit/archive/YYYY-MM-DD/ |
none | none |
REQ-020-206 Archive filename includes session_id and epoch timestamp |
none | none |
REQ-020-207 Archive uses shutil.move() (move, not copy) to prevent duplicates |
none | none |
REQ-020-208 Archive data NEVER deleted |
none | none |
REQ-020-209 Audit directories auto-created with parents=True, exist_ok=True |
none | none |
REQ-020-210 Session close hook runs RTM generation scripts via subprocess |
none | none |
REQ-020-211 Scripts parse @traces(spec=, story=, reqs=[]) decorators from source |
none | none |
REQ-020-212 RTM output committed to plans/ directory |
none | none |
REQ-020-213 RTM generation failures logged but do not block session close |
none | tests/claude/test_session_close_rtm.py::test_missing_generator_degrades_without_raising |
REQ-020-214 Generated RTM maps requirements to implementing functions/classes |
none | none |
REQ-020-215 remember_hook.py fires on UserPromptSubmit event |
none | none |
REQ-020-216 Detects "remember when" trigger phrase |
none | none |
REQ-020-217 Detects "do you remember" trigger phrase |
none | none |
REQ-020-218 Detects "recall when" trigger phrase |
none | none |
REQ-020-219 Detects "remember that" trigger phrase |
none | none |
REQ-020-220 Detects "we discussed" trigger phrase |
none | none |
REQ-020-221 Detects "we talked about" trigger phrase |
none | none |
REQ-020-222 Detects "last time we" trigger phrase |
none | none |
REQ-020-223 Detects "what happened with" trigger phrase |
none | none |
REQ-020-224 Triggers compiled into single regex pattern (case-insensitive) |
none | none |
REQ-020-225 Topic extracted from text after trigger phrase |
none | none |
REQ-020-226 Falls back to whole message (minus trigger) if no text after trigger |
none | none |
REQ-020-227 Empty topic results in no search (empty JSON returned) |
none | none |
REQ-020-228 Query searches ConversationTurn.text with case-insensitive word matching |
none | none |
REQ-020-229 Only words with length >2 used as search terms |
none | none |
REQ-020-230 Query returns up to 15 results ordered by timestamp descending |
none | none |
REQ-020-231 Results include session_id, turn sequence, role, text (500 char limit), timestamp |
none | none |
REQ-020-232 Results injected as additionalContext with factual framing |
none | none |
REQ-020-233 Query timeout set to 15 seconds |
none | none |
REQ-020-234 KG connection parameters loaded from the active env profile... |
none | none |
REQ-020-235 Env files parsed for key=value pairs (strips quotes, skips comments); profile overlays... |
orchestrata_ultimate/core/env_bootstrap _find_repo_root L79orchestrata_ultimate/core/env_bootstrap _parse_env_file L21orchestrata_ultimate/core/env_bootstrap load_env_contract L105+1 more |
none |
REQ-020-236 Missing Neo4j connection returns "(Search failed: ...)" not block |
none | none |
REQ-020-237 subprocess.TimeoutExpired handled gracefully |
none | none |
REQ-020-238 FileNotFoundError (missing uv) handled gracefully |
none | none |
REQ-020-239 Non-matching prompts return empty JSON (no search) |
none | none |
REQ-020-240 JSON parse error on stdin returns empty JSON (no crash) |
none | none |
REQ-020-241 claude/tools/notify sends a desktop notification via the system notifier |
none | none |
REQ-020-242 Notification fires at CRITICAL urgency — normal urgency is suppressed by a focused... |
none | none |
REQ-020-243 The CLI is deployed to ~/.claude/tools/notify by deploy/install-claude-config.sh... |
none | none |
REQ-020-244 claude/hooks/decision_adr_trigger.sh fires on UserPromptSubmit and detects any... |
none | none |
REQ-020-245 On a match the hook injects the ADR discipline (ADR-0046 three homes, ADR-0047 two... |
none | none |
REQ-020-246 The trigger exists at BOTH levels — user (claude/hooks/decision_adr_trigger.sh,... |
none | none |