Files
CASAN/docs/spikes/CASAN_SPIKE_20_AGENTIC_CLIENT_HOOKS.md

14 KiB
Raw Permalink Blame History

CASAN Spike-20 — Agentic Client Hooks

Ngày khảo sát: 2026-07-22
Kết quả: GO có điều kiện
Thứ tự prototype: Claude Code trước, Codex sau, VS Code cuối

Kế hoạch triển khai tương ứng: CASAN Plan-20.

1. Câu hỏi spike

CASAN có thể khiến developer gõ prompt bình thường trong Claude Code, Codex hoặc extension VS Code mà turn vẫn đi qua H1→H7 và sinh H6 report hay không?

Spike tập trung trả lời bốn câu:

  1. Client có hook trước prompt, trước/sau tool và khi turn kết thúc không?
  2. Hook có thể chặn hay chỉ quan sát?
  3. Có lấy được runtime/token/cost/failure đủ tin cậy cho H6 không?
  4. Có thể cam kết “mọi prompt” ở mức project, hay cần managed deployment/custom UI?

2. Baseline đã kiểm tra

Thành phần Kết quả
CASAN hiện tại bin/casan-chat/chat-turn.py sở hữu model execution và sinh H1→H7
Claude Code local 2.1.197
Codex CLI local 0.142.5; feature hooks ở trạng thái stable
VS Code CLI Không có code trong PATH của máy khảo sát; cần test trên máy pilot
Dependency policy Bridge phải dùng Python stdlib/executable hiện có, không cài library mới

3. Kết quả capability matrix

Client/path Before prompt Tool gate Turn end H6 usage/cost Kết luận
Claude Code project hooks UserPromptSubmit allow/block/context PreToolUse, PostToolUse Stop, failure hooks Runtime tốt; token/cost native per-turn chưa đủ trực tiếp GO cho strong project guardrail
Claude Code managed/custom SDK Có Có Có SDK ResultMessage có usage/cost tốt hơn GO cho assurance cao hơn
Codex project hooks UserPromptSubmit PreToolUse, PostToolUse Stop Cần prototype nguồn usage/cost GO sau Claude, có điều kiện
Codex managed hooks Có thể pin bằng policy/requirements Có, theo coverage docs Có Như trên GO cho enterprise rollout
Claude Code CLI / VS Code / JetBrains Dùng chung Claude Code project settings Dùng chung hook contract Dùng chung hook contract Như Claude Code project hooks SUPPORTED local surfaces
Codex desktop / CLI / IDE — Local Dùng chung Codex project hook layer Dùng chung hook contract Dùng chung hook contract Như Codex project hooks SUPPORTED local surfaces; trust bắt buộc
VS Code Chat Participant Participant sở hữu request được route tới nó Participant tự điều phối tools Participant sở hữu response Tự ghi được usage do model API trả về GO cho @casan, không phải global interceptor
VS Code participant detection Auto-route best effort Như participant nếu được route Có Có Không đủ để cam kết mọi prompt
Generic Copilot built-in chat Không có API công khai để intercept toàn bộ prompt Không có CASAN gate chung Không Không NO-GO cho tuyên bố transparent absolute

4. Phát hiện quan trọng

4.1 Claude Code

Official hooks có đúng các điểm lifecycle cần cho prototype:

  • UserPromptSubmit chạy trước khi Claude xử lý prompt, nhận prompt, có thể thêm context hoặc trả decision block.
  • PreToolUse có thể allow/deny/ask và trong một số trường hợp sửa tool input.
  • PostToolUse quan sát input/output sau tool.
  • Stop nhận stop context và assistant message để bridge finalize.
  • .claude/settings.json là project scope có thể commit; plugin cũng có thể bundle hook.

Giới hạn quyết định kiến trúc: hook có outer timeout. Tài liệu Claude nêu rằng khi UserPromptSubmit timeout, output bị bỏ và prompt vẫn tiếp tục. Vì vậy chỉ dùng prompt hook không tạo fail-closed boundary tuyệt đối.

Mitigation được chấp nhận cho MVP:

  1. Bridge có internal timeout ngắn hơn timeout của client và chủ động trả block.
  2. PreToolUse từ chối side effect nếu turn không có admission hợp lệ.
  3. Stop không cấp certified nếu admission/evidence thiếu.
  4. Managed environment hoặc CASAN-owned SDK/client là lựa chọn khi cần chống bypass mạnh.

