# Jiva: Context & Persona Alignment Plan (3‑Agent System)

**Date**: 2026-02-28 (revised)  
**Repo**: KarmaloopAI/Jiva  
**Scope**: DualAgent (Manager + Worker + Client), Personas (Claude Plugins), Directive + Conversation Context

---

## Goals

Two major improvements:

1. **All three agents are context-aware and consistent**
   - Every agent (Manager, Worker, Client) must operate with the same contextual inputs: directive file contents and conversation history (same bounded representation for all three).
   - Reduces incoherence such as "good action then bad action" due to missing/unequal context.

2. **Client Agent becomes persona-aware for validation**
   - Client should understand the active persona's intent/skills to validate tool usage and outcomes.
   - Client should be able to validate persona-specific requirements (expected tools, required steps, constraints).

### Non-goals

- Redesigning the entire orchestration loop.
- Changing persona routing logic beyond making the Client persona-aware.
- Replacing the existing validation architecture.

---

## Current State (What's happening today)

### Context propagation

- **Directive**
  - Manager includes directive in its system prompt (`workspace.getDirectivePrompt()`), but **only at construction time** — not refreshed per turn.
  - Worker does *not* include directive in its prompt at all.
  - Client cannot read directive (no `workspace` access).

- **Conversation history**
  - `DualAgent` maintains `userConversationHistory` but only passes a **recent user-only context string** (last 3 user messages, role `user` only) to Manager/Worker via `context`.
  - Worker uses a fresh `conversationHistory` per subtask execution, scoped only to that subtask.
  - Client validates using `userMessage`, `subtasks`, and `workerResult`, **without broader conversation context**.

### Persona propagation

- **Manager / Worker**: Persona prompt block + `<available_skills>` metadata included in system prompts via `PersonaManager.getSystemPromptAddition()` when provided.
- **Client**: No persona integration at prompt or intent level. Client *can* see tools via MCP discovery, but is **not persona-aware at prompt/validation level**.

---

## Known Bugs Confirmed by Code Review

1. **`getRecentContext()` filters to `user` role only** — the assistant's prior outputs (commitments, reasoning, decisions) are invisible to Manager/Worker.
2. **Manager directive is stale after construction** — `initializeSystemPrompt()` bakes in the directive at startup; file changes during a session are not seen.
3. **Worker receives no directive** — Worker's `executeSubtask` builds its system prompt with persona but no `workspace.getDirectivePrompt()` call.
4. **Client has no context** — `new ClientAgent(this.orchestrator, this.mcpManager)` receives no workspace, no persona, no history.
5. **`failureCount` escalation is blunt** — a single validation failure permanently escalates every subsequent subtask to `THOROUGH`, which can compound with a persona-strict Client to produce runaway correction loops.

---

## Improvement #1: Make all three agents context-aware (directive + conversation history)

### High-level approach

Create a **shared `AgentContext` payload** generated by `DualAgent` and passed consistently to Manager plan creation, Worker execution, and Client validation & correction generation.

