Published on

Day 04 - Permission modes và an toàn khi cho AI sửa code

Authors

1. Mục tiêu bài học

Sau khoảng 2 tiếng, học viên có thể:

  • Giải thích được permission mode trong Claude Code là gì và vì sao nó là guardrail quan trọng khi AI có quyền đọc file, sửa file, và chạy lệnh.
  • Chọn đúng chế độ default, plan, acceptEdits, auto, dontAsk, hoặc bypassPermissions theo mức rủi ro của task.
  • Thiết kế workflow plan-first: yêu cầu Claude Code khảo sát, lập plan, xin xác nhận, rồi mới sửa code.
  • Cho phép Claude Code sửa một file nhỏ trong project taskflow-ai và review diff trước khi accept hoặc commit.
  • Nhận diện rủi ro của auto-approve command, đặc biệt với lệnh destructive như xóa file, reset Git, migration phá dữ liệu, hoặc thao tác production data.

2. Bối cảnh thực tế

Khi dùng Claude Code, developer không chỉ hỏi đáp với chatbot. Claude Code có thể đọc repo, đề xuất patch, chỉnh file, và chạy command trong terminal. Đây là điểm mạnh, nhưng cũng là điểm làm tăng rủi ro: một prompt mơ hồ có thể dẫn tới thay đổi rộng, chạy test tốn thời gian, sửa nhầm file, hoặc thực thi command không nên chạy.

Trong project taskflow-ai, giả sử bạn đang muốn thêm validation nhỏ cho task title. Nếu cho AI quyền sửa toàn repo ngay từ đầu, nó có thể đổi schema, đổi API contract, hoặc viết lại module tasks quá rộng. Workflow tốt hơn là yêu cầu Claude Code đọc file liên quan trong plan mode, trình bày plan, sau đó chỉ cho phép sửa đúng một file nhỏ.

Không nên dùng Claude Code để tự động sửa khi:

  • Bạn đang làm việc trên branch có thay đổi chưa commit mà chưa hiểu rõ trạng thái.
  • Task liên quan tới production credential, dữ liệu thật, migration nguy hiểm, billing, hoặc auth/security boundary.
  • Bạn chưa có test hoặc chưa biết cách verify behavior sau khi sửa.
  • Bạn cần quyết định kiến trúc lớn nhưng chưa thống nhất acceptance criteria với team.

3. Kiến thức nền

Permission mode là cách Claude Code quyết định tool call nào được chạy ngay, tool call nào cần hỏi bạn, và tool call nào bị từ chối. Tool call có thể là đọc file, sửa file, chạy shell command, dùng MCP tool, hoặc thao tác filesystem.

Các mode cần nhớ:

ModeÝ nghĩaKhi nên dùngRủi ro chính
defaultHỏi quyền khi tool được dùng lần đầu hoặc khi cần xác nhận.Học hằng ngày, task chưa rõ phạm vi, repo cá nhân hoặc team repo.Dễ bấm approve theo thói quen nếu không đọc kỹ.
planCho phép đọc file và chạy shell lệnh read-only để khảo sát, không sửa code.Bắt đầu mọi task có rủi ro: refactor, bug fix, migration, security.Plan có thể thiếu file nếu prompt không yêu cầu Claude chỉ rõ bằng chứng.
acceptEditsTự approve file edits và một số command filesystem phổ biến trong working directory.Task nhỏ, file rõ, branch sạch, đã có test, đang trong sandbox/dev repo.AI có thể sửa/tạo/di chuyển file nhiều hơn mong muốn nếu prompt không giới hạn.
autoTự approve theo safety checks nền; docs hiện hành mô tả đây là research preview.Task lặp lại, repo đã có guardrails, môi trường dev không chứa dữ liệu nhạy cảm.Safety check không thay thế review của developer.
dontAskTự deny tool call cần hỏi quyền, trừ các rule đã pre-approved hoặc read-only Bash command.Môi trường cần khóa chặt, demo read-only, audit repo, hoặc khi muốn ép Claude chỉ đề xuất.Claude có thể không hoàn thành task nếu thiếu quyền cần thiết.
bypassPermissionsBỏ qua gần như toàn bộ prompt permission. Chỉ cân nhắc trong sandbox cô lập như container/VM throwaway, tốt nhất không có secret và không có network nhạy cảm.CI sandbox, container throwaway, repo copy, workshop lab có thể reset.Rất nguy hiểm trên máy thật hoặc repo có secret/data thật; circuit breaker không thay thế sandbox.

Một nguyên tắc thực tế: permission mode không thay thế Git hygiene. Trước khi để AI sửa code, bạn vẫn cần biết branch nào đang active, working tree có gì, và rollback bằng cách nào.

Với team, đừng ghi nhớ mode theo truyền miệng. Trước khi chuẩn hóa auto, dontAsk, hoặc bypassPermissions, hãy kiểm tra official docs và CLI đang dùng:

claude --version
claude --help

