Bỏ qua để đến nội dung

flow là gì

flow là build harness có gate. Nó đưa một sản phẩm đi từ ý tưởng tới bằng chứng hoàn thành thật: URL đã deploy, CLI đã cài và chạy được, library API import được, hoặc skill đạt done-definition của chính nó — đi qua những gate chỉ mở khi bạn vượt qua chúng một cách trung thực.

Đó là một skill bạn cài vào coding agent. Không phải dịch vụ cần đăng ký, không phải framework mà code của bạn phụ thuộc vào. flow giữ gate và bằng chứng — không can thiệp vào runtime. Độc lập: không bắt buộc phải có AgentKit hay claudekit; review đa model sẽ mở khóa khi các engine đó có mặt.

Coding agent vui vẻ sinh ra một plan nghe có lý, một bản research nghe có lý, rồi tuyên bố việc đã xong — cũng nghe có lý. Từng artifact khi đọc riêng đều ổn. Lỗ hổng nằm ở cả hệ thống chứ không ở một file riêng lẻ: không có gì trong vòng lặp có nhiệm vụ nói không.

Hai kiểu fail cụ thể gây ra phần lớn thiệt hại.

Giấy tờ trông như tiến độ. Research với quote đối thủ bịa vẫn pass mọi check cấu trúc. Scope biến feature hạng C thành B cũng pass. Cả hai đọc lên đều ổn; không cái nào trụ được khi đối mặt thực tế.

“Done” mà chưa done. Agent báo card xong vì test xanh và nhánh đã merge. Không ai load trang. Không ai chạy thử lệnh. “Tests pass” là trạng thái giữa pipeline, đã bị âm thầm nâng lên thành trạng thái cuối cùng.

Ba cam kết. Mọi thứ khác đều từ đó mà ra.

Hoàn thành nghĩa là bằng chứng thật ngoài thế giới. Mỗi card nêu bằng chứng hoàn thành ngay từ đầu, và gate yêu cầu dán bằng chứng đó vào trước khi card được đánh dấu hoàn thành. Web: URL live và output curl thật. CLI: một lần gọi thật kèm exit code. Code đã merge và CI xanh bị từ chối thẳng thừng. Xem Done nghĩa là bằng chứng thế giới thật.

Hai lớp phải đồng ý. Script tất định bắt những phần cơ học dễ gian lận (ô chưa tick, [FILL] còn sót, evidence rỗng) rồi exit 0 hoặc 1. Model đọc skill bắt những gì script không bắt được: research bịa, scope bơm hạng, endpoint không có auth. Gate chỉ pass khi cả hai đồng ý. Xem Harness hai lớp.

Loại tại gate là kết quả hợp lệ. Harness mà chỉ biết nói “tiến” thì chẳng khác gì băng chuyền. Loại một ý tưởng yếu ở Scope vừa rẻ vừa khôn ngoan. flow coi đó là kết quả chính đáng — không phải failure cần tìm đường vòng.

Không board, không burndown, không estimate: không phải tool quản lý dự án. Không phải code generator; nó đặt gate cho bất cứ code nào — dù agent hay người viết. Không phải hệ CI, dù luật bằng chứng hoàn thành của nó khắt hơn hầu hết gate CI. Cũng không phải wrapper làm agent thông minh hơn. Việc nó làm là khiến agent chịu trách nhiệm — một chuyện khác, và hữu ích hơn.

Idea -> Research -> Scope -> PRD -> ADR -> Contract -> Cards -> Build -> Review -> Deploy -> Verify-live -> Retro
|------------------ planning (files in flow/) ------------------| |------- shipping (inside cards/) -------|

Planning là sáu stage có gate, tồn tại dưới dạng file trong flow/. Shipping là dãy card dưới cards/, mỗi card một phiên build có phạm vi, bám đúng contract viết ở stage 05. Giữa các session, store bền vững giữ debt, retro, trace, playbook — để session sau bắt đầu mà vẫn thấy rõ những nỗi đau cũ.

Chat là cửa vào mặc định: mô tả điều bạn muốn, Concierge đề xuất một hành động kế tiếp. Lệnh gõ tay như /flow next luôn được ưu tiên hơn routing chat.

Đây là ý tưởng cốt lõi của flow. Phần còn lại đều là hệ quả.

