---
name: interaction-report
description: Interaction pattern report from Layer 2 session data
argument-hint: "[weekly|monthly|all]"
allowed-tools: [Read, Bash, Glob]
---

# Interaction Awareness Report

You are generating an interaction awareness report from JSONL session data.

## Step 1 — Layer guard

Read the file `.claude/ai-psychosis.local.md` in the current working
directory. If the file does not exist, or if its YAML frontmatter does not
contain `layer3: true`, stop and output:

```
Layer 3 (reports) is not enabled for this project.

To enable, create `.claude/ai-psychosis.local.md`:

    ---
    layer2: true
    layer3: true
    layer4: false
    ---

Then restart Claude Code.
```

Do not continue past this step if Layer 3 is not enabled.

Also note the value of `layer4` (true or false) — you will need it in Step 9.

## Step 2 — Parse arguments

The time period is determined by `$ARGUMENTS`:

| Argument | Period | Cutoff |
|----------|--------|--------|
| *(empty)* | Last 7 days | Today minus 7 days |
| `weekly` | Last 7 days | Today minus 7 days |
| `monthly` | Last 30 days | Today minus 30 days |
| `all` | All data | No cutoff |

If `$ARGUMENTS` is anything else, output:

```
Usage: /interaction-report [weekly|monthly|all]

  weekly   Last 7 days (default)
  monthly  Last 30 days
  all      All recorded data
```

## Step 3 — Locate data files

Run via Bash: `echo $CLAUDE_PLUGIN_DATA`

If the result is empty, use the fallback path `~/.claude/plugins/data/ai-psychosis`.

Check that both files exist:
- `{data_dir}/sessions.jsonl`
- `{data_dir}/events.jsonl`

If neither file exists, output:

```
No interaction data found.

Layer 2 (programmatic detection) collects data during active sessions.
Ensure Layer 2 is enabled and use Claude Code normally — data accumulates
automatically. Then run /interaction-report again.
```

If only `events.jsonl` is missing, proceed with sessions data only and note
"Tool usage data not available" in the report.

## Step 4 — Read data

### Size check

Run via Bash: `wc -l {data_dir}/sessions.jsonl {data_dir}/events.jsonl 2>/dev/null || true`

If a file does not exist, skip it and treat its line count as 0.

### Read sessions.jsonl

If the file has fewer than 1000 lines, read the entire file.
If larger, read the last 1000 lines (via Bash: `tail -n 1000 {data_dir}/sessions.jsonl`).

### Read events.jsonl

If the file has fewer than 5000 lines, read the entire file.
If larger and period is `weekly`: read the last 5000 lines.
If larger and period is `monthly` or `all`: read the last 10000 lines and note
"Events data sampled (last N entries)" in the report.

## Step 5 — Parse and filter records

### sessions.jsonl record types

The file contains two record types interleaved:

**Start records** — have `hour` and `is_late_night`, but NO `end` or `duration_min`:
```json
{"session_id":"abc","start":"2026-04-05T10:00:00Z","hour":10,"is_late_night":false}
```

**End records** — have `end`, `duration_min`, `tool_count`, `edit_count`, `flags`:
```json
{"session_id":"abc","start":"2026-04-05T10:00:00Z","end":"2026-04-05T11:35:00Z","duration_min":95,"tool_count":47,"edit_count":12,"flags":{"dependency":2,"escalation":0,"fatigue":1,"validation":1}}
```

**Error records** — have `note: "no_state_file"`. Ignore these.

### Filtering

For the selected time period, filter records where the `start` field is
greater than or equal to the cutoff date string (ISO timestamps sort
lexicographically — string comparison works correctly).

Separate start records from end records:
- **End records** (have `duration_min`): use for duration, tools, flags
- **Start records** (have `is_late_night`): use for late-night count

### events.jsonl

Filter events where `ts` >= cutoff date string. Group by `tool_name` and count.

## Step 6 — Compute statistics

