Skip to main content

/session-status

Show all active LLM sessions with full identifiers, task claims, file locks, operator alerts, unread messages, session lifecycle events, and cross-LLM coordination status from the Inter-Session Message Bus (messaging.db). Automatically appends a detailed entry to the session log.

Purpose

Queries the session_registry, task_claims, file_locks, and session_messages tables in messaging.db (ADR-160, ADR-173) to display a comprehensive dashboard of all active sessions with full detail (session UUID, machine UUID, hostname, vendor, project, CWD, PID, uptime, claimed tasks, file locks, operator alerts, unread messages, recent lifecycle events). Then auto-appends the full dashboard as a /session-log entry for traceability.

Usage

# Show all active sessions + auto-log
/session-status

# Show bus stats only
/session-status --stats

# Show file locks only
/session-status --locks

# Show task claims only
/session-status --claims

# Show operator alerts (ADR-173)
/session-status --alerts

# Show unread messages for this session (ADR-173)
/session-status --unread

# Show recent session lifecycle events (ADR-173)
/session-status --lifecycle

# Skip auto-logging
/session-status --no-log

Arguments

ArgumentTypeRequiredDefaultDescription
--statsflagNofalseShow bus statistics (sessions, messages, locks, claims, v2 counts)
--locksflagNofalseShow all active file locks
--claimsflagNofalseShow all task claims
--alertsflagNofalseShow operator alerts (project/task/cwd/file conflicts) (ADR-173)
--unreadflagNofalseShow unread messages for the current session (ADR-173)
--lifecycleflagNofalseShow recent session lifecycle events (started/ended/resumed) (ADR-173)
--verboseflagNofalseShow full timestamps and bus details
--no-logflagNofalseSkip auto-appending to session log

System Prompt

When the user invokes /session-status:

Step 1: Query the Message Bus

import sys, json, os
sys.path.insert(0, 'submodules/core/coditect-core')
from scripts.core.session_message_bus import get_session_message_bus
bus = get_session_message_bus()
status = bus.get_cross_llm_status()
stats = bus.stats()
locks = bus.get_file_locks()
claims = bus.get_task_claims()

# ADR-173 v2: Query structured messages
current_session = f"claude-{os.getpid()}"
alerts = bus.get_operator_alerts(unread_only=True, limit=20)
unread = bus.get_unread(recipient_id=current_session, limit=50)
lifecycle = bus.poll("session_lifecycle", since_id=0, limit=20)

# SessionMessage fields (verified):
# id, sender_id, channel, payload (dict), created_at, ttl_seconds,
# sender_session_uuid, recipient_id, message_type, priority, status,
# project_id, task_id, activity, reply_to, expires_at, delivered_at, read_at
# NOTE: payload is already a dict (not JSON string) — do NOT json.loads() it
# NOTE: use .message_type (not .alert_type), .created_at (not .timestamp)

def safe_payload(msg):
"""Extract payload — already a dict from the bus API."""
p = msg.payload
if isinstance(p, dict):
return p
if isinstance(p, str):
try:
return json.loads(p)
except (json.JSONDecodeError, TypeError):
return {"raw": p}
return {}

Step 1b: Summarize ADR-173 v2 Data

  • Operator Alerts: Group by type (project_conflict, task_conflict, cwd_overlap, file_conflict), show priority and involved sessions
  • Unread Messages: Count by channel, show highest-priority first
  • Lifecycle Events: Show recent started/ended events with timestamps and session identifiers

Step 1c: Mark Alerts as Delivered (Acknowledgment Workflow)

When displaying alerts, mark them as delivered to complete the first stage of the delivery tracking loop:

# Mark all displayed alerts as delivered
for alert in alerts:
try:
bus.mark_delivered(alert.id)
except Exception:
pass # Best-effort — don't fail the dashboard

# Mark all displayed unread messages as delivered
for msg in unread:
try:
bus.mark_delivered(msg.id)
except Exception:
pass

Delivery Tracking Loop (ADR-173):

  1. pending → Alert published by conflict detection or session lifecycle
  2. delivered → Alert displayed to user by /session-status or /orient (auto, this step)
  3. read → User takes action: changes CWD, releases task, or explicitly runs /session-conflicts --acknowledge

This ensures the operator knows which alerts have been seen vs. which are still pending.