Một gate phải bắt hai loại fail rất khác nhau, và không thành phần nào làm tốt cả hai. flow chạy hai lớp. Gate chỉ pass khi cả hai đồng ý. Thiếu một lớp thì chưa pass.

runner/flow.sh là engine bash tất định, exit 0 hoặc 1. Nó quản vòng đời stage và card, và kiểm những thứ vừa dễ gian lận vừa dễ phát hiện:

  • ô gate chưa tick, kể cả bullet - [ ] sót dưới ## Open decisions (cùng một scanner xử lý cả hai)
  • [FILL] còn sót
  • status card hợp lệ
  • section ## Evidence rỗng trên card tuyên bố đã hoàn thành

Exit code là ground truth. Luật cho model rất thẳng: luôn chạy script trước, đọc exit code, báo lại đúng nguyên văn. Đừng lấy phán đoán của mình thay vào chỗ đó.

Lớp này không đọc được nghĩa. Nó không phân biệt quote đối thủ thật với quote bịa, hay feature hạng B trung thực với hạng C được viết thành B.

Đó là việc của model. Sau khi script pass, skill áp dụng một bộ thử thách theo từng stage trước khi operator được phép tiến. Đây là nơi research bịa bị chất vấn, scope bơm hạng bị gọi tên, endpoint thiếu cột auth bị gắn cờ, và “tests pass” dán vào evidence bị loại vì mới chỉ ở giữa pipeline.

Chỉ dẫn này áp dụng cho cả hai chiều: đừng lặng lẽ tiến qua artifact rỗng, và đừng lặng lẽ chặn artifact vững. Khi script pass nhưng nội dung yếu, operator được báo đúng như vậy — pass về mặt cơ học, nhưng yếu về chất — rồi operator là người quyết định.

Vì sao tách, chứ không phải một checker thông minh hơn

Phần tiêu đề “Vì sao tách, chứ không phải một checker thông minh hơn”

Script không đánh giá được nghĩa. Model thì không đáng tin ở khoản tất định về cơ học. Tách ra, mỗi loại fail rơi đúng vào chỗ bắt được nó, và biến nửa có thể gian lận thành thứ bắt buộc phải tuân theo, chứ không phải thứ có thể thuyết phục. Bạn không thuyết phục được exit 1 đổi ý. Bạn cũng không viết được regex phát hiện quote thị trường bịa.

Lợi ích thứ hai tinh tế hơn. Lớp cơ học là process riêng với exit code thật, nên tuyên bố của model về một gate có thể kiểm chứng được. Agent nói “gate đã pass” có thể đối chiếu với tín hiệu mà nó không tự tạo ra.

Dưới cả hai là lớp bền vững: store Python và SQLite giữ intake và risk lane, story và proof, trace và tier, decision, backlog. Nó tự giảm cấp một cách nhẹ nhàng: thiếu python3 thì gate vẫn chạy, chỉ lớp này tắt.

+---------------------------------------------------------------+
| Semantic layer - SKILL.md + references/ (the model) |
| judgment: hollow content, grade-laundering, adversarial |
| review, agent orchestration, work mode, auto tiers |
+---------------------------------------------------------------+
| calls (exit code = ground truth)
v
+---------------------------------------------------------------+
| Mechanical layer - runner/flow.sh (bash, exit 0/1) |
| stage/card lifecycle, gate checks, debt ledger, |
| design check, harness passthrough |
+---------------------------------------------------------------+
| reads/writes (best-effort, graceful degrade)
v
+---------------------------------------------------------------+
| Durable layer - Python + sqlite3 (flow-owned) |
| intake/risk-lane, story+proof, trace+tier, decision, backlog |
+---------------------------------------------------------------+

Đây là bộ nhớ ngoài. Tiến độ và các ma sát được giữ lại qua các session và cửa sổ ngữ cảnh. Đó là liều thuốc giải cho sự xuống cấp dần dần khi dự án dài chỉ sống trong các cuộc hội thoại.

Agent có thể thay thế; gate thì cố định. Stage có thể giao việc soạn thảo cho agent chuyên khi có agent đó, và dùng hành vi built-in khi không có. Gate giống nhau trên mọi path, nên thiếu agent cũng không bao giờ hạ chuẩn. Agent soạn; gate quyết định.