Chạy ở terminal bất kỳ. claude --version in phiên bản Claude Code, còn claude --help liệt kê flag và mode hiện có. Rủi ro: nếu team dùng nhiều phiên bản CLI khác nhau, cùng một rule trong tài liệu nội bộ có thể không còn đúng. Với cấu hình lâu dài, dùng .claude/settings.json để đặt permissions.defaultMode hoặc rule allow/ask/deny, và dùng CLAUDE.md hoặc .claude/CLAUDE.md để ghi coding standards, testing requirements, common commands. Prompt và CLAUDE.md là hướng dẫn hành vi; permission settings mới là lớp enforce.

4. Step-by-step thực hành

Mục tiêu thực hành: dùng Claude Code để thêm rule validation nhỏ cho taskflow-ai: task title không được rỗng sau khi trim. Nếu project của bạn chưa có đúng file ví dụ, hãy yêu cầu Claude Code tìm file tương đương trước, không tự tạo kiến trúc mới.

Bước 1: Kiểm tra trạng thái repo

Chạy trong thư mục gốc project taskflow-ai:

git status --short

Lệnh này hiển thị các file đang thay đổi ở dạng ngắn. Kết quả kỳ vọng là rỗng hoặc chỉ có những file bạn hiểu rõ. Nếu thấy file lạ, dừng lại và đọc trước khi cho Claude Code sửa. Rủi ro: nếu working tree đã bẩn, bạn có thể nhầm thay đổi của mình với thay đổi do AI tạo ra.

Nếu muốn xem branch hiện tại:

git branch --show-current

Lệnh này in ra tên branch đang dùng. Kết quả kỳ vọng là branch feature, ví dụ feature/task-validation, không phải main. Rủi ro: làm trực tiếp trên protected branch khiến review và rollback khó hơn.

Bước 2: Mở Claude Code ở plan mode

Nếu chưa ở đúng thư mục project, chạy:

cd /path/to/your/project
claude

cd đưa terminal vào đúng project, còn claude mở session tương tác mặc định. Trong bài này, /path/to/your/project là thư mục gốc taskflow-ai. Trong session, dùng /help để xem command đang có. Đây là flow khởi động cơ bản trước khi bạn chọn mode nâng cao.

Để vào thẳng plan mode, chạy:

claude --permission-mode plan

Lệnh này mở session Claude Code với quyền ưu tiên đọc và khảo sát. Kết quả kỳ vọng là giao diện Claude Code sẵn sàng nhận prompt. Rủi ro thấp vì mode này không cho sửa file, nhưng Claude vẫn có thể đưa plan sai nếu chưa đọc đủ file.

Prompt đầu tiên:

Bạn đang ở repo taskflow-ai. Hãy khảo sát module quản lý tasks và lập plan để thêm validation: task title sau khi trim không được rỗng.

Ràng buộc:
- Chưa sửa file.
- Chỉ đọc file cần thiết.
- Nêu rõ file nào đã đọc và bằng chứng từ code.
- Đề xuất tối đa 1 file production và 1 file test cần sửa.
- Nếu thiếu thông tin, hỏi lại trước.

Kỳ vọng: Claude Code liệt kê file đã đọc, mô tả flow hiện tại, và đề xuất plan nhỏ. Nếu Claude đề xuất sửa quá nhiều file, yêu cầu thu hẹp phạm vi.

Nếu bạn phải tạm dừng, có hai cách quay lại:

claude --continue
claude --resume

claude --continue tiếp tục session gần nhất trong thư mục hiện tại. claude --resume mở lựa chọn session để bạn chọn đúng cuộc hội thoại; trong session tương tác cũng có thể dùng /resume. Rủi ro: resume nhầm session có thể mang context cũ vào task mới, nên luôn yêu cầu Claude tóm tắt trạng thái trước khi cho sửa tiếp.

Bước 3: Chỉ cho phép sửa một file nhỏ

Sau khi đồng ý plan, mở session mới hoặc tiếp tục session nhưng giữ ràng buộc rõ:

claude --permission-mode default --allowedTools "Read,Bash(git status *)"

Lệnh này chạy Claude Code ở default mode và chỉ pre-approve quyền đọc file cùng command bắt đầu bằng git status. Edit vẫn phải xin phép; bạn chỉ accept nếu đúng file đã thống nhất trong plan. Rủi ro: --allowedTools quá rộng như "Bash,Read,Edit" có thể cho AI chạy nhiều command hơn mức cần thiết hoặc auto-approve edit rộng; chỉ dùng rộng trong sandbox.

Prompt implement:

Thực hiện plan đã thống nhất.

Giới hạn:
- Chỉ sửa file production nhỏ nhất cần thiết.
- Không đổi API contract nếu không bắt buộc.
- Không chạy npm install, migration, git add, git commit, git reset, hoặc lệnh xóa file.
- Sau khi sửa, tóm tắt diff và nêu command test tôi nên tự chạy.

Kỳ vọng: Claude chỉ sửa một file nhỏ, ví dụ handler/service validation. Nếu Claude xin chạy lệnh không nằm trong phạm vi, đọc kỹ trước khi approve.

Bước 4: Review diff trước khi accept

