Skip to content

Commit 5e59e8c

Browse files
committed
feat(cortex): revamp cognitive phases to v2 architecture
Rearchitect cortex agent phases to version 2 with unified cognitive cycle and improved modularity. Removed old phases (categorize, gather, analyze, synthesize, understand, formulate, act) and replaced them with new v2 phases (1.categorize, 2.gather, 3.reason, 5.act) that always run all phases in sequence. Merged analyze and synthesize into a single reason phase. Added new atomic capabilities for action deduplication, evidence and fact management, and memory with composite keys for namespace isolation. Updated cortex main.yaml to reflect new cognitive cycle with depth and iteration tracking, pipeline config overrides, and enhanced permissions and capabilities registry. Added state-management modules for actions, evidence, facts, and memory with SQLite backend supporting deduplication, FTS search, conflict detection, and composite key memory.
1 parent b89c667 commit 5e59e8c

38 files changed

Lines changed: 5087 additions & 3158 deletions
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: cortex-action-complete
2+
description: |
3+
Atomic capability: Mark action as completed with result.
4+
Used by ACT phase after successful execution.
5+
6+
tags: [cortex, capability, atomic, actions, deduplication]
7+
8+
inputs:
9+
state:
10+
type: str
11+
description: Path to SQLite state database.
12+
required: true
13+
14+
action_id:
15+
type: str
16+
description: ID of the action to complete.
17+
required: true
18+
19+
result_json:
20+
type: str
21+
description: Action result as JSON string.
22+
required: false
23+
default: "{}"
24+
25+
blocks:
26+
- id: complete
27+
type: Workflow
28+
inputs:
29+
workflow: agent-state-management
30+
inputs:
31+
state: "{{ inputs.state }}"
32+
op: actions
33+
actions_op: complete
34+
actions_action_id: "{{ inputs.action_id }}"
35+
actions_result_json: "{{ inputs.result_json }}"
36+
caller: "cortex-action-complete"
37+
38+
outputs:
39+
success:
40+
value: "{{ blocks.complete.outputs.actions.success | default(false) }}"
41+
type: bool
42+
description: Whether operation succeeded.
43+
44+
action_id:
45+
value: "{{ inputs.action_id }}"
46+
type: str
47+
description: ID of the completed action.
48+
49+
status:
50+
value: "{{ blocks.complete.outputs.actions.status | default('') }}"
51+
type: str
52+
description: New status of the action (should be "completed").
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
name: cortex-action-dispatch
2+
description: |
3+
Atomic capability: Dispatch action with deduplication.
4+
5+
This is a wrapper that provides transparent action deduplication:
6+
1. Logs the action (creates hash from capability + inputs)
7+
2. If action already completed, returns cached result (skip execution)
8+
3. If new or pending, executes the capability workflow
9+
4. Marks action complete with result
10+
5. Returns result (cached or fresh)
11+
12+
Use this wrapper instead of calling capability workflows directly
13+
to prevent duplicate mutations (idempotency).
14+
15+
The wrapper handles these statuses:
16+
- pending: Execute (new action logged)
17+
- completed: Skip (return cached result)
18+
- failed: Re-execute (retry failed action)
19+
- rolled_back: Re-execute (action was undone)
20+
21+
tags: [cortex, capability, atomic, actions, deduplication, wrapper]
22+
23+
inputs:
24+
state:
25+
type: str
26+
description: Path to SQLite state database.
27+
required: true
28+
29+
cell_id:
30+
type: str
31+
description: Cell ID requesting the action.
32+
required: true
33+
34+
capability:
35+
type: str
36+
description: Capability workflow name to execute.
37+
required: true
38+
39+
inputs:
40+
type: dict
41+
description: Inputs to pass to the capability workflow.
42+
required: true
43+
44+
reason:
45+
type: str
46+
description: Why this action is being executed (for audit).
47+
required: false
48+
default: ""
49+
50+
base_path:
51+
type: str
52+
description: Base path for file operations.
53+
required: false
54+
default: "."
55+
56+
permissions:
57+
type: dict
58+
description: Available permissions.
59+
required: false
60+
default: { "read": true, "write": false, "execute": false }
61+
62+
blocks:
63+
# ===========================================================================
64+
# STEP 1: Log action for deduplication
65+
# ===========================================================================
66+
- id: log_action
67+
type: Workflow
68+
description: Log action and check for duplicates.
69+
inputs:
70+
workflow: cortex-action-log
71+
inputs:
72+
state: "{{ inputs.state }}"
73+
cell_id: "{{ inputs.cell_id }}"
74+
capability: "{{ inputs.capability }}"
75+
inputs_json: "{{ inputs.inputs | tojson }}"
76+
77+
# ===========================================================================
78+
# STEP 2: Check if should execute
79+
# ===========================================================================
80+
- id: check_execute
81+
type: Shell
82+
description: Determine if action should be executed or use cached result.
83+
depends_on: [log_action]
84+
inputs:
85+
command: |
86+
python3 << 'EOF'
87+
import json
88+
import os
89+
90+
already_exists = os.environ.get('ALREADY_EXISTS', 'false').lower() == 'true'
91+
status = os.environ.get('STATUS', 'pending')
92+
cached_result = os.environ.get('CACHED_RESULT', '')
93+
action_id = os.environ.get('ACTION_ID', '')
94+
95+
should_execute = True
96+
result = None
97+
reason = 'new_action'
98+
99+
if already_exists:
100+
if status == 'completed':
101+
# Action already completed - use cached result
102+
should_execute = False
103+
reason = 'cached_completed'
104+
try:
105+
result = json.loads(cached_result) if cached_result else {}
106+
except json.JSONDecodeError:
107+
result = {'raw': cached_result}
108+
elif status == 'failed':
109+
# Previous attempt failed - retry
110+
should_execute = True
111+
reason = 'retry_failed'
112+
elif status == 'pending':
113+
# Action logged but not completed - execute
114+
should_execute = True
115+
reason = 'pending'
116+
elif status == 'rolled_back':
117+
# Action was rolled back - re-execute
118+
should_execute = True
119+
reason = 'retry_rolled_back'
120+
else:
121+
# Unknown status - execute to be safe
122+
should_execute = True
123+
reason = f'unknown_status:{status}'
124+
125+
print(json.dumps({
126+
'should_execute': should_execute,
127+
'reason': reason,
128+
'action_id': action_id,
129+
'cached_result': result,
130+
'already_exists': already_exists,
131+
'status': status
132+
}))
133+
EOF
134+
env:
135+
ALREADY_EXISTS: "{{ blocks.log_action.outputs.already_exists | default(false) }}"
136+
STATUS: "{{ blocks.log_action.outputs.status | default('pending') }}"
137+
CACHED_RESULT: "{{ blocks.log_action.outputs.cached_result | default({}) | tojson }}"
138+
ACTION_ID: "{{ blocks.log_action.outputs.action_id | default('') }}"
139+
140+
# ===========================================================================
141+
# STEP 3: Execute capability (if not cached)
142+
# ===========================================================================
143+
- id: execute_capability
144+
type: Workflow
145+
description: Execute the actual capability workflow.
146+
depends_on: [check_execute]
147+
condition: "{{ (blocks.check_execute.outputs.stdout | fromjson).should_execute }}"
148+
continue_on_error: true
149+
inputs:
150+
workflow: "{{ inputs.capability }}"
151+
inputs: "{{ {'state': inputs.state, 'base_path': inputs.base_path, 'permissions': inputs.permissions} | combine(inputs.inputs) }}"
152+
153+
# ===========================================================================
154+
# STEP 4: Mark action complete (on success)
155+
# ===========================================================================
156+
- id: complete_action
157+
type: Workflow
158+
description: Mark action as completed with result.
159+
depends_on: [execute_capability]
160+
condition: "{{ blocks.execute_capability.succeeded }}"
161+
inputs:
162+
workflow: cortex-action-complete
163+
inputs:
164+
state: "{{ inputs.state }}"
165+
action_id: "{{ (blocks.check_execute.outputs.stdout | fromjson).action_id }}"
166+
result_json: "{{ blocks.execute_capability.outputs | tojson }}"
167+
168+
# ===========================================================================
169+
# STEP 5: Mark action failed (on failure)
170+
# ===========================================================================
171+
- id: fail_action
172+
type: Workflow
173+
description: Mark action as failed.
174+
depends_on: [execute_capability]
175+
condition: "{{ blocks.execute_capability.failed and (blocks.check_execute.outputs.stdout | fromjson).should_execute }}"
176+
inputs:
177+
workflow: agent-state-management
178+
inputs:
179+
state: "{{ inputs.state }}"
180+
op: actions
181+
actions_op: fail
182+
actions_action_id: "{{ (blocks.check_execute.outputs.stdout | fromjson).action_id }}"
183+
actions_result_json: "{{ {'error': blocks.execute_capability.metadata.error_message | default('Unknown error')} | tojson }}"
184+
caller: "cortex-action-dispatch"
185+
186+
outputs:
187+
success:
188+
value: |
189+
{{ blocks.execute_capability.succeeded
190+
or (not (blocks.check_execute.outputs.stdout | fromjson).should_execute) }}
191+
type: bool
192+
description: Whether action succeeded (executed or cached).
193+
194+
executed:
195+
value: "{{ (blocks.check_execute.outputs.stdout | fromjson).should_execute }}"
196+
type: bool
197+
description: Whether action was actually executed (vs cached).
198+
199+
cached:
200+
value: "{{ not (blocks.check_execute.outputs.stdout | fromjson).should_execute }}"
201+
type: bool
202+
description: Whether cached result was used.
203+
204+
action_id:
205+
value: "{{ (blocks.check_execute.outputs.stdout | fromjson).action_id }}"
206+
type: str
207+
description: ID of the logged action.
208+
209+
reason:
210+
value: "{{ (blocks.check_execute.outputs.stdout | fromjson).reason }}"
211+
type: str
212+
description: Why execution decision was made.
213+
214+
result:
215+
value: |
216+
{{ blocks.execute_capability.outputs if blocks.execute_capability.succeeded
217+
else ((blocks.check_execute.outputs.stdout | fromjson).cached_result | default({})) }}
218+
type: dict
219+
description: Action result (fresh or cached).
220+
221+
error:
222+
value: "{{ blocks.execute_capability.metadata.error_message | default('') if blocks.execute_capability.failed else '' }}"
223+
type: str
224+
description: Error message if action failed.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: cortex-action-log
2+
description: |
3+
Atomic capability: Log action for deduplication before execution.
4+
Used by ACT phase to prevent duplicate mutations.
5+
6+
Deduplication uses SHA256 hash of (capability, inputs) to identify
7+
duplicate requests. If an identical action exists, returns cached result.
8+
9+
Action statuses:
10+
- pending: Logged but not yet executed
11+
- completed: Successfully executed
12+
- failed: Execution failed
13+
- rolled_back: Action was reversed
14+
15+
tags: [cortex, capability, atomic, actions, deduplication]
16+
17+
inputs:
18+
state:
19+
type: str
20+
description: Path to SQLite state database.
21+
required: true
22+
23+
cell_id:
24+
type: str
25+
description: Cell ID requesting the action.
26+
required: true
27+
28+
capability:
29+
type: str
30+
description: Capability workflow name (e.g., "action-write", "action-edit").
31+
required: true
32+
33+
inputs_json:
34+
type: str
35+
description: Action inputs as JSON string (used for deduplication hash).
36+
required: true
37+
38+
blocks:
39+
- id: log
40+
type: Workflow
41+
inputs:
42+
workflow: agent-state-management
43+
inputs:
44+
state: "{{ inputs.state }}"
45+
op: actions
46+
actions_op: log
47+
actions_cell_id: "{{ inputs.cell_id }}"
48+
actions_capability: "{{ inputs.capability }}"
49+
actions_inputs_json: "{{ inputs.inputs_json }}"
50+
caller: "cortex-action-log"
51+
52+
outputs:
53+
success:
54+
value: "{{ blocks.log.outputs.actions.success | default(false) }}"
55+
type: bool
56+
description: Whether operation succeeded.
57+
58+
action_id:
59+
value: "{{ blocks.log.outputs.actions.action_id | default('') }}"
60+
type: str
61+
description: ID of the logged action.
62+
63+
already_exists:
64+
value: "{{ blocks.log.outputs.actions.already_exists | default(false) }}"
65+
type: bool
66+
description: Whether action already existed (duplicate detected).
67+
68+
status:
69+
value: "{{ blocks.log.outputs.actions.status | default('') }}"
70+
type: str
71+
description: Current status of the action.
72+
73+
cached_result:
74+
value: "{{ blocks.log.outputs.actions.result.result | default(none) }}"
75+
type: dict
76+
description: Cached result if action was already completed.

0 commit comments

Comments
 (0)