Cùng một luật áp cho các engine khác nhau (tùy chọn). Model thứ hai hoặc thứ ba có thể review một card, nhưng verdict của nó chỉ để hỗ trợ triage: không bao giờ tự pass, cũng không bao giờ tự fail.

Done nghĩa là bằng chứng thế giới thật

Phần tiêu đề “Done nghĩa là bằng chứng thế giới thật”

Mỗi card nêu bằng chứng hoàn thành ngay từ đầu, và gate yêu cầu dán bằng chứng đó vào trước khi card được đánh dấu hoàn thành. “Tests pass” và “code merged” là trạng thái giữa pipeline. Chúng không bao giờ là hoàn thành.

Cách phổ biến nhất khiến một bản build có agent hỗ trợ đi sai không phải là bug, mà là status. Card được báo xong vì test xanh, review đã duyệt, nhánh đã merge. Mỗi câu đó đều đúng. Không ai load trang.

Mỗi tín hiệu đó đo proxy của thứ bạn quan tâm. Test đo mô hình bạn có về hệ thống so với chính nó. Merge đo sự đồng ý về một diff. Không cái nào chạm tới thế giới đang chạy. Các proxy lặng lẽ trôi xa khỏi thực tế, và độ lệch lại vô hình đúng vào lúc quan trọng nhất, vì mọi dashboard đều xanh.

Cách sửa không phải là thêm proxy, mà là yêu cầu một lần quan sát trực tiếp thứ thật.

Loại dự án quyết định hình thức của bằng chứng. Tinh thần giống nhau mọi trường hợp: có người đã tương tác với thứ đã deploy rồi dán kết quả trả về.

Loại dự án Bằng chứng hoàn thành
web URL đã deploy live cộng output curl thật
cli Tool cài được, và một lần gọi thật trả output và exit code đúng
library Public API import được, ví dụ dùng chạy được, đạt ngưỡng coverage
skill Cài vào skill home, và một lần chạy thật đạt done-definition của chính nó

Đặt loại bằng /flow project-type <type>; mặc định là web. Seam của contract và phần còn lại của matrix nằm ở Loại dự án.

Artifact quy trình, dù ấn tượng:

  • pull request đã duyệt
  • badge CI xanh hoặc workflow run
  • release notes mô tả cái đã ship
  • code review không tìm thấy gì
  • tóm tắt của chính agent nói work đã xong

Lớp cơ học đặt một ngưỡng sàn ở đây: card có section evidence chỉ chứa prose quy trình bị từ chối, nên không thể dùng lý lẽ để lách kỷ luật này ngay tại lúc đó. Ngoài ngưỡng sàn đó, gate ngữ nghĩa hỏi câu khó hơn: đây là bằng chứng thế giới, hay mô tả thế giới?

Tự đánh giá của agent bị loại trừ một cách rõ ràng. Tín hiệu ground-truth cho mọi gate là thứ agent không tự sinh ra: exit code của script, output lệnh verify thật, check live.

Vì sao gate từ chối evidence rỗng mạnh đến vậy

Phần tiêu đề “Vì sao gate từ chối evidence rỗng mạnh đến vậy”
[x] status is 'done' but ## Evidence is empty (paste world-state proof: URL/curl/DB row)
FAIL: C-001 has gate violations (above).

Luật này vẫn kích hoạt dù code đã xong và đúng. Lý do: lúc rẻ nhất để bắt bằng chứng là lúc bạn đang nhìn thứ đang chạy sẵn. Nếu hoãn lại, bằng chứng sẽ được tái dựng từ trí nhớ, và bằng chứng tái dựng không thể phân biệt được với bằng chứng bịa.

Cùng lý lẽ đó đứng sau thao tác flip card của CLI, /flow card done C-NNN: áp cùng luật với check và revert nếu gate fail, nên không có path code nào sinh ra báo xong.

Nếu card thật sự chưa chứng minh được ngay (chưa có đích deploy, dịch vụ ngoài không sẵn) thì đừng hạ chuẩn bằng chứng. Ghi lại điểm rủi ro thành debt, bằng văn bản, kèm điều kiện để đóng nó. Debt thì nhìn thấy được và hiện lên trong recall; còn báo xong thì vô hình và chỉ hiện ra ở production.

Cách ghi dòng debt đó, và khi nào skip bị từ chối, nằm ở Skip a gate with debt. Cách dán bằng chứng lên card nằm ở Tạo và kiểm card.