Step 2: Verify PIDs Are Alive

# Check all registered PIDs
ps -p {pid1},{pid2},... -o pid,stat,etime,command

Step 3: Display Full Dashboard to User

Display the dashboard with full detail per session (see Output Format below).

Step 4: Auto-Append to Session Log

Unless --no-log is specified, append the entire dashboard as a session log entry using /session-log conventions:

  1. Get current UTC timestamp
  2. Determine session log path (ADR-155 project-scoped)
  3. Append entry with heading: ### {timestamp} - [H.0] Cross-LLM Session Dashboard Status
  4. Include **Author:** Claude (Opus 4.6) (or appropriate model)
  5. Include full per-session detail blocks (not a compressed table)
  6. Include bus statistics
  7. Include observations

The session log entry MUST use per-session detail blocks, not tables, because tables truncate UUIDs and paths.

Output Format

Per-Session Detail Block (REQUIRED FORMAT)

Each session MUST be displayed as a detail block with all available fields:

**Session: {session_id}** {marker}
- **Session UUID:** `{session_uuid}`
- **Machine UUID:** `{machine_uuid}`
- **Hostname:** `{hostname}`
- **Vendor:** {llm_vendor} ({llm_model})
- **Project:** {project_id or "(not set)"}
- **TTY:** {tty or omit if null}
- **CWD:** `{cwd}`
- **PID:** {pid} (uptime {elapsed})
- **Claimed Task:** {claimed_task or "(none)"}
- **File Locks:** {lock_list or "(none)"}
- **Unread Messages:** {unread_count or 0}

Where {marker} is (THIS SESSION) for the session matching the current PID.

Required Fields Per Session

FieldSourceRequired
Session IDsession_id from busAlways
Session UUIDsession_uuid from busAlways
Machine UUIDmachine_uuid from busAlways
Hostnamehostname from busAlways
Vendorllm_vendor from busAlways
Modelllm_model from busIf available
Projectproject_id from busAlways (show "(not set)" if null)
TTYtty from busOnly if non-null
CWDcwd from busAlways (full path)
PIDpid from busAlways
Uptimefrom ps -o etimeAlways
Claimed Taskclaimed_task from busAlways (show "(none)" if null)
File Locksfrom get_file_locks()Always (show "(none)" if empty)
Unread Messagesfrom get_unread() countAlways (show 0 if none)

Output Examples

Standard Output

Cross-LLM Session Dashboard
==================================================
2 active sessions | 1 file lock | 2 task claims | 1 alert | 3 unread

**Session: claude-29583** (THIS SESSION)
- **Session UUID:** `a1b2c3d4-e5f6-7890-abcd-ef1234567890`
- **Machine UUID:** `d3d3a316-09c6-8f41-4a3f-d93e422d199c`
- **Hostname:** `halcasteel.local`
- **Vendor:** claude (opus-4.6)
- **Project:** PILOT
- **CWD:** `/Users/halcasteel/PROJECTS/coditect-rollout-master`
- **PID:** 29583 (uptime 2h 15m)
- **Claimed Task:** H.13.7 (exclusive)
- **File Locks:** session_message_bus.py, paths.py
- **Unread Messages:** 3

**Session: codex-41200**
- **Session UUID:** `f9e8d7c6-b5a4-3210-fedc-ba9876543210`
- **Machine UUID:** `d3d3a316-09c6-8f41-4a3f-d93e422d199c`
- **Hostname:** `halcasteel.local`
- **Vendor:** codex (o3)
- **Project:** PILOT
- **CWD:** `/Users/halcasteel/PROJECTS/coditect-rollout-master/submodules/core/coditect-core`
- **PID:** 41200 (uptime 1h 30m)
- **Claimed Task:** J.27.4 (exclusive)
- **File Locks:** (none)
- **Unread Messages:** 0

**Operator Alerts (ADR-173):**
- project_conflict (priority 3/critical): claude-29583 + codex-41200 both on PILOT
- Auto-detected on registration — coordinate task boundaries

**Session Lifecycle (ADR-173, last 10):**
- 2026-02-11T00:31:37Z started claude-29583 (PILOT)
- 2026-02-11T00:15:22Z started codex-41200 (PILOT)

