@@ -1,7 +1,13 @@
# KẾ HOẠCH 18 — Governed Chat Console (Chat-as-Loop qua Control Plane)
> Status 2026-07-07 : **📋 planned — CHƯA implement.** Plan thiết kế; không có code
> trong đợt này. Mục tiêu: thêm **cửa sổ chat** vào Control Plane (Plan-13) như một
> Status 2026-07-08 : **🟡 MVP-0 + MVP-1 done+test — target architecture còn planned.**
> Đã implement **Ask CASAN — Read-only Evidence Assistant** qua harness + Control
> Panel (`/api/v1/chat/ask`, `/chat` UI): Prompt Router deterministic
> `READ_ONLY/OPERATOR/BLOCK/NOT_SUPPORTED`, context whitelist, H4 scan in/out, H5
> chat audit hash-chain, H6 token telemetry, answer kèm evidence sources. **MVP-1
> Operator** đã có registered actions `run tests` / `build pack` / `verify pack`
> qua `action-gate`, không free-command, kết quả có artifact provenance. Mục tiêu
> tổng thể vẫn là thêm **cửa sổ chat** vào Control Plane (Plan-13) như một
> **bề mặt tương tác của core harness** — mỗi lượt chat là **một loop-run được
> governance** (Plan-17), đi qua đúng H1→H7, không có đường vòng. Đây **không** phải
> một chatbot; nó là **governed agent console**.
@@ -204,27 +210,27 @@ flowchart TD
### Track 0 — Prompt Mode Router `[MVP-0 rút gọn → đầy đủ ở MVP-1/2]`
| Task | Việc | File | Verify (WSL) |
|---|---|---|---|
| 18.0.1 | Định nghĩa modes + policy map `mode→gate/mức` (READ_ONLY/ANALYSIS/OPERATOR/CODEGEN/ADMIN /BLOCK/NOT_SUPPORTED) | mới `config/prompt-modes.yaml` | schema validate; thiếu policy → BLOCK |
| 18.0.2 | Classifier **deterministic ** : requested-capabilities + denied-verbs + bypass-terms | mới `prompt-mode-router.py` | `rm -rf` / `deploy` → OPERATOR/BLOCK, không READ_ONLY |
| 18.0.3 | Model-assisted **chỉ cho ca mơ hồ ** (optional, skip-aware) | cùng file | không model → vẫn phân loại bằng rule |
| 18.0.4 | **Rule thắng model ** khi rule rủi ro cao hơn | cùng file | model=READ_ONLY + rule=OPERATOR → giữ OPERATOR |
| 18.0.5 | Preview `{mode, risk, gates, needs_approval}` cho UI | cùng file | payload đúng cho từng mode |
| 18.0.6 | Audit kết quả phân loại vào H5 ( fail-closed: lỗi → BLOCK) | nối audit | router lỗi → BLOCK + audit |
| 18.0.1 | ✅ Định nghĩa modes + policy map `READ_ONLY/OPERATOR /BLOCK/NOT_SUPPORTED` | `packages/casan-harness/ config/prompt-modes.yaml` | schema validate; thiếu/corrupt policy → BLOCK |
| 18.0.2 | ✅ Classifier **deterministic ** : requested-capabilities + denied-verbs + bypass-terms | `packages/casan-harness/scripts/bash/prompt-mode-router.py` | `rm -rf` /injection → BLOCK; `deploy` → NOT_SUPPORTED |
| 18.0.3 | ✅ Model-assisted **skip-aware ** ; MVP-0 không cần model | cùng file | không model → vẫn phân loại bằng rule |
| 18.0.4 | ✅ **Rule thắng model ** khi rule rủi ro cao hơn | cùng file | model=READ_ONLY + rule=BLOCK/NOT_SUPPORTED → giữ rule |
| 18.0.5 | ✅ Preview `{mode, risk, gates, needs_approval}` cho UI | cùng file | payload đúng cho từng mode |
| 18.0.6 | ✅ Kết quả router được ghi trong ChatTurn H5; fail-closed lỗi policy → BLOCK | `chat-readonly.py` | router lỗi → BLOCK + audit turn |
### Track 1 — Read-only Ask CASAN (Evidence Assistant) `[MVP-0]`
| Task | Việc | File | Verify (WSL) |
|---|---|---|---|
| 18.1.1 | Context **whitelist ** : Evidence Pack + reports + docs (đọc-only, chặn path ngoài whitelist) | mới `chat-contex t-readonly.sh ` | hỏi ngoài whitelist → không lộ |
| 18.1.2 | Trả lời **kèm nguồn ** (`answer + sources[]` , provenance envelope) | cùng file | mỗi câu trả lời có ≥1 source ref |
| 18.1.3 | H4 scan **input + output ** ; H6 token tracking mỗi lượt | nối H4/H6 | injection → DENY; token ghi H6 |
| 18.1.4 | Cấm tuyệt đối side-effect ở mode này (no command/no write/no skill) | guard | thử exec ở READ_ONLY → BLOCK |
| 18.1.1 | ✅ Context **whitelist ** : Evidence Pack + reports + docs (đọc-only, chặn path ngoài whitelist) | `packages/casan-harness/scripts/bash/cha t-readonly.py ` | hỏi ngoài whitelist → không lộ |
| 18.1.2 | ✅ Trả lời **kèm nguồn ** (`answer + sources[]` , provenance envelope) | cùng file | mỗi câu trả lời có ≥1 source ref |
| 18.1.3 | ✅ H4 scan **input + output ** ; H6 token tracking mỗi lượt | nối `security-check.sh` + metrics jsonl | injection → DENY; token ghi H6 |
| 18.1.4 | ✅ Cấm tuyệt đối side-effect ở mode này (no command/no write/no skill) | router guard | side-effect → NOT_SUPPORTED/ BLOCK |
### Track 2 — Chat session + audit trace `[MVP-0]`
| Task | Việc | File | Verify (WSL) |
|---|---|---|---|
| 18.2.1 | Schema phiên `chat_id/turn_id/actor` (tenant-ready; MVP-0 single-tenant OK) | mới `config/chat-session.schema.json` | schema validate |
| 18.2.2 | Ghi `ChatTurn` (§3) append-only, hash-linked H5 (không nhúng PII/secret, chỉ `*_ref` ) | nối H5 audit | N turn → chain liên tục; secret không lộ |
| 18.2.3 | PII mask trước khi lưu (nối `pii-mask.py` /RAI Plan-15) | nối `rai-guard.py` | msg có PII → audit đã mask |
| 18.2.1 | ✅ Schema phiên `chat_id/turn_id/actor` (tenant-ready; MVP-0 single-tenant OK) | `packages/casan-harness/ config/chat-session.schema.json` | schema validate |
| 18.2.2 | ✅ Ghi `ChatTurn` (§3) append-only, hash-linked H5 (không nhúng PII/secret, chỉ hash/ref/preview) | `chat-readonly.py verify- audit` | N turn → chain liên tục; secret không lộ |
| 18.2.3 | ✅ Không lưu raw message; audit lưu hash/ref/preview đã scan | cùng file | msg có secret token → audit không lộ raw secret |
### Track M — Model Provider Binding `[MVP-0 tối thiểu → lớn dần]`
| Task | Việc | File | Verify (WSL) |
@@ -237,9 +243,9 @@ flowchart TD
### Track 3 — Operator mode (registered actions) `[MVP-1]`
| Task | Việc | File | Verify (WSL) |
|---|---|---|---|
| 18.3.1 | Whitelist hành động: `run tests` / `build pack` / `verify pack` (đăng ký, **không ** free-command) | mới `config/operator-actions.yaml` | lệnh ngoài whitelist → DENY |
| 18.3.2 | Mỗi action qua `action-gate` (ALLOW/WARN/REQUIRE_APPROVAL/BLOCK) | nối `action-gate.sh` | destructive → REQUIRE_APPROVAL |
| 18.3.3 | Kết quả action là artifact có provenance, hiển thị lại trong chat | cùng | action → evidence link |
| 18.3.1 | ✅ Whitelist hành động: `run tests` / `build pack` / `verify pack` (đăng ký, **không ** free-command) | `packages/casan-harness/ config/operator-actions.yaml` | lệnh ngoài whitelist → DENY |
| 18.3.2 | ✅ Mỗi action qua `action-gate` (ALLOW/WARN/REQUIRE_APPROVAL/BLOCK) | `chat-operator.py` + `action-gate.sh` | dangerous → BLOCK; network → REQUIRE_APPROVAL |
| 18.3.3 | ✅ Kết quả action là artifact có provenance, hiển thị lại trong chat | `chat-operator.py` + `/chat` UI | action → evidence link |
### Track 4 — Agent/Skill selection governance `[MVP-2]`
| Task | Việc | File | Verify (WSL) |
@@ -266,8 +272,8 @@ flowchart TD
### Track 7 — Chat API (NestJS) + UI (React) trên Command Center `[MVP-0 tối thiểu → lớn dần]`
| Task | Việc | File | Verify |
|---|---|---|---|
| 18.7.1 | Chat API (NestJS) **bọc ** harness (MVP-0: endpoint read-only ; single-source, không verdict riêng) | `control-pl ane/` (sau 01 → `packages/ `) | API chỉ gọi harness |
| 18.7.2 | Chat panel React + hiển thị **evidence sources ** + badge `mode/risk` (Prompt Router preview) | Control Plane UI | render nguồn + mode đúng |
| 18.7.1 | ✅ Chat API (NestJS) **bọc ** harness (MVP-0/1: read-only + operator ; single-source, không verdict riêng) | `packages/casan- control-panel/backend/src/chat/* ` | API gọi `chat-turn.py` ; `console:test` xanh |
| 18.7.2 | ✅ Chat panel React + hiển thị **evidence sources ** , registered actions, action-gate + badge `mode/risk` | `packages/casan-control-panel/frontend/src/pages/Chat.tsx` | `console:build` xanh |
| 18.7.3 | (MVP-2) agent/skill picker theo RBAC + badge `UNCERTIFIED/CERTIFIED` + nút **loop-breaker ** + delegation-level | Control Plane UI | picker ẩn agent ngoài quyền |
| 18.7.4 | Fail-loud: API/telemetry chết → UI `STALE/503` (tái dùng D3 `/healthz` ) | nối Plan-07 D3 | ngắt backend → UI báo stale |
@@ -318,11 +324,17 @@ cập nhật tổng test ở `CASAN_HARDENING_STATUS.md`.
## 6. Tiêu chí hoàn thành (Definition of Done)
**MVP-0 (Ask CASAN read-only) — cổng ship đầu tiên: **
- [ ] Prompt Router phân loại `READ_ONLY/BLOCK/NOT_SUPPORTED` deterministic; **rule thắng model ** ; router lỗi → BLOCK.
- [ ] Chat chỉ đọc **whitelist ** ; hỏi ngoài whitelist không lộ; **không ** command/write/skill.
- [ ] H4 scan input+output; H5 audit mỗi lượt; H6 token tracking; PII→cloud chặn qua C3 .
- [ ] Trả lời **kèm ≥1 nguồn evidence ** ; UI hiện sources + badge mode/risk.
- [ ] Suite MVP-0 xanh trong WSL, nối CI; không đụng OKR app.
- [x ] Prompt Router phân loại `READ_ONLY/BLOCK/NOT_SUPPORTED` deterministic; **rule thắng model ** ; router lỗi → BLOCK.
- [x ] Chat chỉ đọc **whitelist ** ; hỏi ngoài whitelist không lộ; **không ** command/write/skill.
- [x ] H4 scan input+output; H5 audit mỗi lượt; H6 token tracking. PII→cloud full provider policy vẫn thuộc Track M/Plan-15 khi bật model provider thật .
- [x ] Trả lời **kèm ≥1 nguồn evidence ** ; UI hiện sources + badge mode/risk.
- [x ] Suite MVP-0 xanh và nối CI; không đụng OKR app. Verify: `phase-chat-prompt-router` 6/0, `phase-chat-readonly` 5/0, `phase-chat-session-audit` 3/0, `console:test` 23/0, `console:build` xanh.
**MVP-1 (Operator registered actions): **
- [x] Registered action whitelist có `run-chat-tests` , `build-evidence-pack` , `verify-evidence-pack` ; không chạy free-command.
- [x] Mọi action đi qua `action-gate` ; BLOCK/REQUIRE_APPROVAL không thực thi command.
- [x] Kết quả action ghi artifact có provenance và được hiển thị lại trong `/chat` .
- [x] Suite MVP-1 xanh và nối CI. Verify: `phase-chat-operator` 8/0, prompt-router 8/0, read-only 5/0, session-audit 3/0, `console:test` 24/0, `console:build` xanh.
**Full (target architecture) — DoD tổng: **
- [ ] Turn chạy **đúng như một loop-run Plan-17 ** (không định nghĩa vòng lặp riêng).
@@ -337,7 +349,9 @@ cập nhật tổng test ở `CASAN_HARDENING_STATUS.md`.
---
## 7. Ghi chú trung thực & Non-goals (không lan man)
- **[mới] — 📋 chưa implement.** Plan mô tả thiết kế; chưa viết script trong đợt này.
- **[MVP-0 + MVP-1] — 🟡 done+test.** Ask CASAN read-only và Operator registered
actions đã có harness CLI + Control Panel API/UI. Các phase Chat-as-loop /
Agent-selection / multi-tenant production vẫn chưa mở.
- **MVP-first (chống lan man):** **MVP-0 (Ask CASAN read-only) KHÔNG phụ thuộc Plan-17/
14/SEC-23** — làm được ngay trên nền H4/H5/H6 hiện có. Chỉ **MVP-2 trở đi ** (chat-as-
loop + agent) mới cần Plan-17 (T1– T3) + Plan-14 RBAC; **MVP-3 ** mới cần SEC-23 tenant.