Chạy trong thư mục gốc taskflow-ai:

git diff --stat

Lệnh này cho biết có bao nhiêu file và bao nhiêu dòng thay đổi. Kết quả kỳ vọng là 1 file production, hoặc tối đa thêm 1 file test nếu bạn đã cho phép. Rủi ro: nếu số file tăng bất thường, bạn cần dừng và review từng file.

Xem diff chi tiết:

git diff

Lệnh này hiển thị toàn bộ thay đổi chưa staged. Kết quả kỳ vọng là patch nhỏ, đúng acceptance criteria, không có đổi format hàng loạt, không chạm secret, không đổi config nhạy cảm. Rủi ro: diff dài làm bạn dễ bỏ sót behavior change; dùng git diff -- path/to/file để xem từng file nếu cần.

Nếu chỉ muốn xem một file:

git diff -- backend/src/tasks/task.service.ts

Lệnh này giới hạn diff vào file cụ thể. Hãy thay path theo file thật trong repo của bạn. Kết quả kỳ vọng là thay đổi validation nhỏ. Rủi ro thấp, vì đây là lệnh read-only.

Bước 5: Chạy test do bạn kiểm soát

Ví dụ nếu backend dùng npm script:

npm test -- --runInBand

Lệnh này chạy test suite theo cấu hình project. Chạy ở thư mục package chứa package.json, có thể là root hoặc backend. Kết quả kỳ vọng là test pass. Rủi ro: test có thể tốn thời gian hoặc phụ thuộc service ngoài; đọc script trong package.json trước nếu chưa chắc.

Nếu project dùng Vitest:

npm run test -- --run

Lệnh này chạy Vitest một lần thay vì watch mode. Kết quả kỳ vọng là danh sách test pass và exit code 0. Rủi ro: nếu test chạm database local, cần chắc chắn đang dùng database dev/test, không phải production.

Bước 6: Rollback nếu Claude Code làm sai

Trước khi rollback, xem lại file nào bị thay đổi:

git status --short

Nếu chắc chắn muốn bỏ thay đổi trong một file:

git restore -- backend/src/tasks/task.service.ts

Lệnh này đưa file về trạng thái trong Git index/HEAD. Chạy ở root repo. Kết quả thường không có gì nếu thành công. Rủi ro: mất toàn bộ thay đổi chưa commit trong file đó, kể cả thay đổi do bạn tự viết. Không chạy lệnh này nếu bạn chưa đọc diff.

Không dùng các lệnh sau theo đề xuất tự động của AI nếu chưa tự quyết định:

rm -rf node_modules
git reset --hard
git clean -fd
docker compose down -v

Những lệnh này có thể xóa file, mất thay đổi local, hoặc xóa volume database. Nếu cần chạy, developer phải tự đọc, tự hiểu, và tự chạy.

5. Prompt mẫu nên dùng

Prompt khám phá codebase

Hãy đọc module tasks trong taskflow-ai để hiểu luồng tạo task.

Yêu cầu:
- Chỉ đọc file, chưa sửa gì.
- Nêu rõ file đã đọc.
- Vẽ luồng request từ route/controller tới service/repository nếu có.
- Chỉ ra nơi validation title nên đặt và vì sao.

Prompt lập plan

Lập plan thêm validation: task title sau khi trim không được rỗng.

Ràng buộc:
- Plan tối đa 5 bước.
- Mỗi bước ghi file dự kiến chạm vào.
- Không đổi schema database.
- Không đổi response format trừ khi code hiện tại đã có pattern lỗi validation.
- Chờ tôi approve trước khi sửa.

Prompt implement

Implement theo plan đã duyệt.

Chỉ sửa file: backend/src/tasks/task.service.ts.
Không sửa file khác.
Không chạy lệnh destructive.
Sau khi sửa, báo diff summary và đề xuất test command, nhưng không tự commit.

Prompt review

Review diff hiện tại như senior backend reviewer.

Tập trung:
- Behavior có đúng acceptance criteria không.
- Có đổi contract ngoài ý muốn không.
- Edge case: title là khoảng trắng, null, undefined, chuỗi dài.
- Test nào còn thiếu.
Không sửa file trong bước review này.

Prompt viết test

Đề xuất test tối thiểu cho validation title.

Ràng buộc:
- Đọc test pattern hiện có trước.
- Chỉ đề xuất test case và file cần sửa.
- Không viết test cho đến khi tôi approve.

6. Trade-offs

plan mode chậm hơn vì bạn tách bước khảo sát khỏi bước implement, nhưng đổi lại giảm rủi ro sửa nhầm. Với repo team hoặc task chưa rõ, đây là trade-off đáng chọn.

default mode cân bằng giữa tốc độ và kiểm soát. Bạn vẫn phải đọc prompt xin quyền, nhưng Claude không bị khóa quá chặt. Đây là mode phù hợp nhất cho phần lớn công việc hằng ngày.

