Architecture

Session State & Persistence

Understanding what persists across sessions and compaction

Session State & Persistence

Category: Architecture | Updated: 2026-02-02

Understanding what persists across sessions, compaction, and what's ephemeral in Triqual.


Overview

Triqual maintains state at three levels:

  1. Persistent (survives sessions and compaction) - File-based
  2. Session-only (survives compaction) - Cache directory
  3. Ephemeral (lost on compaction) - Claude's context memory

What Persists

Persistent State (File-Based)

LocationContentSurvivesPurpose
.triqual/runs/*.mdRun logs (per feature)Sessions, compactionTrack test generation workflow
.triqual/knowledge.mdProject patternsSessions, compactionAccumulated learnings
.triqual/context/{feature}/Context filesSessions, compactionQuoth/Exolar research results
triqual.config.tsConfigurationSessions, compactionProject settings

Why persistent?

  • Stored as files in project directory
  • Committed to git
  • Survives Claude Code restarts
  • Survives context compaction
  • Shared across team members

Session State (Cache Directory)

LocationContentSurvivesPurpose
~/.cache/triqual/session-state.jsonSession metadataCurrent session onlyHints, tool counts, test runs
~/.cache/triqual/.lockLock fileActive operations onlyPrevent race conditions

Why session-only?

  • User-specific (not shared)
  • Reset on new session
  • Tracks one-time hints (don't repeat)

Ephemeral State (Context Memory)

Lost on compaction:

  • Conversation history
  • Agent intermediate results
  • Error messages (unless logged)
  • User questions/answers

Preserved via files:

  • Run logs capture all stages
  • Knowledge.md captures learnings
  • Context files capture research

Run Log Persistence

Structure

Each feature has a persistent run log:

.triqual/runs/
├── login.md              # Login feature workflow
├── dashboard.md          # Dashboard feature workflow
└── checkout.md           # Checkout feature workflow

Content Survives

# Test Run Log: login

## Session: 2026-01-27T10:30:00Z
### Stage: ANALYZE
[Requirements, test cases]

### Stage: RESEARCH
[Quoth patterns, Exolar history]

### Stage: PLAN
[Test strategy]

### Stage: WRITE
**Hypothesis:** [Approach]

### Stage: RUN (Attempt 1)
**Result:** FAILED
**Category:** WAIT

### Stage: FIX (Attempt 1)
**Hypothesis:** [Fix approach]

### Stage: RUN (Attempt 2)
**Result:** PASSED

### Stage: LEARN
**Pattern:** [Extracted pattern]

## Accumulated Learnings
1. Login buttons use data-testid="login-submit"
2. Dashboard requires networkidle wait

Multi-Session Workflow

Session 1:

## Session: 2026-01-27T10:30:00Z
### Stage: ANALYZE
...
### Stage: RESEARCH
...
### Stage: PLAN
...
(Session ends - context compacted)

Session 2 (resumes):

## Session: 2026-01-27T14:00:00Z
### Stage: WRITE
(Reads PLAN from above, continues)

Result: Workflow continues seamlessly across sessions.


Knowledge Persistence

Structure

Project-wide patterns file:

.triqual/knowledge.md

Content Accumulates

# Project Knowledge: my-app

## Patterns

### Pattern 1: Auth Redirects Require networkidle Wait

**Context:** Dashboard loads async after login

**Code:**
```typescript
await loginPage.login(email, password);
await page.waitForLoadState('networkidle'); // Critical!

Why: URL change happens before content loads

Added: 2026-01-27 (Session A)


Pattern 2: Error Messages Use toast-error Class

Context: Error notifications appear as toasts

Code:

await expect(page.locator('.toast-error')).toBeVisible();

Why: Consistent error handling pattern

Added: 2026-01-30 (Session B)


### Multi-Session Growth

| Session | Patterns Added | Total Patterns |
|---------|----------------|----------------|
| Session 1 | 2 | 2 |
| Session 2 | 1 | 3 |
| Session 3 | 3 | 6 |
| Session 10 | 1 | 15 |

**Result:** Knowledge grows over time, survives all sessions.

---

## Context File Persistence

### Structure

Per-feature context directories:

.triqual/context/ ├── login/ │ ├── patterns.md │ ├── anti-patterns.md │ ├── codebase.md │ ├── existing-tests.md │ ├── failures.md │ ├── requirements.md │ └── summary.md └── dashboard/ └── (same structure)


### Content Source

Generated by `triqual_load_context` MCP tool:
- Searches Quoth for patterns
- Queries Exolar for failures
- Scans codebase for existing code

### Reuse Across Sessions

**Session 1:**
```bash
/test login
└─► triqual_load_context({ feature: "login" })
    └─► Writes .triqual/context/login/

Session 2 (weeks later):

/test login-variations
└─► triqual_load_context({ feature: "login", force: false })
    └─► REUSES .triqual/context/login/ (no regeneration)

Session 3 (force reload):

/test login-variations
└─► triqual_load_context({ feature: "login", force: true })
    └─► REGENERATES .triqual/context/login/ (fresh research)

Session State (Ephemeral)

Location

~/.cache/triqual/session-state.json

Content

{
  "session_id": "uuid-123",
  "started_at": "2026-01-27T10:30:00Z",

  "hints_shown": {
    "getting_started": true,
    "draft_folder": false,
    "quoth_search": false
  },

  "tool_counts": {
    "Write": 5,
    "Edit": 3,
    "Bash": 12,
    "Read": 20
  },

  "test_runs": {
    "login": {
      "attempts": 3,
      "last_result": "PASS",
      "last_category": "WAIT",
      "fixed": true
    },
    "dashboard": {
      "attempts": 1,
      "last_result": "FAIL",
      "last_category": "TEST_ISSUE",
      "fixed": false
    }
  },

  "awaiting_log_update": false
}

Why Ephemeral?

  • Hints once per session - Don't repeat "Getting Started" every time
  • Tool usage stats - Session summary at end
  • Test run tracking - Retry limit enforcement
  • User-specific - Not shared across team

Reset on New Session

# Start new session
claude

# Session state created fresh
~/.cache/triqual/session-state.json (new)

Effect:

  • Hints can be shown again
  • Tool counts reset to 0
  • Test run tracking starts fresh

Compaction Survival

PreCompact Hook

Event: Before context compaction

Actions:

  1. Mark run log file paths for preservation
  2. Mark knowledge.md for preservation
  3. Save current stage for each active feature

Example:

# Before compaction
Context: 150,000 tokens (approaching limit)

PreCompact Hook:
- Preserve: .triqual/runs/login.md (WRITE stage)
- Preserve: .triqual/knowledge.md
- Preserve: Current agent: test-generator

# After compaction
Context: 50,000 tokens (compacted)

Preserved:
- Run logs intact ✅
- Knowledge.md intact ✅
- Current stage: WRITE ✅

What Survives Compaction

ContentLocationSurvives?
Run logs.triqual/runs/*.md✅ Yes (file-based)
Knowledge.triqual/knowledge.md✅ Yes (file-based)
Context files.triqual/context/**/*✅ Yes (file-based)
Configurationtriqual.config.ts✅ Yes (file-based)
Session state~/.cache/triqual/✅ Yes (separate from context)
Conversation historyClaude's context❌ No (compacted)
Agent intermediate resultsClaude's context❌ No (compacted)