**Bus Statistics:**
- Active sessions: 2 / 5 historical
- File locks: 1
- Task claims: 2 (H.13.7, J.27.4)
- Legacy messages: 3
- v2 messages: 8 (5 pending, 1 delivered, 2 read)
- Unread alerts: 1
- Database: `~/.coditect-data/context-storage/messaging.db` (52 KB, WAL mode)

**Observations:**
- All 2 PIDs confirmed alive via `ps`
- Both sessions on same machine (`d3d3a316-...` / `halcasteel.local`)
- No file lock conflicts detected
- 1 operator alert: project_conflict (PILOT shared by 2 sessions — ensure non-overlapping tasks)
- Session lifecycle: 2 active sessions started today

==================================================
Session log entry appended: SESSION-LOG-2026-02-11.md

--alerts Output (ADR-173)

Operator Alerts
==================================================
2 unread alerts

[CRITICAL] project_conflict — 2026-02-11T00:31:37Z
Sessions: claude-29583, codex-41200
Project: PILOT
Action: Coordinate task boundaries to avoid overlap

[HIGH] cwd_overlap — 2026-02-11T00:31:37Z
Sessions: claude-29583, codex-41200
CWD: /Users/halcasteel/PROJECTS/coditect-rollout-master
Action: One session should work in a subdirectory

--lifecycle Output (ADR-173)

Session Lifecycle Events (last 20)
==================================================

2026-02-11T00:31:37Z started claude-29583 PILOT /Users/halcasteel/PROJECTS/coditect-rollout-master
2026-02-11T00:15:22Z started codex-41200 PILOT /Users/halcasteel/PROJECTS/coditect-rollout-master/...
2026-02-10T23:45:00Z ended claude-88200 PILOT (session ended normally)

--stats Output

Inter-Session Message Bus Statistics
==================================================
Active sessions: 2
Total sessions: 5 (historical)
Legacy messages: 3
v2 messages: 8
v2 pending: 5
Unread alerts: 1
File locks: 1
Task claims: 2
Database size: 52 KB
Database path: ~/.coditect-data/context-storage/messaging.db
Journal mode: WAL

No Active Sessions

Cross-LLM Session Dashboard
==================================================
0 active sessions

No LLM sessions are currently registered.
Run /session-register to register this session.

Session Log Entry Format

The auto-appended session log entry follows this exact structure:

### {UTC_TIMESTAMP} - [H.0] Cross-LLM Session Dashboard Status

**Author:** Claude (Opus 4.6)

Inter-Session Message Bus queried for active session status.

**Cross-LLM Session Dashboard:**

**Session: {session_id}** {marker}
- **Session UUID:** `{session_uuid}`
- **Machine UUID:** `{machine_uuid}`
- **Hostname:** `{hostname}`
- **Vendor:** {vendor} ({model})
- **Project:** {project}
- **CWD:** `{cwd}`
- **PID:** {pid} (uptime {elapsed})
- **Claimed Task:** {claimed_task}
- **File Locks:** {locks}

{...repeat for each session...}

**Operator Alerts (ADR-173):**
- {alert_type} (priority {N}/{label}): {session1} + {session2} on {resource}
{...repeat for each alert...}

**Session Lifecycle (ADR-173, last 10):**
- {timestamp} {event_type} {session_id} ({project})
{...repeat for each event...}

**Bus Statistics:**
- Active sessions: {active} / {total} historical
- File locks: {N}
- Task claims: {N} ({list})
- Legacy messages: {N}
- v2 messages: {N} ({pending} pending, {delivered} delivered, {read} read)
- Unread alerts: {N}
- Database: `~/.coditect-data/context-storage/messaging.db` ({size}, WAL mode)

**Observations:**
- {PID liveness check result}
- {Machine/hostname grouping}
- {UUID sharing / /continue sibling detection}
- {Current session context}
- {File lock conflict status}
- {Operator alert summary and recommendations}
- {Session lifecycle activity summary}

Key rules for the session log entry:

  • Use per-session detail blocks, NEVER tables (tables truncate UUIDs and paths)
  • Include ALL fields from the bus query — nothing omitted
  • Full absolute paths for CWD (not abbreviated)
  • Session UUIDs and Machine UUIDs in backtick code spans
  • Observations section includes analysis (shared UUIDs = /continue siblings, same machine grouping, operator alert recommendations, etc.)
  • Include Operator Alerts and Session Lifecycle sections (ADR-173)