acceptEdits tăng tốc khi bạn đã có phạm vi hẹp và test rõ. Đổi lại, edit và một số thao tác filesystem trong working directory có thể được approve tự động, nên bạn có thể nhận patch nhiều hơn dự kiến nếu prompt không giới hạn file. Chỉ dùng khi branch sạch và bạn sẵn sàng review diff ngay.

autobypassPermissions tối ưu tốc độ nhưng tăng trách nhiệm của môi trường chạy. auto vẫn cần review vì classifier/safety check có thể hiểu sai intent. bypassPermissions chỉ nên là lựa chọn cho sandbox cô lập, đã xác minh official docs và claude --version/claude --help; nếu môi trường không sandbox, không có backup, hoặc có secret thật, lợi ích tốc độ không đáng với rủi ro.

dontAsk phù hợp khi bạn muốn Claude đóng vai trò reviewer hoặc planner, không phải implementer. Điểm bất tiện là Claude có thể bị chặn khi cần thao tác hợp lý, nên prompt phải nói rõ: nếu thiếu quyền, hãy mô tả command để tôi tự chạy.

7. Best practices

  • Bắt đầu task bằng plan mode khi scope chưa rõ, khi sửa module quan trọng, hoặc khi có nhiều file liên quan.
  • Trước khi cho AI sửa, chạy git status --short và hiểu toàn bộ working tree.
  • Giới hạn bằng prompt: file nào được sửa, file nào không được sửa, lệnh nào không được chạy.
  • Với --allowedTools, ưu tiên rule hẹp như Bash(git status *) hoặc Bash(git diff *) thay vì cho toàn bộ Bash.
  • Giữ destructive commands ở chế độ manual: rm, git reset --hard, git clean, docker compose down -v, migration drop table, force push, hoặc lệnh chạm production data.
  • Không đưa .env, token, private key, production credential, customer data vào prompt hoặc file training context.
  • Ghi rule lặp lại vào CLAUDE.md hoặc .claude/CLAUDE.md, nhưng dùng .claude/settings.json/managed settings nếu team cần enforce permission thật.
  • Với team repo, cân nhắc deny rule cho file nhạy cảm như Read(./.env) và command nguy hiểm như Bash(git reset *), Bash(git clean *), Bash(docker compose down -v*).
  • Review diff trước khi accept hoặc commit. AI có thể viết code hợp lý nhưng vẫn sai architecture, sai convention, hoặc thiếu edge case.
  • Với team workflow, yêu cầu Claude tạo summary dạng PR note, nhưng human vẫn review patch cuối.

8. Performance / cost / context

Permission mode ảnh hưởng trực tiếp tới thời gian và token. plan mode thường tốn thêm lượt hội thoại vì Claude phải khảo sát và giải thích trước, nhưng tiết kiệm chi phí sửa sai. Một patch sai trên 8 file thường tốn nhiều token để debug hơn một plan cẩn thận ban đầu.

Cách tối ưu:

  • Đưa context hẹp: nêu module, file nghi ngờ, acceptance criteria, test command.
  • Yêu cầu Claude liệt kê file đã đọc thay vì đọc toàn repo.
  • Chia task thành 3 lượt: explore, plan, implement. Không gộp refactor, feature, test, docs vào một prompt.
  • Dùng dontAsk hoặc plan cho audit/read-only để tránh tool call sửa file không cần thiết.
  • Sau khi implement, dùng git diff --stat trước rồi mới xem diff chi tiết để tiết kiệm thời gian review.

9. Checklist cuối bài

  • Tôi giải thích được từng permission mode và rủi ro của nó.
  • Tôi biết khi nào nên dùng plan trước khi sửa code.
  • Tôi đã chạy git status --short trước khi cho Claude Code edit.
  • Tôi đã yêu cầu Claude Code chỉ sửa một file nhỏ trong taskflow-ai.
  • Tôi đã review git diff --statgit diff trước khi accept.
  • Tôi không auto-approve destructive commands.
  • Tôi biết cách rollback một file bằng git restore -- path, và hiểu rủi ro mất thay đổi chưa commit.
  • Tôi có thể viết prompt giới hạn file, command, và acceptance criteria.
  • Tôi biết kiểm tra claude --version, claude --help, và official docs trước khi đề xuất mode rủi ro cho team.

10. Bài tập

Bài 1 - Cơ bản: mở taskflow-ai bằng claude --permission-mode plan, yêu cầu Claude Code khảo sát module tasks và lập plan cho validation title. Không cho sửa file.

Bài 2 - Thực tế: chuyển sang default với --allowedTools hẹp, cho phép sửa đúng một file nhỏ. Sau đó dùng git diff --statgit diff để review. Nếu patch quá rộng, rollback file đó và yêu cầu plan lại.

Bài 3 - Nâng cao: trong repo copy hoặc sandbox, so sánh default, dontAsk, và acceptEdits cho cùng một task nhỏ. Không chạy bypassPermissions; chỉ mô tả điều kiện an toàn nếu team thật sự cần.