Recovery After Compaction

SessionStart Hook detects active run logs:

📋 Active run logs detected:
- .triqual/runs/login.md (WRITE stage - ready to generate)

Suggestion: Read this log to resume work.

User resumes work:

# Read run log to recover context
cat .triqual/runs/login.md

# Continue from WRITE stage
/test login (continues from plan)

Best Practices

For Long-Running Workflows

DO:

  • Document every stage in run log ✅
  • Update knowledge.md with learnings ✅
  • Use descriptive feature names ✅
  • Commit run logs to git ✅

DON'T:

  • Rely on conversation history ❌
  • Skip documenting stages ❌
  • Assume context survives compaction ❌

For Team Collaboration

Share:

  • .triqual/runs/*.md (workflow state)
  • .triqual/knowledge.md (patterns)
  • triqual.config.ts (configuration)

Don't share:

  • ~/.cache/triqual/ (user-specific)
  • .auth/user.json (credentials)

For CI/CD

Include:

  • .triqual/knowledge.md (for pattern-aware testing)
  • triqual.config.ts (configuration)

Exclude:

  • .triqual/runs/*.md (development workflow, not needed in CI)
  • .triqual/context/**/* (regenerated as needed)

Troubleshooting

Issue: Session State Stale

Symptom: Hooks behave unexpectedly, old data

Solution:

rm -rf ~/.cache/triqual/

Issue: Run Logs Lost

Symptom: Can't find .triqual/runs/login.md

Check:

# Verify directory exists
ls -la .triqual/runs/

# Recreate if missing
mkdir -p .triqual/runs/

Issue: Knowledge Not Accumulating

Symptom: Patterns not saved

Check:

# Verify file exists
cat .triqual/knowledge.md

# Verify writes succeed
echo "test" >> .triqual/knowledge.md

Related Documentation


Next Steps: Read Learning Loop to understand run log stages, or Hooks System for compaction handling.