Health & Staleness

Sessions are automatically cleaned based on heartbeat freshness:

StateCriteriaAction
ActiveHeartbeat within stale_timeout (default 300s)Shown in dashboard
StaleHeartbeat expiredAuto-cleaned on next query

Stale sessions have their file locks and task claims automatically released.

When to Use

Use this command when:

  • Want to see which LLMs are active and what they're working on
  • Checking for task claim conflicts before claiming a task
  • Monitoring file lock status across sessions
  • Debugging multi-session coordination issues
  • Creating a point-in-time snapshot of all active sessions for the session log

Common Workflows

Workflow 1: Multi-LLM Check (Auto-Logged)

# See all active LLM sessions — dashboard displayed AND logged
/session-status

# Output shows full detail per session + auto-appends to session log
# No separate /session-log call needed

Workflow 2: Before Claiming a Task

# Check if task is already claimed
/session-status --claims

# If unclaimed, claim it via Python API:
# bus.claim_task("H.14.1", session_id="claude-{pid}")

Workflow 3: File Lock Coordination

# Check which files are locked
/session-status --locks

# If your target file is locked, coordinate with the lock holder

Workflow 4: Quick Check Without Logging

# View status without appending to session log
/session-status --no-log

Integration

Works with the full Inter-Session Message Bus:

FeatureAPI
Session registrationbus.register_session()
Session heartbeatbus.start_heartbeat_thread()
File lockingbus.lock_file() / bus.unlock_file()
Task claimsbus.claim_task() / bus.release_task()
Pub/sub messagingbus.publish() / bus.poll()
Cross-LLM statusbus.get_cross_llm_status()
Operator alerts (ADR-173)bus.get_operator_alerts()
Unread messages (ADR-173)bus.get_unread()
Directed messaging (ADR-173)bus.send() / bus.mark_read()
Conflict detection (ADR-173)bus._detect_conflicts() (auto on register)
Session log/session-log (auto-invoked)

Error Handling

ErrorCauseSolution
"No sessions"No sessions registeredRun /session-register first
"Database not found"messaging.db doesn't existRun CODITECT-CORE-INITIAL-SETUP.py
"Database locked"Concurrent accessAuto-retries with busy_timeout=3000ms
"Session log write failed"Log directory missingCheck ADR-155 project-scoped paths

Completion Checklist

Before marking complete:

  • Message bus queried successfully
  • All registered PIDs verified alive via ps
  • Full dashboard displayed with per-session detail blocks
  • All fields present: session UUID, machine UUID, hostname, vendor, project, CWD, PID, uptime, claimed task, file locks, unread count
  • Operator alerts section displayed (ADR-173)
  • Session lifecycle section displayed (ADR-173)
  • Bus statistics displayed (including v2 counts)
  • Observations section includes analysis (including alert recommendations)
  • Session log entry appended (unless --no-log)
  • Confirmation line shows log file path
CommandPurpose
/session-registerRegister current session with the bus
/session-conflictsCheck for file lock conflicts
/session-rescueRecover hung/stuck sessions
/session-logAppend entries to session log (auto-invoked by this command)

Architecture


Version: 4.2.0 Created: 2026-02-07 Updated: 2026-02-15 Author: Claude Opus 4.6 Track: H (Framework Autonomy) Task: H.13.9

Changelog:

  • v4.2.0 - Fix SessionMessage field references: use .message_type (not .alert_type), .created_at (not .timestamp), payload is already dict (not JSON string). Added safe_payload() helper and field reference comment.
  • v4.1.0 - Alert acknowledgment workflow: auto-mark displayed alerts as delivered (Step 1c), delivery tracking loop documentation
  • v4.0.0 - ADR-173 v2 integration: operator alerts, unread messages, session lifecycle events, conflict detection summary, --alerts, --unread, --lifecycle flags, v2 bus stats
  • v3.0.0 - Full detail per session (session UUID, machine UUID, hostname, full CWD), auto-append to session log, --no-log flag, per-session detail blocks instead of tables
  • v2.0.0 - Initial Inter-Session Message Bus integration (ADR-160)
  • v1.0.0 - Basic session summary