#!/usr/bin/env ruby
# encoding: UTF-8
# frozen_string_literal: true

# Usage: hook-code-gate <file_path> [session_id] [content]
# PreToolUse gate. Composes two independent block rules; EITHER blocks the edit:
#   - Stage rule (intent 27): when auto mode is armed and the active intent has not
#     reached How (plan.md + checklist.md), block edits to project code outside the store.
#   - Worktree isolation rule (intent 73c2): when the intent has a provisioned code
#     worktree, block project-code edits outside it; and block edits to another
#     intent's store dir whose delivery lock is held by a live non-owner session.
#
# Exit 0 = allow. Exit 2 = block (reason on stderr, shown to the agent).
# No bridge = allow. Each rule fails open on its own conditions (see bridge.rb).
#
# Thin CLI wrapper (intent 244): the gate logic itself lives in
# scripts/lib/edit_gates.rb, shared with the merged Claude dispatcher
# (scripts/hook-edit-gates) and, since intent 251, the merged Codex dispatcher
# (scripts/lib/codex_edit_gates.rb). This wrapper has no production caller on
# either harness anymore; it remains as the per-gate isolation surface for the
# hook test suite.

require_relative "lib/edit_gates"

file_path = ARGV[0]
exit 0 unless file_path && !file_path.empty?

session = (ARGV[1] unless ARGV[1].to_s.empty?) || ENV["CLAUDE_CODE_SESSION_ID"]

ctx = EditGates::Context.new(
  tool_name: "Write", session: session, gate_path: file_path, file_path: file_path,
  content: ARGV[2], harness: "claude",
)

outcome = EditGates.code_gate(ctx)
exit 0 unless outcome
outcome.lines.each { |line| $stderr.puts line }
exit 2