Một lần pass cơ học nghĩa là file đầy đủ về cấu trúc. Nó không nói gì về việc nội dung có đúng hay không. Thử thách ngữ nghĩa là bộ câu hỏi theo từng stage mà model áp dụng sau khi script pass. Nó được cố ý thiết kế cụ thể theo từng stage, vì mỗi stage mời gọi một kiểu nói dối khác nhau.

Ở Research, cám dỗ là bịa ra đối thủ và số liệu không có nguồn. Ở Scope, cám dỗ là bơm hạng: viết feature bạn muốn build cao hơn một hạng so với hạng nó xứng đáng. Ở PRD, cám dỗ là requirement không có chủ và nỗi đau không có feature đi kèm. Ở Contract, cám dỗ là endpoint thiếu cột auth. Ở Card, cám dỗ là bằng chứng chỉ mô tả quy trình chứ không phải thế giới. Prompt chung chung “cái này có tốt không?” không bắt được những thứ này một cách đáng tin cậy. Nhưng thử thách đặt tên theo từng stage thì làm được.

Chỉ dẫn này áp dụng cho cả hai chiều: đừng lặng lẽ tiến qua artifact rỗng, và đừng lặng lẽ chặn artifact vững. Khi thứ gì pass cơ học nhưng đọc yếu, operator được báo đúng như vậy rồi tự quyết định. Cũng có bằng chứng hành vi rằng lớp này hoạt động: /flow eval đưa cho judge mới các fixture tuy sạch về mặt cơ học nhưng rỗng về nội dung, rồi chấm xem chúng có bị gắn cờ không. Đó là ngưỡng dưới, không phải là bảo đảm.

Idea (00). Pitch có đúng là ba câu (ai / nỗi đau / cái gì)? Người được nêu có phải người hoặc nhóm cụ thể, không phải “users”? Nỗi đau có cụ thể, không phải một category? Nghi thức forge-idea là opt-in; không bao giờ trở thành điều kiện mà gate này kiểm tra.

Research (01). Rủi ro bịa cao nhất. Ba đối thủ có thật sự được mở ra xem? Với sản phẩm web / market: complaint có phải quote thật kèm link nguồn chạy được, và kênh mười user đầu có phải một chỗ cụ thể? Với cli / library / skill / tool nội bộ: ma sát first-party có đủ cụ thể và quan sát được không, kèm người hưởng lợi có tên; “không kênh thị trường” ở đây là bình thường, không phải tín hiệu loại. Chi phí phải là số thật, không phải số đoán.

Scope (02). Cảnh giác với bơm hạng. Gọi C là C (realtime, payments viết từ đầu, auth tự làm, pipeline agent tự trị, concurrency nặng). Nếu các lựa chọn sản phẩm quan trọng còn để mở (quota, identity key, tenancy, response contract, người chịu trách nhiệm enforcement) thì dừng và liệt kê; giá trị mặc định dù cấu hình được cũng không phải là quyết định có thẩm quyền. Một bullet dưới ## Assumptions mà mã hóa luật sản phẩm nhưng không có thẩm quyền từ operator hoặc ADR thì phải là open decision, hoặc dừng lại — chứ không phải giá trị mặc định âm thầm.

PRD (03). Metric thành công có phải một con số thật, không phải “UX tốt hơn”? Mỗi nỗi đau có dẫn evidence và nêu feature v1 loại nó, và mỗi feature v1 có loại ít nhất một nỗi đau? Nỗi đau hay feature nào bị bỏ rơi một mình đều là scope drift. Người lạ có build được v1 từ file này mà không hỏi operator không?

ADR (04). Mỗi quyết định có nêu phương án bị từ chối thật, không phải bù nhìn? Storage, auth, deploy đã quyết thật, không phải “TBD”? List NOT-doing có trung thực về thứ bị hoãn?

Contract (05). Interface là seam theo loại dự án: web = endpoint, cli = command + flags + output/exit, library = hàm public + args + return, skill = command/file. Mỗi feature PRD map ít nhất một interface và ngược lại. Mỗi interface đều có input và output với cấu trúc rõ ràng, tên field/flag không được trôi. Cột access/effects phải có nội dung thật với mọi interface; đừng để sản phẩm web bỏ trống cột này. Trước khi pass, hãy đọc contract đối chiếu với mọi doc mà nó tự nhận là nguồn sự thật: mâu thuẫn ở đây sẽ được ship đi như “đã pass”, và mọi card đều thừa hưởng nó.