Bài 4 - Review & Reflection: chọn một bug nhỏ trong repo cá nhân, viết prompt theo format Context, Goal, Constraints, Acceptance Criteria, Verification. Từ trải nghiệm đó, soạn rule đưa vào CLAUDE.md hoặc .claude/CLAUDE.md: plan trước, sửa nhỏ, review diff, chạy test, không commit tự động.


Tài liệu

Tóm tắt kiến thức

Permission mode trong Claude Code là lớp kiểm soát quyền cho agentic coding. Nó quyết định Claude được đọc gì, sửa gì, chạy lệnh nào, và khi nào phải hỏi developer.

Các điểm quan trọng:

  • default: mode cân bằng cho công việc thường ngày, có prompt xin quyền khi cần.
  • plan: mode an toàn để khảo sát codebase, đọc file, chạy lệnh read-only, và lập plan trước khi edit.
  • acceptEdits: tự approve edits và một số common filesystem commands trong working directory, phù hợp task nhỏ trong branch sạch.
  • auto: tự approve dựa trên safety checks, hiện được docs mô tả là research preview; cần môi trường dev có guardrails và vẫn phải review diff.
  • dontAsk: tự deny các tool call cần hỏi quyền, trừ rule đã pre-approved hoặc read-only Bash command.
  • bypassPermissions: bỏ qua gần như toàn bộ prompt permission, chỉ nên dùng trong sandbox/container/VM throwaway đã cô lập và không chứa secret.
  • .claude/settings.json: có thể đặt permissions.defaultMode, ví dụ auto, nhưng team nên thống nhất policy và xác minh official docs/CLI version trước khi áp dụng.
  • CLAUDE.md hoặc .claude/CLAUDE.md: nơi lưu coding standards, testing requirements, common commands, và rule review; đây là hướng dẫn cho Claude, không phải enforcement permission.

Nguyên tắc cốt lõi của Day 04: Claude Code có thể act nhanh, nhưng developer vẫn là owner của code. Permission mode chỉ giảm rủi ro, không thay thế review, test, Git hygiene, và judgment của team.

Sơ đồ tư duy hoặc luồng xử lý

Nhận task
  |
  v
Mở đúng project: cd /path/to/project -> claude -> /help khi cần
  |
  v
Kiểm tra Git state
  |
  v
Chọn permission mode
  |
  +-- Scope chưa rõ / rủi ro cao -> plan
  |
  +-- Scope nhỏ / branch sạch -> default
  |
  +-- Sửa nhỏ đã duyệt / sandbox -> acceptEdits
  |
  +-- Audit read-only / khóa quyền -> dontAsk
  |
  +-- Sandbox throwaway -> bypassPermissions
  |
  v
Yêu cầu Claude lập plan
  |
  v
Developer approve phạm vi
  |
  v
Claude sửa file nhỏ
  |
  v
git diff --stat -> git diff
  |
  v
Chạy test phù hợp
  |
  v
Accept / chỉnh tiếp / rollback
  |
  v
Ghi rule lặp lại vào CLAUDE.md hoặc .claude/CLAUDE.md

Luồng an toàn nên dùng trong taskflow-ai:

plan mode
  -> đọc module tasks
  -> plan validation title
  -> developer duyệt
default mode với tool hẹp như Bash(git status *)
  -> edit 1 file
  -> Claude tóm tắt diff
developer terminal
  -> git diff
  -> npm test hoặc npm run test
  -> commit thủ công nếu đạt

Bảng so sánh

Tình huốngMode nên dùngVì saoKhông nên làm
Mới mở repo, chưa hiểu architectureplanCho Claude đọc và giải thích trước khi sửaDùng acceptEdits ngay
Sửa bug nhỏ, biết file cần sửadefaultVẫn kiểm soát được tool callCho phép toàn bộ Bash nếu không cần
Format/lint fix nhỏ trong branch sạchacceptEditsTăng tốc thao tác edit phổ biếnChạy trên repo có thay đổi chưa review
Audit security/read-onlydontAskÉp Claude không tự sửa hoặc chạy tool ngoài ruleKỳ vọng Claude tự fix mọi thứ
Workshop trong container/VM có thể resetbypassPermissionsTốc độ cao, môi trường có thể bỏ điDùng trên máy thật, repo có secret, hoặc network nhạy cảm
Migration database hoặc xóa dữ liệuplan + manual commandDeveloper phải tự chạy command nguy hiểmAuto-approve migration/drop/reset
PR reviewplan hoặc dontAskClaude đóng vai reviewer, không editĐể Claude commit thay reviewer
Chuẩn hóa policy cho teamdefault/plan + settingsDễ enforce và audit hơn prompt miệngBật auto/bypassPermissions mà chưa kiểm docs/version
LệnhDùng để làm gìKết quả kỳ vọngRủi ro
cd /path/to/your/projectChuyển terminal vào đúng project trước khi mở ClaudePrompt đang ở root repo cần làmMở sai thư mục làm Claude đọc/sửa sai repo
claudeMở session Claude Code tương tác mặc địnhWelcome screen hoặc prompt Claude CodeNếu đang ở thư mục sai, context sai ngay từ đầu
claude --continueTiếp tục session gần nhất trong thư mục hiện tạiQuay lại đúng hội thoại gần nhấtCó thể nối nhầm context nếu thư mục có nhiều session
claude --resumeChọn session để resumeDanh sách session hoặc pickerChọn nhầm session đưa yêu cầu cũ vào task mới
claude --versionXem version CLI đang dùngIn phiên bản Claude CodeTeam dùng version khác nhau có thể khác behavior
git status --shortXem working tree trước khi AI sửaRỗng hoặc danh sách file đã hiểuBỏ sót thay đổi của người khác
git diff --statXem phạm vi patchSố file/dòng thay đổi nhỏKhông thấy logic chi tiết
git diffReview patch chi tiếtDiff đúng acceptance criteriaDiff dài dễ bỏ sót
git restore -- path/to/fileRollback một fileKhông có output nếu thành côngMất thay đổi chưa commit trong file đó
claude --permission-mode planMở Claude Code read-only planningSession Claude sẵn sàngPlan vẫn cần kiểm chứng
claude -p "Apply the lint fixes" --permission-mode acceptEditsChạy prompt một lần với auto-approve editsPatch lint nhỏKhông dùng cho thay đổi chưa rõ phạm vi