H6:

  • lifecycle timestamps cho runtime/failure đáng tin cậy;
  • status line nhận session/model, estimated cost, duration và context usage;
  • nhưng per-turn attribution cần session delta/correlation và phải ghi estimated/partial;
  • Claude Agent SDK trả ResultMessage với usage/cost tốt hơn, đổi lại đây là custom agent path chứ không còn native Claude Code UI thuần túy.

Verdict Claude: GO cho prototype đầu tiên. Claim phù hợp là “mọi certified side-effect turn trong trusted project hooks đều có CASAN admission”; không claim “không thể bypass”.

4.2 Codex

Codex hiện có lifecycle hooks tương đương: UserPromptSubmit, PreToolUse, PostToolUse và Stop. Project config có thể đặt trong .codex/hooks.json/.codex/config.toml, nhưng project-local hooks chỉ load sau trust review. Đây phải là bước onboarding được doctor kiểm tra, không thể giấu khỏi member.

Điểm mạnh cho enterprise là managed hooks có thể được pin bằng requirements/policy và có chế độ chỉ cho managed hooks. Điểm hạn chế là official docs mô tả tool hooks như guardrail, không phải complete boundary: hosted web search và một số specialized tool có thể nằm ngoài coverage.

H6 token/cost chưa được chứng minh từ payload hook hiện tại. Prototype phải kiểm tra nguồn runtime event/telemetry của Codex. Nếu không có nguồn ổn định, record để null với telemetry_quality=partial thay vì suy ra số.

Verdict Codex: GO có điều kiện, bắt đầu sau khi Claude adapter dùng chung lifecycle contract đã pass. Managed hook là đường khuyến nghị khi tổ chức yêu cầu enforcement.

4.3 Local UI surfaces và Copilot

VS Code Chat Participant API cho phép extension tạo participant như @casan và sở hữu toàn bộ prompt được route tới participant đó. Participant detection có thể tự chọn participant cho câu tự nhiên, nhưng built-in participants được ưu tiên. Do đó detection là convenience, không phải global interception guarantee.

Language Model Chat Provider chỉ xử lý request khi model/provider đó được chọn; nó cũng không phải interceptor cho mọi model/chat có sẵn. Enterprise policy còn có thể vô hiệu provider kiểu BYOK.

Claude Code settings được tài liệu chính thức xác nhận dùng chung giữa CLI và VS Code extension; cùng settings precedence áp dụng cho CLI, VS Code và JetBrains. Codex official surface matrix xác định Hook áp dụng cho desktop app, CLI và IDE extension. Vì vậy CASAN dùng một adapter theo runtime, không fork adapter theo UI.

Qualification vẫn phải phân biệt supported contract với tested build: mỗi release nên smoke-test ít nhất một build của từng UI family và không suy rộng local project hook sang Codex Cloud/Web, Claude Desktop hoặc claude.ai.

Verdict VS Code:

  • GO cho Claude Code local trên CLI, VS Code và JetBrains qua shared project settings;
  • GO có trust gate cho Codex local trên desktop app, CLI và IDE extension;
  • GO cho CASAN-owned @casan Chat Participant;
  • NO-GO cho tuyên bố CASAN tự động intercept mọi prompt built-in Copilot bằng public API.

5. Kiến trúc prototype được chọn

Client hook JSON on stdin
        |
        v
client adapter (Claude/Codex renderer only)
        |
        v
CASAN agentic bridge
  begin -> pre-tool -> post-tool -> telemetry -> finalize/abort
        |
        +--> admission state (TTL + project/session binding)
        +--> H1-H7 trace/evidence
        +--> H6 metrics with provenance + quality

Bridge không gọi model. Claude/Codex tiếp tục là model executor duy nhất. Đây là cách duy nhất giữ native UX mà không double execution.

Lifecycle state machine

stateDiagram-v2
    [*] --> Admitted: begin allow
    [*] --> Rejected: begin block
    Admitted --> Active: native model starts
    Active --> Active: pre-tool allow + post-tool evidence
    Active --> PolicyBlocked: pre-tool deny
    Active --> Finalizing: Stop
    Active --> Aborted: error/interruption/expired
    PolicyBlocked --> Finalizing
    Finalizing --> Certified: required evidence complete
    Finalizing --> NonCertified: missing/failed/unsupported coverage
    Rejected --> [*]
    Certified --> [*]
    NonCertified --> [*]
    Aborted --> [*]

6. Claude Code experiment — thực hiện đầu tiên

Fixture tối thiểu