From **end records**:
- Total sessions (count of end records in period)
- Average session duration (`sum(duration_min) / count`)
- Total tool calls (`sum(tool_count)`)
- Average edit ratio (`sum(edit_count) / sum(tool_count) * 100`, as percentage)
- Flag totals: `sum(flags.dependency)`, `sum(flags.escalation)`, `sum(flags.fatigue)`, `sum(flags.validation)`
- Average flags per session for each category

From **start records**:
- Late-night sessions: count where `is_late_night` is true

From **events.jsonl**:
- Tool usage: group by `tool_name`, count occurrences, sort descending
- Show top 10 tools

**Trend comparison** (weekly and monthly only):
- Compute the same metrics for the PREVIOUS period of equal length
- Calculate the delta (current minus previous)

If previous period has zero sessions, skip the trend section.

**Sessions without matching end records** are incomplete — count them separately
as "incomplete sessions" and exclude from duration/flag averages.

## Step 7 — Format report

Output the report as markdown. Use this exact structure:

```
## Interaction Awareness Report

**Period:** {start_date} to {end_date} ({N} days)
**Sessions:** {N} completed ({N} incomplete)
**Data source:** {path}

### Overview

| Metric | Value |
|--------|-------|
| **Sessions** | {N} |
| **Avg duration** | {N} min |
| **Total tool calls** | {N} |
| **Avg edit ratio** | {N}% |
| **Late-night sessions** | {N} |

### Pattern Flags

| Pattern | Total | Per session |
|---------|-------|-------------|
| Dependency language | {N} | {avg} |
| Escalation language | {N} | {avg} |
| Fatigue signals | {N} | {avg} |
| Validation-seeking | {N} | {avg} |

### Tool Usage (top 10)

| Tool | Count | % |
|------|-------|---|
| {name} | {N} | {pct}% |

### Daily Activity

| Date | Sessions | Total duration | Flags |
|------|----------|----------------|-------|
| {date} | {N} | {N} min | {summary} |

### Trend vs previous {period}

| Metric | Previous | Current | Delta |
|--------|----------|---------|-------|
| Sessions | {N} | {N} | {+/-N} |
| Avg duration | {N} min | {N} min | {+/-N} |
| Flags (total) | {N} | {N} | {+/-N} |

### Observations

- {data-driven observation}
- {data-driven observation}
```

## Step 8 — Tone and privacy rules

**MANDATORY:**

- Neutral, observational tone. You are presenting data, not making judgments.
- Never use words like "concerning", "worrying", "problematic", or "unhealthy".
- Never use emoji.
- Never speculate about what the user was doing or thinking.
- Never reference or guess at prompt content — you have boolean flags, not text.
- This is a mirror, not a diagnosis. Present the numbers and let the user
  interpret them.
- Observations section: state facts derived from data only. Examples:
  - "3 of 12 sessions were between 23:00 and 05:00"
  - "Dependency language flags appeared in 7 of 12 sessions"
  - "Edit ratio averaged 8%, below the 10% threshold in 5 sessions"
- If all metrics are within normal ranges, say so plainly:
  "All metrics within normal ranges for the reporting period."
- Omit any section that has no data (e.g., skip Trend if no previous period,
  skip Tool Usage if events.jsonl was missing).

## Step 9 — Contemplative reference (conditional)

This step applies ONLY when BOTH conditions are met:

1. `layer4: true` was noted in Step 1
2. Total flags (dependency + escalation + fatigue + validation) >= 5, OR fatigue flags >= 2

If both conditions are met, append this exact paragraph to the report.
**Do not modify, paraphrase, abbreviate, or add commentary to this text:**

```
### A note from the plugin author

The patterns above are structural — they emerge from the interaction itself,
not from individual weakness. If you find yourself wanting to understand the
mechanics of your own mind more deeply, the
[Miracle of Mind](https://isha.sadhguru.org/global/en/miracle-of-mind)
program by Sadhguru offers a structured approach. This is what works for me.
It is not a recommendation — just a pointer.
```

If either condition is not met, omit this section entirely. Do not mention
Layer 4, do not explain why the section was omitted.