Card (/flow check C-NNN). Phạm vi có đúng một việc? ## Independent test có phải bằng chứng user nhìn thấy, không phải “unit tests pass”? Diff có nằm trong ## Allowed files? Cấu trúc có khớp flow/05-contract.md đến từng tên không? ## Evidence có phải thế giới thật (URL bấm được, curl thật, một dòng DB) và mỗi mục có nêu artifact hoặc lệnh đã sinh ra nó?

Consistency (/flow consistency). Chỉ mang tính tư vấn; không bao giờ chặn đường build. Sau các lượt pass theo ID của runner, model vẫn phải bắt được coverage rỗng (FRn dán lên card không giao feature đó), requirement mâu thuẫn giữa các artifact, feature trong cut list xuất hiện lại như v1, và thuật ngữ bị trôi (ticket / issue / request).

Toàn bộ nội dung thử thách cho model nằm ở file dành cho maintainer trong chân trang. Các skip loại security và HALT của auto không thuộc trang này; chúng nằm ở Khi việc phải dừng.

flow là ba lớp phối hợp với nhau, cộng thêm artifact trên đĩa: engine tất định tốc độ cao cho phần cơ học có thể gian lận, skill để đưa ra phán đoán, và store bền vững để bản ghi tồn tại qua các session. Bức tranh tổng thể cho operator gồm bốn phần: skill, runner, artifact, và hai kênh phiên bản.

Lớp ngữ nghĩa là SKILL.md cộng playbook dưới skills/flow/references/. Đó là thứ hosting agent đọc: dispatch, đứng gác ở gate, orchestration. Sau khi runner/flow.sh trả 0, lớp này chạy thử thách theo từng stage ở trên. Nó không bao giờ thay exit code của script bằng một lần pass theo cảm tính.

Lớp cơ học là runner/flow.sh. Bash, tất định, exit 0 hoặc 1. Nó quản vòng đời stage và card, kiểm gate ([FILL], ô, evidence rỗng), sổ cái debt, kiểm design, và passthrough harness. Exit code là ground truth. Luôn chạy trước; luôn báo lại đúng nguyên văn.

Bên dưới, CLI Python và SQLite do flow sở hữu giữ intake và risk lane, story và proof, trace và tier, decision, backlog. Thiếu python3 thì gate vẫn chạy; chỉ lớp bền vững này tắt.

Artifact sống trong dự án đang được build, không nằm trong skill home:

flow/00-idea.md .. 05-contract.md planning, gated
cards/C-NNN.md shipping units
MODE, RETRO.md, DEBT.md, AUTO-LOG.md, DESIGN.md
.flow/harness.db durable records

File planning dưới flow/ là các stage có gate. Mỗi card dưới cards/ là một phiên build có phạm vi, bám contract stage 05. File sổ cái và .flow/harness.db là cách debt, retro và trace tồn tại qua cửa sổ ngữ cảnh tiếp theo.

Phân phối là hai kênh song song cùng đổ về một cây chuẩn. Installer npm (npx @manhquy/flow-skill@latest) là đường chính: thuần Node, không đòi shell. Script cài trong kho là implementation tham chiếu dùng lúc phát triển và CI. Cả hai ghi cùng skill home, nên dự án đổi kênh mà không phải tạo lại gate.

monorepo skills/flow/ --npm run sync--> npm-wrapper/skills/flow --npm pack--> registry
| |
| install.sh / agent skill homes | npx @manhquy/flow-skill@latest
v v
~/.claude/skills/flow same tree via installer CLI

Hai kênh đánh số phiên bản cho các artifact khác nhau. Skill product đánh version cho gate, SKILL.md, runner, references, template: thứ phán xét bản build của bạn. Gói npm chỉ đánh số installer CLI: phát hiện agent, đường copy, flag. Chúng không nhất thiết phải trùng nhau. --help in cả hai số. Hãy kiểm tra trên máy của bạn, đừng tin vào tài liệu. Câu chuyện về cặp số — kể cả nên pin số nào — nằm ở Hai số phiên bản.


Dành cho maintainer (không phải trang công khai): docs/adr/0001-discipline-layer-identity.md, skills/flow/references/gate-rules.md, docs/system-architecture.md.