13 KiB
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:
- Client có hook trước prompt, trước/sau tool và khi turn kết thúc không?
- Hook có thể chặn hay chỉ quan sát?
- Có lấy được runtime/token/cost/failure đủ tin cậy cho H6 không?
- 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/Codex VS Code extension | Chưa black-box verify | Chưa verify | Chưa verify | Chưa verify | CONDITIONAL |
| 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:
UserPromptSubmitchạy trước khi Claude xử lý prompt, nhậnprompt, có thể thêm context hoặc trả decision block.PreToolUsecó thể allow/deny/ask và trong một số trường hợp sửa tool input.PostToolUsequan sát input/output sau tool.Stopnhận stop context và assistant message để bridge finalize..claude/settings.jsonlà 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:
- Bridge có internal timeout ngắn hơn timeout của client và chủ động trả block.
PreToolUsetừ chối side effect nếu turn không có admission hợp lệ.Stopkhông cấp certified nếu admission/evidence thiếu.- 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 VS Code, Claude/Codex extension 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 hoặc Codex extension có thể tái sử dụng CLI/project hooks, nhưng spike chưa có
black-box evidence trên máy hiện tại. Mỗi extension/version phải được test độc lập trước khi
gắn badge verified.
Verdict VS Code:
- GO cho CASAN-owned
@casanChat Participant; - CONDITIONAL cho native Claude/Codex extension tới khi black-box test pass;
- 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.jsonchoUserPromptSubmit,PreToolUse,PostToolUse,Stop;- bridge fixture không gọi network/model;
- deterministic policy: prompt marker
CASAN_SPIKE_BLOCKbị 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:
@casanparticipant 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:
- Claude Code: có đủ lifecycle hook để làm MVP; đây là spike/prototype đầu tiên.
- Codex: API hook phù hợp, reuse common bridge; managed hooks đáng ưu tiên cho rollout tổ chức.
- VS Code: xác minh native Claude/Codex extension riêng; bổ sung
@casanparticipant cho đường CASAN-owned. 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
- Claude Code hooks
- Claude Code status line
- Claude Agent SDK cost tracking
- Codex hooks
- VS Code Chat Participant API
- VS Code Language Model Chat Provider
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.