{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent hook claude PostToolUse >/dev/null",
            "timeout": 5
          }
        ],
        "description": "Emit a bounded Cortex progress/testing signal from a governed Claude tool completion; raw tool input/output is discarded."
      },
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/pre-commit-check.sh",
            "async": true,
            "timeout": 15
          }
        ],
        "description": "Layer 1（确定性）：文件编辑后自动执行质量检查（Lint / 密钥扫描），失败时阻断"
      }
    ],
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent hook claude SessionStart >/dev/null",
            "timeout": 5
          }
        ],
        "description": "Validate private Cortex context for a governed Claude session; only the launcher writes task.accepted."
      },
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "node -e \"const f='.agent/plans/task-progress.md'; const fs=require('fs'); if(fs.existsSync(f)){console.log('[Cortex] Task progress loaded: '+f);}\""
          }
        ],
        "description": "会话启动时提示加载任务进度文件"
      },
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "node -e \"const fs=require('fs');const p='.agent/memory/MEMORY.md';if(fs.existsSync(p)){const c=fs.readFileSync(p,'utf8');const lines=c.split('\\n').slice(0,200);const cap=Buffer.byteLength(c,'utf8')>25*1024;if(cap)lines.push('... [truncated, 25KB cap reached]');console.log('[Cortex] Memory index loaded:\\n'+lines.join('\\n'));}\"",
            "async": true,
            "timeout": 5
          }
        ],
        "description": "On session start, load .agent/memory/MEMORY.md index (≤200 lines / 25KB cap, topic files read on demand)"
      },
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "PROJ=$(node -e \"console.log(require('path').basename(process.cwd()))\"); CORTEX_SESSION_START=1 node .agent/skills/runtime-continuity/scripts/index.js warm --auto --project \"$PROJ\" 2>/dev/null; exit 0",
            "async": true,
            "timeout": 5
          }
        ],
        "description": "On session start, launch or renew the single runtime-continuity guard: catch up stale archives, archive every 2 hours, and exit after the 5-hour window"
      },
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent dashboard ensure --project \"$PWD\" --reason session-start >/dev/null 2>&1; exit 0",
            "async": true,
            "timeout": 5
          }
        ],
        "description": "Ensure the singleton Dashboard Supervisor only when the project explicitly enabled automation; disabled projects perform zero writes and start no process"
      },
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent bridge sync --auto >/dev/null 2>&1; exit 0",
            "async": true,
            "timeout": 10
          }
        ],
        "description": "P-006 §3.5: auto-pull every subscribed peer project's outbox into the local inbox by resolving host_root from the topology registry. Projects with no subscriptions perform zero reads. Source-unreachable peers are reported but never block the session."
      },
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent memory validate --quiet 2>&1",
            "timeout": 10
          }
        ],
        "description": "Session start: silently validate .agent/memory/MEMORY.md integrity (drift/missing/schema/orphan/duplicate/over-cap); one-line summary printed to session context if issues exist"
      }
    ],
    "PermissionRequest": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent hook claude Permission >/dev/null",
            "timeout": 5
          }
        ],
        "description": "Report a governed Claude permission request without approving, denying, or changing permissions."
      }
    ],
    "Notification": [
      {
        "matcher": "permission_prompt|agent_needs_input",
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent hook claude Notification >/dev/null",
            "timeout": 5
          }
        ],
        "description": "Convert Claude waiting-for-input notifications into Cortex task.input_required without forwarding notification text."
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "cortex-agent hook claude Stop >/dev/null",
            "timeout": 5
          }
        ],
        "description": "Record a non-terminal Stop; never infer completed or ready_for_review from it."
      }
    ]
  }
}
