@aryaminus/controlkeel-opencode 0.3.10 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,6 +11,27 @@ compatibility:
11
11
  - copilot-plugin
12
12
  - github-repo
13
13
  - open-standard
14
+ - cline-native
15
+ - cursor-native
16
+ - windsurf-native
17
+ - continue-native
18
+ - letta-code-native
19
+ - pi-native
20
+ - roo-native
21
+ - goose-native
22
+ - opencode-native
23
+ - gemini-cli-native
24
+ - kiro-native
25
+ - kilo-native
26
+ - amp-native
27
+ - augment-native
28
+ - hermes-native
29
+ - multica-native
30
+ - openclaw-native
31
+ - devin-terminal-native
32
+ - warp-native
33
+ - droid-bundle
34
+ - forge-acp
14
35
  disable-model-invocation: true
15
36
  metadata:
16
37
  author: controlkeel
@@ -0,0 +1,355 @@
1
+ ---
2
+ name: agent-pattern-verification
3
+ description: "Verify AI agent code for dangerous patterns including infinite loops, unbounded retries, tool hallucinations, and context overflow. Use before deploying agent workflows or when reviewing agent code."
4
+ when_to_use: "Activate when reviewing agent code, before deploying LangGraph/CrewAI/AutoGen workflows, or when the user asks about agent safety, loops, retries, or tool consistency."
5
+ argument-hint: "[agent directory or files to verify]"
6
+ license: Apache-2.0
7
+ compatibility:
8
+ - codex
9
+ - claude-standalone
10
+ - claude-plugin
11
+ - copilot-plugin
12
+ - github-repo
13
+ - open-standard
14
+ - cline-native
15
+ - cursor-native
16
+ - windsurf-native
17
+ - continue-native
18
+ - letta-code-native
19
+ - pi-native
20
+ - roo-native
21
+ - goose-native
22
+ - opencode-native
23
+ - gemini-cli-native
24
+ - kiro-native
25
+ - kilo-native
26
+ - amp-native
27
+ - augment-native
28
+ - hermes-native
29
+ - multica-native
30
+ - openclaw-native
31
+ - devin-terminal-native
32
+ - warp-native
33
+ - droid-bundle
34
+ - forge-acp
35
+ metadata:
36
+ author: controlkeel
37
+ version: "1.0"
38
+ category: security
39
+ ck_mcp_tools:
40
+ - ck_context
41
+ - ck_validate
42
+ - ck_finding
43
+ ---
44
+
45
+ # Agent Pattern Verification Skill
46
+
47
+ Verify AI agent code for common anti-patterns that can cause infinite loops, runaway retries, tool mismatches, and context overflow. This skill complements ControlKeel's security and compliance validation with agent-specific pattern detection.
48
+
49
+ ## When to Use
50
+
51
+ Trigger this skill when:
52
+ - Reviewing agent code before deployment
53
+ - Validating LangGraph, CrewAI, AutoGen, or LangChain workflows
54
+ - User asks about "agent safety", "infinite loops", "retry limits", or "tool consistency"
55
+ - Before merging agent workflow changes
56
+
57
+ ## Verification Flow
58
+
59
+ 1. **Call `ck_context`** to load the session context, risk tier, and existing findings
60
+ 2. **Detect agent framework** by scanning imports and configuration files
61
+ 3. **Run pattern checks** using the checklist below
62
+ 4. **Persist findings** with `ck_finding` for each issue discovered
63
+ 5. **Generate structured report** with pattern-matched vs heuristic tagging
64
+
65
+ ## Pattern Checks
66
+
67
+ All checks are classified as:
68
+ - `[PATTERN]` - Mechanical check, high reliability (applied exactly as specified)
69
+ - `[HEURISTIC]` - Judgment-based, best-effort (requires interpretation)
70
+
71
+ ### 1. Loop Safety `[PATTERN]`
72
+
73
+ Apply mechanically. Do not pass a loop because it "looks like it might terminate."
74
+
75
+ | Pattern to find | Pass condition | Severity |
76
+ |-----------------|----------------|----------|
77
+ | `while True:` in Python | A `break` statement exists within the same block scope | ⚠️ Warning if absent |
78
+ | `for { }` in Go | A `break` or `return` exists within the block | ⚠️ Warning if absent |
79
+ | `while (true)` in TypeScript/JavaScript | A `break` or `return` exists within the block | ⚠️ Warning if absent |
80
+ | Recursive function calls | A non-recursive return path exists (base case), OR a depth/counter parameter is present | ⚠️ Warning if absent |
81
+
82
+ **Heuristic Fallback**: After applying pattern table, scan for:
83
+ - Loops where termination depends entirely on external/runtime state with no timeout
84
+ - Generator functions that `yield` indefinitely without documented exit
85
+ - Event/polling loops without timeout parameters
86
+ - Recursive call chains across multiple functions without depth tracking
87
+
88
+ Flag as ⚠️ Warning: *"Potential unbounded loop not matching known patterns — verify termination condition manually"*
89
+
90
+ ### 2. Retry Limit Enforcement `[PATTERN]`
91
+
92
+ Apply mechanically. If required parameter is absent, flag as ❌ Issue.
93
+
94
+ **Python — Decorator-based:**
95
+
96
+ | Library/Pattern | Required parameter | Fail condition |
97
+ |-----------------|-------------------|----------------|
98
+ | `@retry` (tenacity) | `stop=stop_after_attempt(n)` or `stop=stop_after_delay(n)` | `stop=` absent |
99
+ | `@backoff.on_exception` | `max_tries=n` | `max_tries=` absent |
100
+
101
+ **Python — HTTP client retry:**
102
+
103
+ | Library/Pattern | Required parameter | Fail condition |
104
+ |-----------------|-------------------|----------------|
105
+ | `urllib3.Retry(...)` | `total=n` where n > 0 | `total=` absent or `total=0` |
106
+ | `HTTPAdapter(max_retries=Retry(...))` | Retry object must have `total=n` | `total=` absent |
107
+ | `httpx.HTTPTransport(retries=n)` | `retries=n` where n > 0 | `retries=` absent or `retries=0` |
108
+
109
+ **Python — AWS SDK (boto3):**
110
+
111
+ | Library/Pattern | Required parameter | Fail condition |
112
+ |-----------------|-------------------|----------------|
113
+ | `Config(retries={...})` | `max_attempts` > 1 | `max_attempts` absent or ≤ 1 |
114
+
115
+ > Note: boto3 without explicit retry config uses SDK defaults (3 attempts) — do not flag absence.
116
+
117
+ **JavaScript/TypeScript:**
118
+
119
+ | Library/Pattern | Required parameter | Fail condition |
120
+ |-----------------|-------------------|----------------|
121
+ | `retry(...)` (async-retry) | `retries: n` in options | `retries:` absent |
122
+ | `pRetry(...)` (p-retry) | `retries: n` in options | `retries:` absent |
123
+
124
+ **Custom retry loops (all languages):**
125
+
126
+ | Pattern to find | Pass condition | Fail condition |
127
+ |-----------------|----------------|----------------|
128
+ | Loop + `try/except` + `continue` | Integer counter with max check | No counter → ❌ Issue |
129
+
130
+ **Heuristic Fallback**: Scan for:
131
+ - Functions/decorators with "retry" in name not in tables above
132
+ - Imported modules with "retry" in package name (e.g. `stamina`, `aiohttp_retry`)
133
+ - Loops with sleep + exception handling + re-invocation without visible counter
134
+ - Config keys like `max_retries`, `retry_count`, `attempts`
135
+
136
+ Flag as ⚠️ Warning: *"Potential retry pattern not matching known libraries — verify retry bounds manually"*
137
+
138
+ ### 3. Tool Registry Consistency `[PATTERN]`
139
+
140
+ **Step 1: Collect defined tools**
141
+
142
+ Scan tool definition files. A name found by any pattern counts as registered.
143
+
144
+ *Python — decorator patterns:*
145
+
146
+ | Pattern | How to extract name |
147
+ |---------|---------------------|
148
+ | `@tool` (LangChain) on `def` | Function name below decorator |
149
+ | `@function_tool` (OpenAI Agents SDK) on `def` | Function name below decorator |
150
+ | `@tool(name="...")` | Use `name=` argument value |
151
+
152
+ *Python — dict/list patterns:*
153
+
154
+ | Pattern | How to extract name |
155
+ |---------|---------------------|
156
+ | `{"type": "function", "function": {"name": "..."}}` (OpenAI) | Value of `"name"` inside `"function"` |
157
+ | `{"name": "...", "input_schema": {...}}` (Anthropic) | Top-level `"name"` |
158
+ | `{"name": "...", "description": "...", "parameters": {...}}` | Top-level `"name"` |
159
+ | `ToolNode([func1, func2, ...])` (LangGraph) | Each function name in list |
160
+ | `tools = [func1, func2]` / `TOOLS = [...]` | Each identifier in list |
161
+
162
+ *TypeScript/JavaScript:*
163
+
164
+ | Pattern | How to extract name |
165
+ |---------|---------------------|
166
+ | `{ type: "function", function: { name: "..." } }` (OpenAI) | `name:` inside `function:` |
167
+ | `tool({ description: "...", parameters: z.object({...}) })` | The `const` variable name |
168
+ | `new DynamicTool({ name: "...", ... })` (LangChain.js) | Value of `name:` |
169
+ | `zodFunction({ name: "...", ... })` | Value of `name:` |
170
+
171
+ **Step 2: Collect tool references from prompts**
172
+
173
+ Scan `.md`, `.txt`, `prompts.py` for backtick-quoted identifiers naming capabilities.
174
+
175
+ **Step 3: Cross-reference**
176
+
177
+ | Finding | Severity |
178
+ |---------|----------|
179
+ | Reference not in definition list | ❌ Issue (hallucinated tool) |
180
+ | Defined tool not in any prompt | ⚠️ Warning (undocumented tool) |
181
+
182
+ **Heuristic**: Find where tools are defined and where LLM is invoked. If tools exist but are never connected to the LLM call, flag as ❌ Issue: *"Tools defined but never connected to LLM invocation"*
183
+
184
+ **Heuristic Fallback**: Scan for tool-like structures:
185
+ - Dicts with both `"description"` and `"parameters"` keys
186
+ - Functions with structured docstrings (name, params, return)
187
+ - Variables named `tools`, `tool_list`, `available_tools`, `functions`
188
+ - Classes with `run()`, `execute()`, or `__call__()` methods
189
+
190
+ Include in count and note: *"Tool detected via heuristic — verify this is an intended agent tool."*
191
+
192
+ ### 4. Context Size Awareness `[PATTERN]`
193
+
194
+ Formula: `token_estimate = len(file_content_chars) / 4`
195
+
196
+ | Content | ⚠️ Warning threshold | ❌ Issue threshold |
197
+ |---------|----------------------|-------------------|
198
+ | System prompt file | > 4,000 tokens | > 8,000 tokens |
199
+ | Single tool description | > 500 tokens | > 1,000 tokens |
200
+ | All tool descriptions combined | > 2,000 tokens | > 4,000 tokens |
201
+
202
+ **Exclude**: `skills/` directories (loaded on demand, not embedded)
203
+
204
+ **Heuristic Fallback**:
205
+ - Estimates within 20% of threshold → flag with tokenizer recommendation
206
+ - Dynamic prompts (f-strings, `.format()`) → flag if template alone is large
207
+ - Multiple concatenated prompts → estimate combined size
208
+ - Prompts with includes → note effective size may be larger
209
+
210
+ ### 5. LangGraph Graph Cycle Analysis `[PATTERN]`
211
+
212
+ *(Only when LangGraph is detected)*
213
+
214
+ **Detection steps:**
215
+ a. Find graph file (`graph.py`, `graph.ts`, or file with `StateGraph`/`MessageGraph`)
216
+ b. Build edge map:
217
+ - `workflow.add_edge(source, dest)` — unconditional edge
218
+ - `workflow.add_conditional_edges(source, fn, mapping)` — extract destinations from mapping
219
+ c. Identify cycles: nodes reachable from themselves
220
+ d. For each cycle, check if `END` (or `"__end__"`) is reachable via conditional edge
221
+
222
+ | Condition | Severity |
223
+ |-----------|----------|
224
+ | Cycle exists, `END` reachable via conditional | ✅ Pass |
225
+ | Cycle exists, no path to `END` | ❌ Issue |
226
+ | Graph has no `END` node | ❌ Issue |
227
+ | Node has no outgoing edges and is not `END` | ⚠️ Warning (dead-end) |
228
+
229
+ ## Framework Detection
230
+
231
+ Identify the agent framework by checking imports:
232
+
233
+ | Import Pattern | Framework |
234
+ |----------------|-----------|
235
+ | `from langgraph` or `import langgraph` | LangGraph |
236
+ | `from crewai` or `import crewai` | CrewAI |
237
+ | `from autogen` or `import autogen` | AutoGen |
238
+ | `from langchain` or `import langchain` | LangChain |
239
+ | Direct `openai`/`anthropic` SDK only | Custom |
240
+
241
+ Also check for framework config files: `langgraph.json`, `crew.yaml`.
242
+
243
+ ## File Discovery
244
+
245
+ **Priority files:**
246
+ - `graph.py`, `graph.ts` - Agent workflow definitions
247
+ - `tools.py`, `tools.ts`, `tools/*.py`, `tools/*.ts` - Tool implementations
248
+ - `state.py`, `state.ts` - State schemas
249
+ - `prompts.py`, `prompts/*.md`, `system.md` - Prompt templates
250
+ - `agent.py`, `agent.ts` - Main agent logic
251
+
252
+ **Directories to check:**
253
+ - `src/agent/`, `agent/`, `src/`, project root
254
+ - `lib/`, `app/`, `packages/`
255
+
256
+ **Exclude from analysis:**
257
+ - `skills/` directory — these are skill definitions, not agent system prompts
258
+
259
+ ## Report Format
260
+
261
+ Generate a structured report with the following format:
262
+
263
+ ```markdown
264
+ # Agent Pattern Verification Report
265
+
266
+ **Project:** [project name or path]
267
+ **Date:** [current date]
268
+ **Framework:** [LangGraph | CrewAI | AutoGen | LangChain | Custom | None]
269
+ **Files analyzed:** [count]
270
+
271
+ ## Summary
272
+
273
+ ✅ X checks passed | ⚠️ Y warnings | ❌ Z issues
274
+
275
+ ### By Category
276
+
277
+ | Category | Pass | Warn | Issue |
278
+ |----------|------|------|-------|
279
+ | Loop Safety | X | X | X |
280
+ | Retry Limits | X | X | X |
281
+ | Tool Consistency | X | X | X |
282
+ | Context Size | X | X | X |
283
+ | Graph Cycles | X | X | X |
284
+
285
+ ## Detailed Findings
286
+
287
+ > `[P]` = pattern-matched (structurally reliable) · `[H]` = heuristic (best-effort judgment)
288
+
289
+ ### ✅ Passing
290
+
291
+ - `[P]` All retry decorators have stop conditions
292
+ - `[P]` Tool registry consistent with prompt references
293
+
294
+ ### ⚠️ Warnings
295
+
296
+ - `[P|H]` [Check name]: [Description]
297
+ - **Location:** [file:line]
298
+ - **Category:** [Loop Safety | Retry Limits | Tool Consistency | Context Size]
299
+ - **Suggestion:** [How to address]
300
+
301
+ ### ❌ Issues
302
+
303
+ - `[P|H]` [Check name]: [Description]
304
+ - **Location:** [file:line]
305
+ - **Category:** [Loop Safety | Retry Limits | Tool Consistency | Context Size]
306
+ - **Rule:** [Which rule this violates]
307
+ - **Fix:** [Specific remediation steps]
308
+
309
+ ## Recommendations
310
+
311
+ 1. **[Highest priority]** - [Specific action]
312
+ 2. **[Second priority]** - [Specific action]
313
+ 3. [Additional improvements]
314
+
315
+ ---
316
+
317
+ *Report generated by ControlKeel Agent Pattern Verification v1.0*
318
+ ```
319
+
320
+ ## Integration with CK Tools
321
+
322
+ ### Using `ck_validate`
323
+
324
+ For pattern-matched checks that can be expressed as code patterns, use `ck_validate` with:
325
+ - `artifact_type: "source"`
326
+ - `intended_use: "code"`
327
+ - `domain_pack: "software"` or relevant domain
328
+ - `security_workflow_phase: "analysis"`
329
+
330
+ ### Using `ck_finding`
331
+
332
+ Persist each issue with structured metadata:
333
+ ```elixir
334
+ ck_finding(
335
+ category: "security",
336
+ finding_family: "agent_pattern",
337
+ affected_component: "agent/loop.py:45",
338
+ severity: "warning", # or "issue"
339
+ evidence_type: "code_pattern",
340
+ description: "Potential unbounded loop detected",
341
+ suggested_fix: "Add MAX_ITERATIONS constant or break condition",
342
+ check_type: "pattern" # or "heuristic"
343
+ )
344
+ ```
345
+
346
+ ### Using `ck_context`
347
+
348
+ Call at the start to:
349
+ - Load existing findings to avoid duplicates
350
+ - Understand the risk tier and compliance profile
351
+ - Get workspace context for file discovery
352
+
353
+ ## Additional Resources
354
+
355
+ For detailed check specifications and examples, see [references/pattern-checklist.md](references/pattern-checklist.md).