Lỗi thường gặp

  1. Dùng acceptEdits khi chưa có plan
    Hậu quả là Claude có thể sửa nhiều file, đổi style, hoặc thêm abstraction không cần thiết.

  2. Bấm approve command theo thói quen
    Một số command trông vô hại nhưng có thể xóa dữ liệu local, ví dụ git clean -fd hoặc docker compose down -v.

  3. Cho --allowedTools "Bash,Read,Edit" quá sớm
    Broad permission làm giảm giá trị của permission mode. Nên cấp tool theo task, càng hẹp càng tốt.

  4. Không review diff trước khi accept
    AI có thể pass test nhưng vẫn đổi API contract, bỏ validation cũ, hoặc sửa file ngoài scope.

  5. Dùng bypassPermissions trên máy làm việc chính
    Mode này chỉ hợp lý trong sandbox cô lập như container/VM throwaway. Nếu repo có secret, config thật, data local quan trọng, hoặc network có thể chạm dịch vụ nội bộ, rủi ro quá cao. Trước khi đưa vào workflow team, kiểm official docs và claude --version/claude --help.

  6. Không phân biệt read-only command và lệnh destructive
    git diff là read-only. git reset --hard là destructive. Hai lệnh đều thuộc Git nhưng mức rủi ro hoàn toàn khác.

  7. Tin rằng CLAUDE.md có thể chặn tool thật CLAUDE.md giúp Claude làm theo convention, nhưng không enforce permission. Muốn chặn thật, dùng permission rule trong .claude/settings.json, managed settings, hoặc hook.

Ví dụ policy tối thiểu trong .claude/settings.json cho repo team:

{
  "permissions": {
    "defaultMode": "default",
    "deny": [
      "Read(./.env)",
      "Read(./secrets/**)",
      "Bash(git reset *)",
      "Bash(git clean *)",
      "Bash(docker compose down -v*)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(npm install *)"
    ]
  }
}

File này đặt ở root project, path .claude/settings.json. Mục đích là enforce deny/ask rule tối thiểu; vẫn cần human review vì Bash pattern là prefix/glob rule chứ không phải security sandbox hoàn chỉnh.

Cách debug

Khi Claude Code sửa sai hoặc phạm vi patch quá rộng:

  1. Dừng session implement và không approve thêm tool call.
  2. Chạy trong root taskflow-ai:
git diff --stat

Lệnh này giúp xác định patch rộng tới đâu. Nếu thấy nhiều file ngoài scope, không tiếp tục implement.

  1. Xem diff chi tiết:
git diff

Đọc theo thứ tự: file bị chạm, public API change, logic change, test change, config change.

  1. Nếu chỉ một file sai và bạn chắc chắn muốn bỏ:
git restore -- path/to/file

Thay path/to/file bằng file thật. Lệnh này mất thay đổi chưa commit trong file đó, nên chỉ chạy sau khi đã review.

  1. Quay lại plan mode và prompt lại:
Patch vừa rồi quá rộng. Hãy lập lại plan nhỏ hơn.
Chỉ đề xuất một file cần sửa, không implement.
Nêu rõ vì sao file đó là điểm thay đổi tối thiểu.

Khi Claude Code bị chặn permission:

  • Kiểm tra mode hiện tại có phải dontAsk hoặc plan không.
  • Nếu task chỉ cần đọc, giữ mode hiện tại và yêu cầu Claude mô tả command để bạn tự chạy.
  • Nếu task cần sửa, mở session default với tool hẹp thay vì chuyển thẳng sang acceptEdits.

Khi test thất bại sau patch:

  • Yêu cầu Claude review failure output, nhưng chưa cho edit.
  • Hỏi Claude failure đến từ bug mới, test cũ không phù hợp, hay môi trường.
  • Chỉ cho sửa tiếp sau khi có diagnosis và file scope rõ.

Bài tập

