plan: update plan20

This commit is contained in:
thanhnv
2026-07-22 00:20:12 +07:00
parent 6faf589694
commit 0cc43d94d3
8 changed files with 566 additions and 4 deletions
+3 -1
View File
@@ -4,7 +4,7 @@
> bước tiếp theo cụ thể + cờ phụ-thuộc-hạ-tầng, để **bất kỳ AI/người nào tiếp quản
> cũng làm tiếp được ngay**. Cập nhật mỗi khi hoàn thành một mục.
>
> Cập nhật lần cuối: 2026-07-17 · Nhánh làm tiếp từ handoff Claude/Codex.
> Cập nhật lần cuối: 2026-07-22 · Nhánh làm tiếp từ handoff Claude/Codex.
>
> **Vai trò file (single source of truth):** file này là **nguồn chuẩn cho "còn
> gì phải làm"**. Control **đã implement+test** → xem `CASAN_HARDENING_STATUS.md`.
@@ -67,6 +67,8 @@
| **17 Loop Engineering** | � T1–T6 done+test (offline) | **Agentic Loop Governance** — đủ 5 primitive + orchestrator (97/0 WSL, nối CI). T1 **Governor** (`loop-governor.py`; deny-by-default, no/corrupt policy→strict/HALT, on_exceed halt/escalate) 15/0; T2 **Convergence** (`loop-convergence.py`; repeat/thrash→OSCILLATING, flat→STALLED, fail-closed) 15/0; T3 **Verify Contract** (`loop-gate.py`; H4→DENY, unmet→FAIL, correction bounded→ESCALATE, no self-declared DONE) 20/0; T4 **Trace/Replay** (`loop-trace.py`; append-only hash-linked, edited→BREAK, tampered artifact→replay DRIFT) 16/0; T5 **Meta-loop** (`loop-metaloop.py`; propose≠apply, SoD, loosen>org_ceiling refused, apply qua governed CP store→đổi thật ceiling + rollback) 15/0; T6 **Orchestrator** (`loop-run.sh`; gate→governor→convergence→trace/turn, secure-by-default opt-out, nén giữa vòng) 16/0. State qua `CASAN_LOOP_STATE_ROOT` (repo `.specify/state` sạch). **Còn (infra):** T4 KMS-anchor head (A7 Vault), T6 widget Command Center (17.22, C5), live H3-judge. Chi tiết: `CASAN_PLAN_17_LOOP_ENGINEERING.md`. |
| **16 Security audit remediation** | � P0/P1/P2 phần lớn done+test | **Remediation đã thực thi:** 28 SEC suite (151/0 WSL, nối `ci-harness-gate.sh`). Done: SEC-01..10, 12, 13, **14** (model-digest bỏ env-override ở prod/strict), 15, 16..21, **22** (trusted-time JWT `exp` ARCH-06 + tag proposal nguồn-không-tin ARCH-08), **26** (stored/second-order injection scan), 27..30, **23 Phase 1–5 offline** (multi-tenant: tenant-store+guard · per-tenant CP/audit/telemetry · RBAC data-boundary · tenant kill-switch/quota · ký registry · crypt at-rest per-tenant), **24 offline** (image digest-pin + ký workflow), **25 offline** (artifact attestation tested==deployed); **SEC-11 gộp vào SEC-17** (`CASAN_PROFILE=prod` enforce-by-default). **Còn 📋 planned (hạ tầng/process):** SEC-22 ARCH-10 (attestation ngoài) · SEC-23 23.11 (crypt qua Vault Transit) · **SEC-24 còn** (live CVE/OSV + scan image thật — offline image-pin/ký-workflow đã done) · **SEC-25 còn** (signed-commit enrollment + SLSA chain — offline artifact-attestation đã done). Chi tiết: `CASAN_PLAN_16` §0a/§2d. |
| **18 Chat Console** | ✅ **MVP-0 + MVP-1 + MVP-2 + MVP-3 + Track M done+test** | **Governed Chat Console** (cắt lát MVP chống lan man). **MVP-0 Ask CASAN read-only DONE**: `prompt-mode-router.py`, `chat-readonly.py`, `chat-session.schema.json`, H4 input/output scan, H5 chat audit hash-chain, H6 token telemetry, answer kèm evidence sources. **MVP-1 Operator DONE**: registered actions through `action-gate`, no free-command, action artifacts with provenance. **MVP-2 Track 4 DONE**: `agent-registry.yaml`, `chat-agent-resolver.py`, `chat:select_agent` RBAC, delegation hold, tool allowlist BLOCK, Control Panel agent picker, CODEGEN draft-only through `artifact-scan` + Plan-17 loop certification. **MVP-2 OPERATOR Track 5/6 DONE**: `chat-turn.py` certifies UNCERTIFIED draft through Plan-17 `loop-run.sh` + trace verify/replay before side-effect release. **Track 8.1/8.2 DONE**: `chat-replay.py` verifies chat chain, evidence artifact hash, and OPERATOR/CODEGEN loop replay; Control Panel `GET /api/v1/chat/replay`. **Track 8.3 DONE**: Command Center `chat_loop` widget reads chat audit/replay evidence, loop ticker, budget gauge, and click-through evidence drawer. **Track 8.4 DONE**: `REQUIRES_APPROVAL` chat turns become pending `chat.escalate` approvals, SoD/reason enforced, strict/fake JWT denied before mutation. **Track 9 DONE**: non-default tenant chat state is partitioned by `tenant-store.sh`, explicit cross-tenant replay paths are denied, encrypted audit snapshots are written via `tenant-crypt.sh`, tenant kill-switch/quota are isolated. Test: chat suites **59/0** (`phase-chat-prompt-router` 9/0, `phase-chat-readonly` 5/0, `phase-chat-session-audit` 3/0, `phase-chat-operator` 8/0, `phase-chat-agent-select` 8/0, `phase-chat-pipeline` 4/0, `phase-chat-stream-hold` 2/0, `phase-chat-replay` 4/0, `phase-chat-approval` 4/0, `phase-chat-codegen` 4/0, `phase-chat-tenant` 8/0), Control Panel **29/0** + build xanh. **Track M (2026-07-09) DONE**: model-optional grounded synthesis — read-only Ask CASAN tổng hợp câu trả lời tự nhiên có citations qua `model-router.sh` khi `CASAN_CHAT_MODEL_MODE=model` (config `model-providers.yaml`), offline-first (mặc định deterministic), fail-safe fallback, cloud→ép preflight PII-guard, model output vẫn qua H4 (secret→DENY), H6 real token/cost. `phase-chat-model-synthesis` **7/0** (chat suites **66/0**), nối `ci-harness-gate.sh`, UI badge model/deterministic. **Uplift items 1–5 (2026-07-09b) DONE**: (1) ANALYSIS mode reasoning/compare; (2) multi-turn memory per-chat/tenant nén Plan-08; (3) streaming draft UNCERTIFIED→final (API `/chat/ask/stream` + UI toggle); (4) CODEGEN full model-router draft (artifact-scan + loop-cert); (5) `chat-cloud-smoke.sh` (SKIP nếu thiếu key). `phase-chat-advanced` **8/0**, chat suites **74/0**. Còn: cloud live-smoke với key thật; token-level SSE (hiện 2-pha). |
| **19 Harness Reporting** | ✅ **H6 done+test** | H1–H7 dùng chung report contract; H6 có JSON API, standalone HTML/JSON export, filter project/run/time, freshness/data-quality và evidence-derived verdict. H1–H5/H7 hiện `contract_ready`, chưa được đánh đồng với report đã implement. |
| **20 Agentic Client Integration** | 🔬 **spike GO có điều kiện / implementation chưa bắt đầu** | Làm theo wave bắt buộc: common admission bridge → Claude Code hooks + Windows acceptance → Codex project/managed hooks → black-box Claude/Codex VS Code extension → optional `@casan` Chat Participant. Bất biến: bridge không gọi model lần hai; turn thiếu admission/finalize là non-certified; H6 phải hiển thị certification strength và telemetry quality. Bước tiếp theo: chạy Claude cases C1–C12 trong `CASAN_SPIKE_20_AGENTIC_CLIENT_HOOKS.md`; chỉ bắt đầu Codex sau Claude exit gate. |
## Production-enterprise preparation (P2)
+6 -1
View File
@@ -1,6 +1,6 @@
# CASAN — Mục lục Plan
> Cập nhật: 2026-07-08. File này là **mục lục thuần** cho bộ plan CASAN. Trạng thái
> Cập nhật: 2026-07-22. File này là **mục lục thuần** cho bộ plan CASAN. Trạng thái
> chi tiết **không** lặp ở đây để tránh lệch: "còn gì phải làm" xem
> `CASAN_BACKLOG_STATUS.md` (có legend nhãn chuẩn); "control nào đã implement+test"
> xem `CASAN_HARDENING_STATUS.md`. Ba file phân vai rõ, một sự thật ghi một nơi.
@@ -36,6 +36,8 @@
| 16 | `CASAN_PLAN_16_SECURITY_AUDIT_REMEDIATION.md` | Security audit core harness + kế hoạch vá (tamper-evidence/injection/fail-open) | � P0/P1/P2 done |
| 17 | `CASAN_PLAN_17_LOOP_ENGINEERING.md` | Loop Engineering / Agentic Loop Governance (budget governor, convergence, verify-contract, loop trace/replay, meta-loop) | 📋 |
| 18 | `CASAN_PLAN_18_CHAT_CONSOLE.md` | Governed Chat Console (MVP-0 Ask CASAN + MVP-1 Operator + MVP-2 Chat-as-Loop/Agent/Replay + MVP-3 multi-tenant) | ✅ done+test |
| 19 | `CASAN_PLAN_19_HARNESS_REPORTING.md` | H1–H7 reporting contract + H6 JSON/HTML report | ✅ H6 done+test |
| 20 | `CASAN_PLAN_20_AGENTIC_CLIENT_INTEGRATION.md` | Gõ prompt native qua CASAN: Claude Code → Codex → VS Code | 🔬 spike GO có điều kiện / 📋 implementation |
| Future | `CASAN_PLAN_FUTURE_PHASES.md` | Approval workflow, state machine, benchmark, memory, remediation, KPI | 💤 vision |
> **Không có plan số 11:** số 11 được bỏ trống có chủ ý — nhánh eval/traceability đã
@@ -89,6 +91,9 @@ flowchart LR
P17 --> P18["18 Chat Console<br/>chat = governed loop-run"]
P13 --> P18
P14 --> P18
P18 --> P20["20 Agentic clients<br/>Claude → Codex → VS Code"]
P19["19 Harness reports<br/>H6 HTML/JSON"] --> P20
P07T2 --> P20
style CORE fill:#d0e8ff,stroke:#2c3e91,stroke-width:2px
style STRONG fill:#d0ffd0,stroke:#1e8449,stroke-width:2px
```
@@ -0,0 +1,295 @@
# CASAN Plan-20 — Transparent Agentic Client Integration
> Ngày lập: 2026-07-22
> Trạng thái: **PLAN — thực hiện sau khi Spike-20 đạt exit gate**
> Thứ tự bắt buộc: **Claude Code → Codex → Claude/Codex trên VS Code**
Kết quả khảo sát và test matrix: [CASAN Spike-20](../spikes/CASAN_SPIKE_20_AGENTIC_CLIENT_HOOKS.md).
## 1. Mục tiêu
Cho phép developer gõ prompt bình thường trong agentic coding client mà không phải chạy
`bin/casan-chat`, nhưng mọi kết quả được CASAN chứng nhận vẫn phải có trace H1→H7 đầy đủ.
Trải nghiệm đích:
1. Member mở project trong Claude Code, Codex hoặc client VS Code được hỗ trợ.
2. Member gõ prompt như bình thường.
3. CASAN mở một admission/trace cho turn đó trước khi agent được phép tạo side effect.
4. Mọi tool call có tác động được CASAN kiểm tra và ghi evidence.
5. Khi turn kết thúc, CASAN finalize H3–H7 và H6 hiển thị runtime/token/cost/failure cùng
nguồn và chất lượng của số liệu.
6. Turn không có admission hợp lệ hoặc không finalize được **không được gắn nhãn certified**.
## 2. Phạm vi và giới hạn cam kết
### Trong phạm vi
- Claude Code CLI/native UI, triển khai đầu tiên bằng lifecycle hooks.
- Codex CLI/IDE host, triển khai sau khi Claude Code đạt gate.
- Claude Code và Codex extension trên VS Code, nếu thực nghiệm xác nhận extension dùng cùng
project hooks với CLI.
- Một CASAN Chat Participant riêng cho VS Code/Copilot nếu cần tuyến chat do CASAN sở hữu.
- Cài đặt và tài liệu cho Windows PowerShell, macOS/Linux.
- Mapping turn/session/client vào trace H1→H7 và H6 report.
### Ngoài phạm vi Plan-20
- Chặn prompt trong mọi AI extension bất kỳ của bên thứ ba.
- Khẳng định project hook là security boundary tuyệt đối khi user có thể sửa/tắt cấu hình.
- Gọi model lần thứ hai từ hook để “chạy lại qua CASAN”.
- Thay đổi core semantics H1→H7 hoặc cài thêm thư viện runtime.
## 3. Nguyên tắc kiến trúc
### 3.1 Không chạy model hai lần
`chat-turn.py ask` hiện là đường CASAN sở hữu cả model execution. Native adapter **không**
được gọi lệnh này rồi để Claude/Codex tiếp tục xử lý cùng prompt, vì sẽ tạo hai lượt model,
hai chi phí và hai kết quả cạnh tranh.
Plan-20 thêm một lifecycle bridge chỉ làm admission, policy, evidence và finalize:
```mermaid
sequenceDiagram
actor U as Developer
participant C as Claude/Codex/VS Code
participant B as CASAN Agentic Bridge
participant H as H1-H7 Harness
participant M as Native Model
U->>C: Prompt bình thường
C->>B: begin(prompt, client, session)
B->>H: H1 context + H4 security admission
H-->>B: admission_id + trace_id hoặc block
B-->>C: allow/context hoặc block
C->>M: Native model execution (một lần)
loop Mỗi tool call
C->>B: pre-tool(admission_id, tool, input)
B->>H: H2/H4/H5 policy gate
H-->>C: allow/deny
C->>B: post-tool(result, duration)
B->>H: append evidence
end
C->>B: finalize(last message, outcome)
B->>H: H3/H5/H7 + H6 telemetry
H-->>C: certified / non-certified
```
### 3.2 Certification strength phải hiển thị công khai
Mỗi trace native có `integration_mode` và `certification_strength`:
| Strength | Ý nghĩa | Cam kết |
|---|---|---|
| `casan_owned` | Launcher/SDK/Chat Participant do CASAN điều khiển toàn vòng đời | Mạnh nhất trong local client |
| `managed_hook` | Hook/policy được tổ chức pin và user thường không thể tắt | Guardrail tổ chức |
| `project_hook` | Hook được commit trong repo và user trust project | Guardrail theo project, có thể bị bypass bởi người có quyền sửa cấu hình |
| `observed_only` | Chỉ thu telemetry, không đủ tool/admission gate | Không certified |
UI và export H6 không được gom bốn mức trên thành một nhãn `pass` duy nhất.
### 3.3 Fail-closed ở điểm tạo side effect
Hook nhận prompt có thể có giới hạn fail-open của client. Vì vậy điều kiện tối thiểu để một
turn được certified là:
- có `admission_id` hợp lệ, ngắn hạn và gắn với project/session/turn;
- mọi tool side-effect được hỗ trợ phải qua `pre-tool`;
- tool bị từ chối khi không có admission hoặc bridge không phản hồi trong internal timeout;
- `finalize` chỉ chứng nhận evidence thực sự quan sát được;
- hook timeout/error được ghi là failure, không tự suy diễn các H downstream đã pass.
Absolute enforcement cần `casan_owned` hoặc cấu hình `managed_hook`; Plan-20 không quảng bá
`project_hook` như một sandbox tuyệt đối.
## 4. Agentic bridge dùng chung
Thêm executable Python stdlib-only trong `packages/casan-harness` với các operation:
| Operation | Input chính | Output/side effect |
|---|---|---|
| `begin` | client, project, session, prompt | scan H1/H4, tạo trace/admission, trả client-native allow/block JSON |
| `pre-tool` | admission, tool name/input | H2/H4/H5 decision, allow/deny/update input nếu client hỗ trợ |
| `post-tool` | tool result/status/duration | append evidence đã redact |
| `telemetry` | model, runtime, token/cost fields | ghi H6 cùng provenance và data quality |
| `finalize` | stop reason, assistant summary, changed files | chạy verify/final controls và đóng trace |
| `abort` | failure/interruption reason | đóng trace non-certified, phát failure telemetry |
### State contract
- State nằm dưới `.specify/state/agentic-sessions/`, dùng atomic write và file lock hiện có.
- Không dùng raw prompt làm key; dùng hash + opaque `turn_id`.
- Admission có TTL, project root canonical và client/session binding.
- Không ghi secret, credential hoặc toàn bộ tool output vào audit log.
- Hook response renderer tách theo adapter; core bridge không phụ thuộc Claude/Codex JSON.
- Mọi record có `schema_version`, `trace_id`, `project_id`, `client`, `client_version`,
`integration_mode`, `certification_strength`, `occurred_at`.
## 5. H6 cho native agentic client
H6 cần bổ sung các field sau nhưng vẫn giữ tương thích schema hiện tại:
| Nhóm | Field |
|---|---|
| Client | `client`, `client_version`, `adapter_version`, `integration_mode` |
| Identity | `client_session_id_hash`, `client_turn_id_hash`, `trace_id` |
| Runtime | `started_at`, `finished_at`, `duration_ms`, `tool_calls`, `failures`, `retries` |
| Usage | input/output/cache token nếu client cung cấp |
| Cost | amount, currency, `cost_source`, estimated/provider-reported |
| Quality | `telemetry_quality=complete|partial|insufficient`, warnings, missing fields |
| Trust | `certification_strength`, hook trust/policy mode, bypass/fallback signal |
Quy tắc:
- Không biến dữ liệu thiếu thành `0`.
- Token/cost không có nguồn chính xác phải là `null` kèm warning.
- Claude status-line estimate và session delta phải ghi rõ provenance; không gọi là
provider-reported.
- Codex usage/cost chỉ được gắn `complete` sau khi spike chứng minh nguồn lifecycle ổn định.
- H6 report cho phép filter theo `client`, `integration_mode`, `trace_id` và project.
## 6. Kế hoạch thực hiện theo wave
### Wave 0 — Common contract và fixtures
| ID | Việc | Deliverable | Gate |
|---|---|---|---|
| 20.0.1 | Chốt JSON lifecycle contract | schema + fixtures begin/pre/post/finalize | invalid payload fail rõ ràng |
| 20.0.2 | Implement bridge state machine | script + atomic state | replay/expired/cross-project admission bị chặn |
| 20.0.3 | Nối evidence H1→H7 | trace writer dùng contract hiện có | không phát evidence downstream giả |
| 20.0.4 | Mở rộng H6 provenance | writer/report/UI/export | thiếu token/cost hiển thị partial, không thành 0 |
| 20.0.5 | Threat tests | tamper, timeout, bypass, injection | security suite xanh |
### Wave 1 — Claude Code spike và MVP
Thực hiện trước mọi code Codex/VS Code.
| ID | Việc | Deliverable | Gate |
|---|---|---|---|
| 20.1.1 | Prototype `UserPromptSubmit` → `begin` | `.claude/settings.json` fixture + command hook | prompt allow/block đúng |
| 20.1.2 | Prototype `PreToolUse`/`PostToolUse` | tool adapter | side effect thiếu admission bị deny |
| 20.1.3 | Prototype `Stop`/failure | finalize/abort adapter | trace đóng đúng, không vòng lặp stop |
| 20.1.4 | Telemetry experiment | status-line/session correlation | H6 ghi provenance + quality đúng |
| 20.1.5 | Windows installer | PowerShell install/doctor/uninstall | clean Windows clone chạy được |
| 20.1.6 | Claude acceptance suite | fixture + black-box test | exit gate mục 8 đạt |
Project config được commit; secret và machine-specific path không được commit. Hook command
phải tự resolve repo root và gọi interpreter có sẵn trong CASAN distribution.
### Wave 2 — Claude Code hardening và rollout nhỏ
- Internal timeout ngắn hơn outer hook timeout; mọi timeout tạo H6 failure.
- PreToolUse deny side effect khi admission thiếu/expired.
- Doctor kiểm tra hook loaded, project trust, bridge version và log permissions.
- Pilot với ít nhất Windows PowerShell và macOS/Linux.
- Tài liệu nêu rõ project-hook vs managed-hook.
- Chỉ chuyển sang Codex khi Claude exit gate xanh và có rollback test.
### Wave 3 — Codex spike và MVP
| ID | Việc | Deliverable | Gate |
|---|---|---|---|
| 20.3.1 | Map Codex lifecycle payload | fixtures cho UserPromptSubmit/Pre/Post/Stop | contract mapping đầy đủ |
| 20.3.2 | Project hook adapter | `.codex/hooks.json` + `.codex/config.toml` | trust onboarding rõ ràng |
| 20.3.3 | Managed policy path | requirements/MDM guide | pin hook và chống disable được chứng minh |
| 20.3.4 | Tool coverage audit | coverage matrix | tool ngoài coverage bị ghi warning/non-certified |
| 20.3.5 | H6 usage experiment | stable source hoặc partial contract | không suy diễn token/cost |
| 20.3.6 | Windows acceptance | install/doctor/normal prompt | cùng behavior với Claude MVP |
Codex tool hooks là guardrail chứ không được xem là coverage tuyệt đối cho hosted/specialized
tools. Certification phải hạ cấp khi một turn dùng tool mà adapter không quan sát được.
### Wave 4 — VS Code và extension
Thực hiện theo ba tuyến riêng, không gom thành một tuyên bố “mọi plugin”:
1. **Claude Code extension:** black-box test xem project `.claude/settings.json` và hooks có
chạy trong extension host hay không.
2. **Codex IDE extension:** black-box test xem `.codex/hooks.json`, trust và managed policy
có giống CLI hay không.
3. **VS Code/Copilot generic:** tạo `@casan` Chat Participant nếu cần một UI do CASAN sở hữu.
Participant detection chỉ là auto-route best effort; built-in participant có thể được ưu
tiên nên không được quảng bá là chặn mọi prompt Copilot mặc định.
Mỗi tuyến có capability badge riêng trong H6: `verified`, `partial`, `unsupported`.
### Wave 5 — Adoption, reporting và release
- Update `packages/casan-devkit` để cài config/hook theo client được chọn.
- Thêm `casan doctor --client claude|codex|vscode` và smoke command.
- Update hướng dẫn Windows từ clone sạch, không yêu cầu người dùng copy file thủ công.
- H6 UI drill-down từ client session → trace → H1–H7 evidence.
- Release notes liệt kê client/version đã test và limitation còn lại.
- Pilot ≥ 2 project, trong đó có project Basic Design lớn trên Windows.
## 7. Definition of Done
Một client chỉ được ghi là `supported` khi:
- gõ prompt bình thường tạo đúng một native model execution và một CASAN trace;
- prompt bị policy block không tới model theo capability thực tế của client;
- side-effect tool thiếu admission bị từ chối trong coverage đã công bố;
- allow, deny, timeout, interruption và hook crash đều có automated test;
- H6 hiển thị client/runtime/failure và token/cost theo đúng data quality;
- H1→H7 evidence truy ngược được từ cùng `trace_id`;
- Windows install, doctor, uninstall và restart đã chạy trên clean clone;
- bypass limitation được ghi trong UI/docs, không dùng từ “bắt buộc tuyệt đối” sai mức;
- core harness regression suite vẫn xanh.
## 8. Exit gate theo giai đoạn
### Claude Code GO để bắt đầu Codex
- 100% test lifecycle fixtures pass.
- 100% side-effect test trong published coverage bị deny khi thiếu admission.
- Không có double model execution.
- Timeout/hook failure tạo non-certified trace và H6 failure.
- Windows + macOS/Linux smoke pass.
- H6 HTML/JSON thể hiện `project_hook` hoặc `managed_hook` và telemetry quality.
### Codex GO để bắt đầu VS Code
- Project trust onboarding có test và doctor diagnostic.
- Managed hook path có tài liệu/policy test.
- Tool coverage matrix được machine-readable và phản ánh trong certification.
- Token/cost source được chứng minh hoặc để `partial`, không giả số.
### VS Code release gate
- Mỗi extension/version có black-box evidence độc lập.
- `@casan` participant được mô tả là CASAN-owned route; participant detection không được
dùng làm bằng chứng interception tuyệt đối.
- Unsupported extension không được hiện `certified`.
## 9. Rollout và rollback
- Feature flags: `CASAN_AGENTIC_BRIDGE_ENABLED`, `CASAN_AGENTIC_ENFORCEMENT_MODE` và client
allowlist.
- Bắt đầu `observe`, sau đó `enforce` trong pilot; production default chỉ đổi sau exit gate.
- Mỗi installer lưu manifest file đã tạo để uninstall không xóa config của user.
- Rollback chỉ tắt adapter; `bin/casan-chat` và core H1→H7 hiện tại vẫn hoạt động.
- Trace sinh trong observe mode luôn mang `observed_only`, không retroactively certified.
## 10. Deliverable dự kiến
```text
packages/casan-harness/
scripts/python/agentic_bridge.py
adapters/claude-code/
adapters/codex/
schemas/agentic-lifecycle.schema.json
tests/phase-agentic-bridge-tests.sh
packages/casan-devkit/
templates/claude/
templates/codex/
windows/install-agentic.ps1
docs/casan/
CASAN_AGENTIC_CLIENTS_WINDOWS.md
CASAN_AGENTIC_CLIENT_SECURITY.md
docs/spikes/
CASAN_SPIKE_20_AGENTIC_CLIENT_HOOKS.md
```
Tên/file cụ thể có thể điều chỉnh sau Spike-20, nhưng lifecycle contract, single-model
invariant và certification strength là quyết định kiến trúc bắt buộc.
@@ -0,0 +1,252 @@
# 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](../plans/CASAN_PLAN_20_AGENTIC_CLIENT_INTEGRATION.md).
## 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/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:
- `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 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 `@casan` Chat 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
```text
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
```mermaid
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. **VS Code:** xác minh native Claude/Codex extension riêng; bổ sung `@casan` participant
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](https://code.claude.com/docs/en/hooks)
- [Claude Code status line](https://code.claude.com/docs/en/statusline)
- [Claude Agent SDK cost tracking](https://code.claude.com/docs/en/agent-sdk/cost-tracking)
- [Codex hooks](https://learn.chatgpt.com/docs/hooks)
- [VS Code Chat Participant API](https://code.visualstudio.com/api/extension-guides/ai/chat)
- [VS Code Language Model Chat Provider](https://code.visualstudio.com/api/extension-guides/ai/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`.