Skip to content

Session Initialization Hook

The session-init hook runs at the start of every Claude Code session to load workflow state, inject context about the current phase, and remind users of pending checkpoints.

Overview

Attribute Value
Hook Name session-init
Script hooks/scripts/session-init.py
Event SessionStart
Matcher None (runs for all sessions)
Blocking No (informational only)
Timeout 10000ms

Purpose

The session initialization hook serves three key purposes:

  1. State Detection: Identifies whether an active encoding session exists
  2. Context Injection: Informs the AI about current workflow state
  3. Guidance: Provides instructions for starting or resuming work

Configuration

In hooks/hooks.json:

{
  "SessionStart": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "python ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-init.py",
          "timeout": 10000
        }
      ]
    }
  ]
}

Behavior

No Active Session

When no .mistaber-session.yaml exists:

Mistaber Encoding Plugin Active

No active encoding session found.
To start encoding: "Prepare corpus for YD {siman}:{seif}"

Workflow Rules:
- Cannot write .lp files until corpus-prep approved
- Cannot commit until review approved
- All rules require @makor attribution

Active Session Found

When an encoding session exists:

Resuming Encoding Session

Target: YD:87:3
Current Phase: hll-encode

Checkpoint Status:
  corpus-prep: approved
  hll-encode: pending_review
  validate: not_started
  review: not_started

Action Required: hll-encode checkpoint awaiting review

Workflow Rules:
- Cannot write .lp files until corpus-prep approved
- Cannot commit until review approved
- All rules require @makor attribution

Session State Error

When session file exists but cannot be parsed:

Session State Warning

Could not parse .mistaber-session.yaml: [error details]

Implementation Details

State Loading

def load_session_state() -> dict | None:
    """Load existing session state if it exists."""
    session_path = Path(".mistaber-session.yaml")
    if not session_path.exists():
        return None

    if yaml is None:
        # Fallback: basic parsing
        return {"exists": True, "parse_error": "PyYAML not installed"}

    try:
        with open(session_path, "r") as f:
            return yaml.safe_load(f)
    except Exception as e:
        return {"exists": True, "parse_error": str(e)}

Checkpoint Formatting

def format_checkpoint_status(checkpoints: dict) -> str:
    """Format checkpoint status for display."""
    lines = []
    checkpoint_order = ["corpus-prep", "hll-encode", "validate", "review"]

    for checkpoint in checkpoint_order:
        data = checkpoints.get(checkpoint, {})
        status = data.get("status", "not_started")

        if status == "approved":
            icon = "completed"
        elif status == "pending_review":
            icon = "pending"
        else:
            icon = "not started"

        lines.append(f"  {checkpoint}: {status}")

    return "\n".join(lines)

Output Generation

def main():
    """Main hook execution."""
    session = load_session_state()

    output = {
        "continue": True,  # Always continue - informational only
        "message": ""
    }

    messages = []

    if session is None:
        messages.append(
            "Mistaber Encoding Plugin Active\n"
            "No active encoding session found.\n"
            "To start encoding: \"Prepare corpus for YD {siman}:{seif}\""
        )
    elif "parse_error" in session:
        messages.append(
            f"Session State Warning\n"
            f"Could not parse .mistaber-session.yaml: {session['parse_error']}"
        )
    else:
        # Active session found
        current_phase = session.get("current_phase", "unknown")
        target_seif = session.get("target_seif", "unknown")
        checkpoints = session.get("checkpoints", {})

        messages.append(
            f"Resuming Encoding Session\n"
            f"Target: {target_seif}\n"
            f"Current Phase: {current_phase}\n\n"
            f"Checkpoint Status:\n"
            f"{format_checkpoint_status(checkpoints)}"
        )

    # Add workflow rules reminder
    messages.append(
        "\nWorkflow Rules:\n"
        "- Cannot write .lp files until corpus-prep approved\n"
        "- Cannot commit until review approved\n"
        "- All rules require @makor attribution"
    )

    output["message"] = "\n".join(messages)
    print(json.dumps(output))
    return 0

Session State Format

The hook reads .mistaber-session.yaml:

current_phase: hll-encode
target_seif: "YD:87:3"
started: 2026-01-25T10:00:00Z
last_activity: 2026-01-25T14:30:00Z
checkpoints:
  corpus-prep:
    status: approved
    approved_by: human
    timestamp: 2026-01-25T10:30:00Z
  hll-encode:
    status: pending_review
  validate:
    status: not_started
  review:
    status: not_started

Status Values

Status Icon Meaning
approved Completed Checkpoint passed
pending_review Pending Awaiting human approval
not_started Not started Phase not begun
in_progress In progress Phase executing
tests_passed Completed Tests successful
tests_failed Failed Tests have failures

Error Handling

PyYAML Not Installed

If PyYAML is not available, the hook falls back to basic detection:

if yaml is None:
    return {"exists": True, "parse_error": "PyYAML not installed"}

Malformed Session File

If the YAML is invalid:

try:
    return yaml.safe_load(f)
except Exception as e:
    return {"exists": True, "parse_error": str(e)}

Integration Points

With Skills

The session-init hook informs the AI about:

  • Which skill to resume if session exists
  • What checkpoint needs approval
  • What work remains

With Other Hooks

Other hooks rely on session state loaded by session-init:

  • phase-gate checks checkpoint status
  • git-commit-guard verifies all approvals
  • checkpoint-enforcement warns about pending work

Debugging

Manual Testing

# Test with no session
rm -f .mistaber-session.yaml
python mistaber-skills/hooks/scripts/session-init.py | jq .

# Test with session
echo "current_phase: hll-encode" > .mistaber-session.yaml
python mistaber-skills/hooks/scripts/session-init.py | jq .

Debug Mode

export MISTABER_DEBUG=1
python mistaber-skills/hooks/scripts/session-init.py

Common Issues

Session Not Detected

Symptom: Hook reports no session when one exists.

Causes: - Wrong working directory - File permissions - Hidden file not visible

Solutions:

ls -la .mistaber-session.yaml
cat .mistaber-session.yaml

YAML Parse Error

Symptom: "Could not parse" error.

Causes: - Invalid YAML syntax - Encoding issues - Truncated file

Solutions:

python -c "import yaml; yaml.safe_load(open('.mistaber-session.yaml'))"