Bài 1 — Cơ bản

Mục tiêu: hiểu permission mode bằng thao tác read-only.

Yêu cầu:

  1. Mở terminal tại thư mục gốc taskflow-ai.
  2. Chạy:
git status --short

Lệnh này kiểm tra working tree. Kết quả kỳ vọng là rỗng hoặc chỉ gồm file bạn biết rõ. Nếu có file lạ, ghi lại và không cho Claude sửa code.

  1. Mở Claude Code:
claude --permission-mode plan

Lệnh này mở Claude Code ở mode lập plan, phù hợp để đọc và phân tích trước khi edit.

  1. Gửi prompt:
Hãy đọc cấu trúc taskflow-ai và tìm module liên quan tới tasks.
Chưa sửa file.
Nêu rõ file đã đọc, entrypoint của luồng tạo task, và nơi phù hợp để validate title.

Kết quả cần có: danh sách file Claude đã đọc, mô tả luồng xử lý, và đề xuất điểm đặt validation.

Bài 2 — Thực tế

Mục tiêu: cho Claude Code sửa một file nhỏ dưới sự kiểm soát của developer.

Yêu cầu:

  1. Từ kết quả Bài 1, chọn một thay đổi nhỏ: task title sau khi trim không được rỗng.
  2. Mở Claude Code bằng mode kiểm soát:
claude --permission-mode default --allowedTools "Read,Bash(git status *)"

Lệnh này pre-approve quyền đọc và command bắt đầu bằng git status; edit vẫn phải xin phép trong default mode. Kết quả kỳ vọng là session Claude Code sẵn sàng. Rủi ro: nếu thêm Edit hoặc mở rộng Bash quá nhiều, Claude có thể tự động làm nhiều hơn phạm vi bạn muốn.

  1. Gửi prompt:
Implement validation title theo plan.

Ràng buộc:
- Chỉ sửa đúng một file production mà plan đã chọn.
- Không đổi schema database.
- Không sửa file test trong bài này.
- Không chạy npm install, migration, git add, git commit, git reset, git clean, hoặc lệnh xóa file.
- Sau khi sửa, tóm tắt thay đổi và đề xuất test command.
  1. Sau khi Claude sửa, tự chạy:
git diff --stat

Kết quả kỳ vọng: chỉ một file production thay đổi. Nếu nhiều hơn, dừng lại và chuyển sang phần debug trong document.md.

  1. Xem chi tiết:
git diff

Kết quả kỳ vọng: validation nhỏ, đúng acceptance criteria, không đổi behavior ngoài phạm vi.

Bài 3 — Nâng cao

Mục tiêu: so sánh default, acceptEdits, và dontAsk trong cùng một task.

Thực hiện trên branch dev hoặc repo copy, không làm trên branch chính.

Trước khi so sánh mode, kiểm tra CLI đang dùng:

claude --version
claude --help

claude --version in phiên bản Claude Code. claude --help cho biết --permission-mode hiện hỗ trợ những giá trị nào. Kết quả kỳ vọng là bạn xác nhận mode đang dùng tồn tại trong CLI hiện tại; rủi ro là tài liệu nội bộ có thể lệch nếu team dùng nhiều version khác nhau.

Phần A: dontAsk

claude --permission-mode dontAsk

Prompt:

Review diff hiện tại và chỉ đề xuất rủi ro. Nếu cần chạy command hoặc sửa file, hãy mô tả để tôi tự quyết định. Không tự sửa.

Kỳ vọng: Claude đóng vai reviewer, không tự sửa các tool call cần quyền.

Phần B: acceptEdits

Chỉ làm nếu working tree sạch hoặc bạn đang ở repo copy:

claude -p "Apply a minimal lint-only cleanup to the task validation file. Do not change behavior." --permission-mode acceptEdits

Lệnh này chạy prompt một lần và auto-approve edits/common filesystem commands theo mode acceptEdits. Kết quả kỳ vọng là patch nhỏ hoặc thông báo không cần sửa. Rủi ro: nếu prompt không đủ hẹp, AI có thể đổi nhiều hơn lint-only.

Sau đó kiểm tra:

git diff --stat
git diff

Nếu patch không đúng:

git restore -- path/to/file

Chỉ thay path/to/file bằng file đã review và chắc chắn muốn rollback. Rủi ro: mất toàn bộ thay đổi chưa commit trong file đó.

Viết nhận xét ngắn: mode nào giúp bạn kiểm soát tốt nhất, mode nào nhanh nhất, và mode nào bạn sẽ cấm trong repo thật.

Phần C: bypassPermissions

Không chạy mode này trong bài tập trên repo thật. Chỉ viết một đoạn đánh giá ngắn:

Tôi chỉ chấp nhận bypassPermissions khi:
- chạy trong container/VM throwaway hoặc CI sandbox cô lập;
- không có secret, production credential, customer data;
- không có network nhạy cảm hoặc đã chặn outbound không cần thiết;
- đã kiểm official docs và claude --version/--help của team;
- có cách reset môi trường sau bài lab.