`AgentContext` must include:
- Directive content (freshly loaded per turn)
- Consistent conversation history (same bounded representation for all three agents): either full recent messages or condensed summary + last N messages
- Persona context (split into execution context for Manager/Worker, and validation context for Client — see Improvement #2)

### Design principles

1. **Single source of truth**: `DualAgent` owns and produces the context.
2. **Bounded tokens**: context must be trimmed/condensed deterministically.
3. **Fresh directive**: directive must be refreshed per turn to reflect file changes.
4. **Same context for all agents**: Manager, Worker, Client should not disagree due to different inputs.
5. **Role-appropriate persona payload**: Manager/Worker receive the full execution persona block; Client receives a validation-specific subset.
6. **Tool role messages included**: shared conversation context should include `tool` role messages (tool results), not just `user` and `assistant`, so that the Worker does not repeat tool calls it already made and the Client can verify claims against real tool output.

### Proposed new types

```ts
export interface AgentContext {
  workspaceDir: string;
  directive?: string;                // raw directive prompt block (freshly loaded each turn)
  conversation: {
    summary?: string;                // optional condensed summary (from ConversationManager)
    recentMessages: Message[];       // bounded list of recent messages (user + assistant + tool roles)
  };
  persona?: {
    name?: string;
    systemPromptAddition?: string;   // For Manager/Worker: full persona block + <available_skills>
    validationContext?: string;      // For Client: skills metadata + constraints only (no execution directives)
  };
}
```

**Notes**:
- `recentMessages` MUST include `user`, `assistant`, **and `tool`** roles because:
  - Coherence failures arise when the model can't see its own prior commitments.
  - Duplicate tool call failures arise when Worker can't see prior tool results.
  - Client's coherence check is more accurate when it sees actual tool output.
- `summary` is optional and used when history is long.
- `persona.systemPromptAddition` and `persona.validationContext` serve **different purposes** and must not be conflated.

### Conversation history strategy

**Option A (recommended)**: Summary + last N message pairs
- If total messages exceed threshold: use `ConversationManager.condenseConversation()` (already implemented) to produce a summary message + last N messages (user + assistant + tool).
- Persist updated `userConversationHistory` in `DualAgent`.
- When `ConversationManager` is `null`, fall back to Option B.

**Option B**: Keep only last N messages (fallback when ConversationManager unavailable)
- Keep last N messages of all roles (user + assistant + tool).
- Fallback only — risks losing long-range constraints.
- `buildAgentContext()` must explicitly handle this case.

**Recommendation**: Option A as primary; Option B as explicit graceful fallback. `buildAgentContext()` must document which path was taken.

### Directive strategy

- Load directive via `workspace.getDirectivePrompt()` **each turn** in `DualAgent.buildAgentContext()`.
- Embed into Manager, Worker, and Client prompts.
- **Manager-specific note**: Manager currently bakes the directive into its system prompt at construction time. This must be refactored: Manager should store its base system prompt content **without** the directive and inject a fresh directive into each LLM call, following the pattern already established in `JivaAgent.getSystemMessages()`. This is a non-trivial change and must be called out as an explicit implementation task.

### Implementation tasks

1. **Add `AgentContext` type** (new file `src/core/types/agent-context.ts`). Export from `src/index.ts`.

2. **Add `serializeAgentContext()` utility** (new file `src/core/utils/serialize-agent-context.ts`):
   ```ts
   serializeAgentContext(ctx: AgentContext, role: 'manager' | 'worker' | 'client'): string
   ```
   This produces a consistent, role-appropriate string block that each agent embeds in its prompt. Using the same serializer for all three agents ensures the format is identical. **Must be implemented before wiring up individual agents.**

3. **DualAgent constructs shared context each `chat()` turn**:
   - Add `buildAgentContext(): AgentContext` method.
   - Reads directive fresh via `workspace.getDirectivePrompt()`.
   - Selects/condenses history: Option A if `ConversationManager` available, Option B otherwise.
   - Includes `user` + `assistant` + `tool` role messages in `recentMessages`.
   - Populates `persona.systemPromptAddition` and `persona.validationContext` separately.

4. **Manager uses shared context with per-call directive injection**:
   - Refactor `ManagerAgent.initializeSystemPrompt()` to store base prompt **without** directive.
   - Introduce `ManagerAgent.getSystemMessages(ctx: AgentContext): Message[]` (analogous to `JivaAgent.getSystemMessages()`).
   - Update `createPlan()` and `synthesizeResponse()` to use `getSystemMessages(ctx)`.
   - Update `DualAgent.chat()` to pass `agentContext` into `manager.createPlan()`.

5. **Worker uses shared context + directive**:
   - Update `WorkerAgent.executeSubtask()` to accept optional `context: AgentContext`.
   - Include `ctx.directive` (currently missing) and `serializeAgentContext(ctx, 'worker')` in system prompt.
   - `tool` role messages from `ctx.conversation.recentMessages` give Worker visibility into prior tool results, reducing redundant tool calls.
   - Update `DualAgent.chat()` to pass `agentContext` into `worker.executeSubtask()`.

6. **Client uses shared context + directive**:
   - Update `ClientAgent.validate()` to accept `ctx: AgentContext`.
   - Include `serializeAgentContext(ctx, 'client')` in all internal LLM prompts: `analyzeTaskRequirements`, `analyzeForUnjustifiedFailure`, `analyzeResultCoherence`, `generateCorrectionInstruction`.
   - Update `DualAgent.chat()` to pass `agentContext` into `client.validate()`.

7. **Single context object per turn**: The same `agentContext` produced by `buildAgentContext()` must be passed to all three agents in that turn. No agent should build its own context independently.

---

## Improvement #2: Make Client persona-aware (for validation/testing)

### High-level approach

Provide a **validation-specific persona context** to the Client. This is deliberately different from the execution persona block given to Manager/Worker:
- The execution block tells the agent *how to behave* (active voice, procedural).
- The validation context tells the Client *what correct behavior looks like* (descriptive, criteria-oriented).

Conflating these would risk the Client trying to direct execution rather than evaluate outcomes.

### What `persona.validationContext` contains

A string block constructed by `DualAgent.buildAgentContext()` containing:
- Persona name and description.
- `<available_skills>` L1 metadata: skill names, descriptions, and any constraints (mandatory steps, allowed tools, safety rules).
- **Not** the full execution persona prompt block.

Example structure:
```
ACTIVE PERSONA: [name] — [description]

SKILLS AVAILABLE TO WORKER:
- [skill name]: [description]
  Constraints: [any mandatory steps, required tools, or safety rules from SKILL.md]

VALIDATION GUIDANCE:
- Worker is expected to use skills above when relevant to the user's request.
- Validate that Worker's tool usage is consistent with the skills it was expected to apply.
- Validate that any mandatory steps or safety constraints defined above were followed.
```

### Implementation tasks

1. **Add `buildValidationContext()` helper** to `DualAgent` (or `PersonaManager`). Takes the active persona and produces the `validationContext` string. Returns `undefined` if no persona is active.

2. **Include `validationContext` in Client's LLM prompts**: `serializeAgentContext(ctx, 'client')` must include the `validationContext` block when present. Update all Client LLM prompt builders to embed this block.

3. **Enable Client to load SKILL.md for deep validation (optional, Phase 2)**: Give Client a reference to `PersonaManager`. Add `client.loadSkillForValidation(skillName: string): Promise<string>`. When a Worker cites a specific skill, Client can load and reference the SKILL.md L2 content.

---

## Improvement #3: Replace blunt `failureCount` escalation with Completion Confidence scoring

### Problem

The current `failureCount` mechanism is binary and permanent within a session:
- One validation failure → all subsequent subtasks escalate to `THOROUGH` forever.
- When combined with persona-strict Client (from Improvement #2), this can produce runaway correction loops: strict persona makes Client harder to satisfy, `failureCount` accumulates, THOROUGH escalation makes Client even stricter, corrections pile up.

### Proposed replacement: `CompletionSignal`

Replace `failureCount` + hard `THOROUGH` escalation with a **`CompletionSignal`** model — a richer, per-subtask assessment that the Client emits alongside its `ValidationResult`. `DualAgent` uses this signal to decide corrective strategy rather than blindly escalating involvement level.

**New type**:
```ts
export interface CompletionSignal {
  confidence: 'high' | 'medium' | 'low' | 'none';
  progressMade: boolean;           // did Worker make any measurable forward progress?
  blockerType?: 'tool_failure'     // Worker tried but tool errored
               | 'hallucination'   // Worker claimed work it didn't do
               | 'scope_drift'     // Worker did something unrelated
               | 'partial'         // Worker made progress but didn't finish
               | 'loop'            // Worker is repeating the same action
               | 'capability_gap'; // Task requires tools/capabilities not available
  suggestedStrategy?: 'retry'      // retry same subtask
                    | 'rephrase'   // retry with clearer instruction
                    | 'decompose'  // break subtask into smaller steps
                    | 'skip'       // skip this subtask, continue plan
                    | 'escalate';  // flag to user, cannot auto-correct
}
```

### How it works

1. Client emits a `CompletionSignal` alongside `ValidationResult` from `validate()`.
2. `DualAgent` uses `CompletionSignal` to choose a **corrective strategy** per subtask failure, instead of simply escalating involvement level.
3. Involvement level (`MINIMAL` / `STANDARD` / `THOROUGH`) becomes a **task-type signal** only — it answers "how deeply should we validate this type of task?", not "how many times have we failed?".

### Corrective strategies in `DualAgent`

| `blockerType` | `suggestedStrategy` | `DualAgent` action |
|---|---|---|
| `hallucination` | `retry` | Re-queue subtask with explicit instruction to use specific tools |
| `tool_failure` | `retry` or `rephrase` | Re-queue with error context; limit retries to 2 |
| `partial` | `decompose` | Ask Manager to break subtask into smaller steps |
| `scope_drift` | `rephrase` | Re-queue with tighter scope instruction |
| `loop` | `skip` or `escalate` | Skip after 2 loop detections; flag to user |
| `capability_gap` | `escalate` | Flag immediately; don't retry |

### Retry budget

- Each subtask gets a `maxRetries` (default: 2) correction attempts.
- When budget is exhausted: if `progressMade: true` → continue to synthesis; if `progressMade: false` → emit user-visible warning and skip.
- The retry budget resets for each new subtask.
- Global session health can still be tracked (for telemetry), but must **not** trigger involvement escalation.

### Interaction with persona-aware validation

- A strict persona may produce more `low` or `none` confidence signals, but each subtask is managed independently.
- `DualAgent` applies the corrective strategy for that specific subtask, not a session-wide escalation.
- If a persona constraint is the blocker (e.g., Worker used a disallowed tool), `blockerType: 'scope_drift'` and `suggestedStrategy: 'rephrase'` guides correction without escalating other subtasks.

### Implementation tasks

- [ ] Define `CompletionSignal` interface in `src/core/types/completion-signal.ts`.
- [ ] Add `completionSignal: CompletionSignal` to `ValidationResult`.
- [ ] Add `analyzeCompletionSignal()` private method to `ClientAgent`: LLM-based assessment of `confidence`, `progressMade`, `blockerType`, `suggestedStrategy`. Called at end of `validate()`. Receives full `AgentContext` + `workerResult` + current `ValidationResult.issues`.
- [ ] Remove `failureCount` escalation logic from `analyzeTaskRequirements()` in `ClientAgent`.
- [ ] Demote `this.failureCount` to telemetry-only (or remove).
- [ ] Update `DualAgent.chat()` subtask loop: read `validation.completionSignal` to determine corrective strategy; track per-subtask retry budget; implement strategy dispatch.
- [ ] Handle `progressMade: true` vs `false` at budget exhaustion.
- [ ] Implement `escalate` strategy (user-visible warning, skip subtask).
- [ ] Rename `resetFailureTracking()` → `resetSessionState()` for clarity.
- [ ] Regression guard: preserve `THOROUGH` involvement from `analyzeTaskRequirements()` for explicit user test requests (this path must not be removed).

---

## Improvement #4: Sub-agent context inheritance (known scope boundary)

### Decision

Sub-agent context inheritance is **explicitly out of scope for Phase 1**.

When `AgentSpawner` spawns a sub-agent, it creates a fresh `DualAgent` with its own empty `userConversationHistory`, no access to the parent session's `AgentContext`. This is acceptable because sub-agents are designed to operate autonomously with a clearly scoped task.

### What Manager must do (Phase 1 guard)

When Manager decides to spawn a sub-agent (via `spawn_agent` tool), it should include in `request.context`:
- A brief context summary from `AgentContext.conversation.summary` (if available).
- Relevant directive constraints that apply to the sub-agent's task.
- The active persona name (for task framing).

This is a **prompt-level convention**, not a type-level enforcement.

### Phase 2 consideration

`AgentSpawner.spawnAgent()` could optionally accept `parentContext?: Partial<AgentContext>` to seed the sub-agent's initial context. Noted here but not specified for Phase 1.

---

## `serializeAgentContext()` utility — detailed spec

**Signature**: `serializeAgentContext(ctx: AgentContext, role: 'manager' | 'worker' | 'client'): string`

### Behavior by role

- **`manager`**: Include directive + conversation summary/recent messages. Omit `validationContext`. Persona block handled separately in system prompt.
- **`worker`**: Include directive + conversation summary/recent messages (user + assistant + **tool** role messages). Omit `validationContext`. Persona block handled separately in system prompt.
- **`client`**: Include directive + conversation summary/recent messages (user + assistant + **tool** role messages). Include `validationContext` block. Omit execution persona block.

### Token budget considerations (tunable)

| Block | Limit |
|---|---|
| Directive | 500 tokens max (truncate with notice if exceeded) |
| Conversation summary | 300 tokens max |
| Recent messages | Last 6 messages of all roles, bounded to ~800 tokens |
| Validation context | 400 tokens max |

When `ConversationManager` is null, summary is omitted; recent messages fall back to Option B.

---

## Suggested API Changes (minimal, incremental)

### Phase 1 (minimal disruption)

- Introduce `AgentContext` type (`src/core/types/agent-context.ts`).
- Introduce `CompletionSignal` type (`src/core/types/completion-signal.ts`).
- Introduce `serializeAgentContext()` utility (`src/core/utils/serialize-agent-context.ts`).
- Add `DualAgent.buildAgentContext()`.
- Refactor `ManagerAgent` to inject directive per-call (not at construction).
- Add directive + conversation context into Worker and Client prompts.
- Add persona validation context into Client prompts.
- Add `CompletionSignal` to `ValidationResult`; replace `failureCount` escalation with per-subtask retry budget + strategy dispatch in `DualAgent`.

No major refactors required. All changes are additive or localized replacements.

### Phase 2 (stronger validation)

- Give Client access to `PersonaManager` (and optionally `WorkspaceManager`).
- Add optional skill loading in Client for deeper persona-aware validation.
- Consider `parentContext?: Partial<AgentContext>` parameter in `AgentSpawner.spawnAgent()`.

---

## Testing Plan

### Functional tests

1. **Directive coherence**: Put a directive that forbids a class of actions (e.g., "never modify files outside workspace"). Ensure Manager, Worker, and Client all comply and validate accordingly. Verify directive refreshes: modify the directive file mid-session; confirm next turn uses the new content.

2. **Conversation coherence (assistant history)**: Create a multi-turn session where the assistant commits to a plan, then a later subtask could contradict it. Ensure Worker/Client see earlier **assistant** messages (not just user messages) and reject contradictions.

3. **Tool result visibility**: Worker executes a tool in subtask N; Worker should not repeat the identical tool call in subtask N+1. Confirm `tool` role messages in `recentMessages` prevent this.

4. **Persona validation**: Activate persona with skills that mandate a particular approach/tooling. Confirm Client `validationContext` reflects persona constraints. Confirm Client validation is consistent with persona guidance.

5. **Persona MCP tools**: Activate a persona that adds MCP servers. Ensure Client sees those tools and can reference them in validation logic.

6. **CompletionSignal strategy dispatch**: Trigger each `blockerType` and confirm `DualAgent` takes the expected corrective strategy. Confirm loop detection leads to `skip` after 2 occurrences. Confirm `capability_gap` leads to `escalate`, not retry.

7. **Retry budget**: Verify per-subtask retry budget resets between subtasks. Verify budget exhaustion with `progressMade: true` leads to continuation. Verify budget exhaustion with `progressMade: false` leads to skip + warning.

8. **Persona + CompletionSignal non-compounding**: Activate a strict persona; trigger a validation failure on subtask 1. Confirm subtask 2 is NOT automatically elevated to `THOROUGH` due to subtask 1 failure.

### Regression tests

- Token usage remains bounded (condensing + trimming still works).
- Sub-agent spawning still works (AgentSpawner ephemeral persona remains correct).
- `THOROUGH` involvement level for explicit user testing requests is preserved (path from `analyzeTaskRequirements`, not `failureCount`).
- `failureCount: 0` baseline behavior (no regressions for sessions with zero failures).

---

## Rollout / Backward Compatibility

- Default behavior remains the same for users without directives/personas.
- Context additions should be additive, not breaking:
  - If no directive exists, `context.directive` is empty/undefined; serializer omits the block.
  - If no persona active, persona additions are empty; serializer omits the block.
  - If `ConversationManager` is null, summary is omitted; Option B fallback is used.
- Keep thresholds configurable to avoid huge prompts.
- `CompletionSignal` is additive to `ValidationResult`; existing consumers that only read `approved` / `issues` / `nextAction` are unaffected.

---

## Risks & Mitigations

| Risk | Mitigation |
|---|---|
| Token bloat / WAF issues | Bounded serialization in `serializeAgentContext()`; consistent trimming + condensing; configurable thresholds. |
| Different prompt formats between agents | Single `serializeAgentContext()` utility; role parameter governs what is included, not the format. |
| Client becomes too strict due to persona + failure compounding | `CompletionSignal` replaces blunt `failureCount` escalation; per-subtask retry budgets prevent session-wide escalation; persona context is validation-framed only. |
| Manager directive staleness after construction | Explicit refactor of `ManagerAgent` to use per-call directive injection (analogous to `JivaAgent.getSystemMessages()`). |
| Sub-agent context isolation gap | Explicitly documented as out of scope for Phase 1; Manager instructed (via prompt convention) to include relevant context in `spawn_agent` requests. |
| `ConversationManager` being null | `buildAgentContext()` explicitly handles both paths; documented behavior, not a crash condition. |

---

## Implementation Checklist (Summary)

### Pre-requisites (do first, before wiring any agent)

- [ ] Define `AgentContext` interface (`src/core/types/agent-context.ts`)
- [ ] Define `CompletionSignal` interface (`src/core/types/completion-signal.ts`)
- [ ] Implement `serializeAgentContext()` utility (`src/core/utils/serialize-agent-context.ts`) — **must be done before wiring any agent**

### Improvement #1 (Context alignment)

- [ ] `DualAgent`: Add `buildAgentContext()` method
  - [ ] Reads directive fresh each turn
  - [ ] Handles Option A (condense) and Option B (trim) based on `ConversationManager` availability
  - [ ] Includes `user` + `assistant` + `tool` role messages in `recentMessages`
  - [ ] Populates `persona.systemPromptAddition` and `persona.validationContext` separately
- [ ] `ManagerAgent`: Refactor to inject directive per-call (not at construction), following `JivaAgent.getSystemMessages()` pattern
- [ ] `ManagerAgent`: Accept `AgentContext` in `createPlan()` and `synthesizeResponse()`
- [ ] `WorkerAgent`: Include directive + shared conversation context (with `tool` role messages) in prompts
- [ ] `WorkerAgent`: Accept `AgentContext` in `executeSubtask()`
- [ ] `ClientAgent`: Include directive + shared conversation context + `validationContext` in all LLM prompts
- [ ] `ClientAgent`: Accept `AgentContext` in `validate()`
- [ ] `DualAgent.chat()`: Build `agentContext` once per turn; pass same instance to all three agents

### Improvement #2 (Client persona awareness)

- [ ] Add `buildValidationContext()` helper to `DualAgent` (or `PersonaManager`)
- [ ] Include `validationContext` in `AgentContext.persona.validationContext`
- [ ] `serializeAgentContext()` for `'client'` role includes `validationContext`
- [ ] (Optional, Phase 2) Give Client reference to `PersonaManager` for SKILL.md deep validation

### Improvement #3 (CompletionSignal — replaces `failureCount` escalation)

- [ ] Define `CompletionSignal` interface
- [ ] Add `completionSignal` field to `ValidationResult`
- [ ] Add `analyzeCompletionSignal()` method to `ClientAgent` (LLM-based)
- [ ] Remove `failureCount` escalation logic from `analyzeTaskRequirements()` in `ClientAgent`
- [ ] Demote `this.failureCount` to telemetry-only (or remove)
- [ ] `DualAgent.chat()`: Implement per-subtask retry budget (default: 2 retries per subtask)
- [ ] `DualAgent.chat()`: Implement corrective strategy dispatch based on `CompletionSignal.blockerType`
- [ ] `DualAgent.chat()`: Handle `progressMade: true` vs `false` at budget exhaustion
- [ ] `DualAgent.chat()`: Implement `escalate` strategy (user-visible warning, skip subtask)
- [ ] Rename `resetFailureTracking()` → `resetSessionState()` for clarity
- [ ] Preserve `THOROUGH` involvement from `analyzeTaskRequirements()` for explicit user test requests (regression guard)

### Improvement #4 (Sub-agent context — Phase 1 boundary)

- [ ] Document in `AgentSpawner` and `spawn_agent` prompt guidance that Manager should include relevant directive/context summary in `request.context`
- [ ] (Phase 2 only) Add optional `parentContext?: Partial<AgentContext>` to `AgentSpawner.spawnAgent()`

---

## References (current code)

| Reference | Location |
|---|---|
| DualAgent constructs Manager/Worker/Client | `src/core/dual-agent.ts` |
| `getRecentContext()` (user-only, 3 messages) | `src/core/dual-agent.ts#L299-L308` |
| Directive loading | `src/core/workspace.ts` |
| Manager includes directive + persona at construction | `src/core/manager-agent.ts#L59-L100` |
| Worker includes persona but not directive | `src/core/worker-agent.ts#L95-L193` |
| Client has no persona/context integration | `src/core/client-agent.ts` |
| `failureCount` escalation | `src/core/client-agent.ts#L206-L213`, `#L234-L236` |
| `generateCorrectionInstruction()` | `src/core/client-agent.ts#L636-L679` |
| `JivaAgent.getSystemMessages()` (per-call directive pattern to follow) | `src/core/agent.ts#L116-L141` |
| `ConversationManager.condenseConversation()` | `src/core/conversation-manager.ts#L164-L265` |
| PersonaManager prompt addition & MCP servers | `src/personas/persona-manager.ts` |
| AgentSpawner sub-agent construction | `src/core/agent-spawner.ts#L182-L227` |
| CLI merges persona MCP servers | `src/interfaces/cli/index.ts` |
| Persona design notes | `docs/architecture/PERSONAS_IMPLEMENTATION.md` |