Không gắn vào user-global config. Tạo temp fixture project chứa:

  • .claude/settings.json cho UserPromptSubmit, PreToolUse, PostToolUse, Stop;
  • bridge fixture không gọi network/model;
  • deterministic policy: prompt marker CASAN_SPIKE_BLOCK bị block;
  • side-effect tool chỉ allow khi có đúng admission.

Test cases

# Case Expected
C1 Prompt bình thường một admission, một trace, native model tối đa một lần
C2 Prompt vi phạm policy block trước model theo hook capability
C3 Bash/Edit/Write có admission pre allow, post evidence cùng trace
C4 Tool không admission deny và H6 failure
C5 Admission expired/cross-project deny
C6 Bridge internal timeout explicit block; trace aborted
C7 Client outer hook timeout ghi nhận documented fail-open risk; side effect vẫn bị pre-tool deny
C8 Stop bình thường finalize đúng một lần
C9 Stop/error lặp idempotent, không loop vô hạn
C10 Token/cost unavailable null + partial warning, không phải zero
C11 Secret/tool output log redaction pass
C12 Windows path có space PowerShell install + prompt + report pass

Exit decision

  • GO Claude MVP: C1–C12 pass, H1→H7/H6 cùng trace, không double execution.
  • HOLD: prompt works nhưng tool gate hoặc finalize không reliable.
  • NO-GO native hooks: không thể deny side effect khi bridge fail; chuyển sang managed wrapper/Agent SDK CASAN-owned path.

7. Codex experiment — chỉ chạy sau Claude GO

Reuse toàn bộ C1–C12 với Codex payload fixtures, cộng thêm:

  • X1: untrusted project không load hook → doctor phải báo non-certified.
  • X2: trusted project load đúng hash/review.
  • X3: managed-only policy chặn project/user override.
  • X4: tool coverage matrix được đối chiếu với tool thực tế.
  • X5: hosted/specialized tool ngoài hook coverage làm trace hạ cấp.
  • X6: xác minh nguồn usage/cost; nếu không có thì H6 partial.

8. VS Code experiment — chỉ chạy sau Codex GO

  • V1: Claude Code extension có phát đủ four lifecycle events hay không.
  • V2: Codex extension có load project/managed hooks và trust state hay không.
  • V3: restart Extension Host/VS Code có giữ admission cleanup đúng không.
  • V4: Windows Remote/WSL path mapping có canonical project root đúng không.
  • V5: @casan participant nhận prompt, stream response và finalize trace.
  • V6: participant detection conflict với built-in participant được mô tả đúng là best effort.
  • V7: built-in Copilot prompt không route qua participant không được CASAN chứng nhận.

9. Rủi ro và cách xử lý

Rủi ro Mức Xử lý
Prompt hook timeout rồi client tiếp tục Cao internal timeout + side-effect pre-tool gate + non-certified
User sửa/tắt project hook Cao hiện project_hook; managed policy cho tổ chức cần enforcement
Double model execution Cao bridge tuyệt đối không gọi chat-turn.py ask/provider
Tool nằm ngoài hook coverage Cao capability matrix + hạ cấp certification
Token/cost không có per-turn Vừa nullable fields + provenance + quality warning
Session/turn mapping sai Cao opaque ID + session binding + concurrency/replay tests
Secret lọt vào log Cao hash/redact/allowlist metadata; không lưu raw prompt/tool output mặc định
Windows quoting/path spaces Vừa PowerShell-native installer + test path có dấu cách
Hook làm agent chậm Vừa local bridge, bounded timeout, latency budget và H6 P95

10. Kết luận spike

Hướng này khả thi và nên làm theo đúng thứ tự đã yêu cầu:

  1. Claude Code: có đủ lifecycle hook để làm MVP; đây là spike/prototype đầu tiên.
  2. Codex: API hook phù hợp, reuse common bridge; managed hooks đáng ưu tiên cho rollout tổ chức.
  3. Local UI surfaces: dùng chung adapter theo runtime; smoke-test desktop/CLI/IDE trong release qualification. Bổ sung @casan participant cho đường CASAN-owned và không hứa intercept toàn bộ Copilot built-in chat.

Kết quả được gọi là “đi qua CASAN” khi có trace/admission/finalize và certification strength rõ ràng, không chỉ vì project có một file hướng dẫn hoặc hook telemetry.

11. Nguồn chính thức

Các capability ở tài liệu này phải được black-box test trên version phát hành trước khi đổi trạng thái adapter thành supported.