Bài 4 — Review & Reflection

Mục tiêu: biến trải nghiệm Day 04 thành rule làm việc cho team.

Trả lời các câu hỏi:

  1. Trong taskflow-ai, loại task nào bắt buộc dùng plan trước khi sửa?
  2. Lệnh nào bạn không bao giờ auto-approve? Liệt kê ít nhất 5 command hoặc nhóm command.
  3. Khi Claude đề xuất sửa 6 file cho một bug nhỏ, bạn sẽ phản hồi bằng prompt nào?
  4. Khi nào bypassPermissions có thể chấp nhận được, và điều kiện nào bắt buộc phải có trước khi dùng trong team?
  5. Bạn sẽ viết rule gì vào CLAUDE.md hoặc .claude/CLAUDE.md ở Day 05 để kiểm soát permission và destructive commands?

Gợi ý prompt reflection:

Dựa trên workflow hôm nay, hãy giúp tôi soạn 8 rule an toàn cho CLAUDE.md của taskflow-ai.
Không thêm rule chung chung.
Mỗi rule phải có ví dụ command hoặc hành vi cụ thể.
Phân biệt rule hướng dẫn trong CLAUDE.md với permission rule enforce trong .claude/settings.json.

Tiêu chí hoàn thành

  • Đã chạy git status --short trước khi cho Claude Code sửa.
  • Đã dùng plan mode để yêu cầu Claude khảo sát và lập plan.
  • Đã implement một thay đổi nhỏ với file scope rõ ràng.
  • Đã review git diff --statgit diff trước khi accept.
  • Đã ghi lại ít nhất 5 destructive commands không auto-approve.
  • Đã rollback được một file trong repo copy hoặc giải thích được chính xác khi nào dùng git restore -- path.
  • Không có commit tự động do Claude Code tạo ra.
  • Đã giải thích được vì sao không chạy bypassPermissions ngoài sandbox cô lập.

Gợi ý nếu bí

Nếu không tìm được module tasks, dùng prompt:

Hãy tìm file định nghĩa route/controller/service liên quan tới task hoặc todo.
Chỉ đọc file.
Nếu project chưa có module tasks, hãy nói rõ trạng thái hiện tại và đề xuất một file nhỏ nhất để thêm validation demo, nhưng chưa tạo file.

Nếu Claude muốn sửa nhiều file, dùng prompt:

Phạm vi này quá rộng. Hãy thu hẹp về thay đổi nhỏ nhất.
Chỉ chọn 1 file production.
Không implement.
Giải thích trade-off nếu không sửa test trong bước này.

Nếu Claude xin chạy command nguy hiểm, dùng phản hồi:

Không chạy command đó. Hãy giải thích command làm gì, rủi ro là gì, và có lệnh read-only nào thay thế để kiểm tra trạng thái không.

Nếu diff quá dài, chạy:

git diff --stat

Sau đó xem từng file:

git diff -- path/to/file

Đáp án tham khảo hoặc kết quả kỳ vọng

Kết quả kỳ vọng cho Bài 1:

  • Claude xác định được file/module liên quan tới tasks.
  • Claude chưa sửa file.
  • Plan nêu đúng điểm đặt validation và lý do.

Kết quả kỳ vọng cho Bài 2:

  • Diff chỉ chạm một file production.
  • Logic validation xử lý được title rỗng sau khi trim.
  • Claude không chạy npm install, migration, Git lệnh destructive, hoặc commit.

Ví dụ diff summary chấp nhận được:

1 file changed, 4 insertions(+)

Ví dụ behavior mong muốn:

Input title: "   "
Kết quả kỳ vọng: request bị reject bằng lỗi validation hiện có của project.

Kết quả kỳ vọng cho Bài 3:

  • Bạn phân biệt được dontAsk là phù hợp cho review/read-only.
  • Bạn thấy acceptEdits nhanh hơn nhưng cần prompt hẹp và branch sạch.
  • Bạn không dùng bypassPermissions ngoài sandbox cô lập, và biết phải kiểm docs/CLI version trước khi đề xuất cho team.

Kết quả kỳ vọng cho Bài 4:

Rule mẫu có thể đưa vào CLAUDE.md hoặc .claude/CLAUDE.md Day 05:

- Luôn lập plan trước khi sửa code production.
- Không chạy destructive commands như rm -rf, git reset --hard, git clean -fd, docker compose down -v, migration drop/truncate nếu chưa có xác nhận thủ công.
- Với bug nhỏ, chỉ sửa tối đa 1 file production trước khi review diff.
- Sau mọi edit, báo git diff summary và test command đề xuất; không tự commit.
- Không dùng bypassPermissions trên máy làm việc chính; chỉ dùng trong sandbox throwaway đã xác minh version/docs.

Permission rule enforce tương ứng có thể đặt trong .claude/settings.json:

{
  "permissions": {
    "defaultMode": "default",
    "deny": [
      "Read(./.env)",
      "Bash(git reset *)",
      "Bash(git clean *)",
      "Bash(docker compose down -v*)"
    ]
  }
}