Astragentic chạy trên gì

Tech stack

Danh sách này ngắn có chủ đích. Mỗi thành phần ở đây phải trả lời được câu “bỏ nó ra thì cái gì gãy”, và thành phần nào chỉ gây bất tiện nhỏ khi bỏ đi thì tôi đã bỏ. Hai thành phần đầu là hai CLI, ba thành phần giữa là cơ chế, ba thành phần cuối là thứ tôi tự viết hoặc tự chọn để dựng chính trang này.

Hai Lớp, Chỉ Một Là Của Ta An architecture diagram generated by Archify. Astragentic · điều phối · ĐIỀU PHỐI Astragentic điều phối Claude Code · runtime · RUNTIME Claude Code runtime Codex · runtime · RUNTIME Codex runtime OpenCode · runtime · RUNTIME OpenCode runtime mattpocock-skills · phương pháp · PHƯƠNG PHÁP mattpocock-skills phương pháp Superpowers · phương pháp · PHƯƠNG PHÁP Superpowers phương pháp khác · phương pháp chưa liệt kê · PHƯƠNG PHÁP khác phương pháp chưa liệt kê dùng ĐIỀU PHỐI RUNTIME PHƯƠNG PHÁP Legend Backend External

Vuốt ngang để xem hết sơ đồ

Xem sơ đồ đầy đủ ↗mở tab mới

required

Claude Code

Runtime. Agent của mọi role đều chạy ở đây, và claude --dangerously-skip-permissions --agent thomas --model claude-opus-5 --effort medium là câu lệnh mở đầu một session. Nếu bạn chỉ cài đúng một CLI thì phải là CLI này.

Nó bắt buộc vì hai cơ chế sau chỉ tồn tại ở đây:

  • System prompt tách khỏi contract. .claude/agents/<role>.md là system prompt và sống sót qua compaction, còn .agents/roles/<role>.md vào session như một tool result và bị compaction tóm tắt đi trước tiên.
  • Compaction. hook-contract-reload.py đăng ký ở Claude Code cho sự kiện compaction, và không runtime nào khác trong harness có sự kiện đó.

optional

Codex CLI

Codex CLI, có mặt vì cross-vendor arm và không vì gì khác. Không role nào chạy trên nó. Không có vendor thứ hai thì arm đó không tồn tại, và arm là cơ chế có sản lượng bắt lỗi cao nhất trong hệ này.

Builder chạy nó từ worktree của mình qua plugin Codex (codex-arm), còn Thomas chạy ở phạm vi spec và slice. Nếu Codex không dùng được hoặc hết quota thì arm chưa chạy, và biên nhận ghi đúng như vậy.

required

git worktree

Đây là ranh giới isolation thật, và nó là git chứ không phải nội quy. Mỗi ticket một checkout riêng tại .claude/worktrees/<branch-slug>, đường dẫn tuyệt đối và nằm trong repo, tạo bằng git worktree add -b <ticket-branch> <worktree-path> <base>. Builder là người ghi duy nhất trong đó. Thomas, Rin và Builder khác đều chỉ đọc, không ai ghi.

Chỗ dễ hiểu nhầm là worktree giữ cái gì. Nó giữ nội dung git được track và không giữ gì khác:

  • Database container. Không bị cô lập.
  • Tiến trình nền. Không bị cô lập.
  • Đường dẫn cố định ngoài checkout. Bất cứ gì một công cụ ghi ra đó cũng không bị cô lập.

Xoá thì phải bằng git worktree remove, không bao giờ bằng rm -rf. Xoá thô để lại đăng ký trong .git/worktrees/, rồi lần add sau ở đúng đường dẫn đó sẽ bị từ chối.

Một Ticket, Một Worktree, Một Pane A sequence diagram generated by Archify. claim claim claim claim merge merge merge merge claim (lệch giờ) build + review (tách biệt từng worktree) merge (trả về lệch giờ) Tracker · frontier + assignee · Sequence participant Tracker frontier + assignee TRA-139 · worktree Builder · Sequence participant TRA-139 worktree Builder TRA-142 · worktree Builder · Sequence participant TRA-142 worktree Builder TRA-125 · worktree Builder · Sequence participant TRA-125 worktree Builder TRA-087 · worktree Builder · Sequence participant TRA-087 worktree Builder Legend request return

Vuốt ngang để xem hết sơ đồ

Xem sơ đồ đầy đủ ↗mở tab mới

required

herdr

Trình quản lý workspace terminal, floor >= 0.8.0. Nó cho mỗi agent một pane mở ra nhìn được, và cho phép nhắc, chờ, đọc từng pane. Đây là thứ biến dispatch từ một câu kể thành một vật đếm được.

Và nó là kênh duy nhất không phân biệt nền tảng. Giữa hai session Claude Code đã có sẵn cross-session messaging, nhưng kênh đó chỉ tồn tại bên trong một hãng. Khi một Builder mở một junior trên runtime khác ngay cạnh mình, hai tiến trình của hai hãng không có giao thức chung nào để nói với nhau. herdr có: pane là địa chỉ, herdr pane run là gửi, herdr pane read là đọc. Builder điều một junior bằng đúng những lệnh nó dùng cho mọi pane — và đó là lý do “một quy trình, nhiều runtime” không dừng ở khẩu hiệu.

Một bẫy đã đo khi đọc pane: phần đọc bị cắt bớt mà không báo gì. Khi cần nguyên văn một output dài, đừng tin lần đọc pane — bảo agent ghi ra file rồi đọc file. Một lần đọc thiếu trông hệt như một lần đọc đủ.

dispatch-ticket từ chối dispatch nếu herdr-watchdog.sh chưa chạy, và nó kiểm ngay ở lần dispatch đầu tiên. Giới hạn tôi phải học lại: herdr agent wait không đáng tin cho phần verdict. Bây giờ herdr-watch-terminal.sh chờ theo lát 60 giây và lấy verdict từ một lệnh herdr agent get mới tinh ở mỗi lát; wait bị hạ xuống thành giấc ngủ có thể ngắt. Độ trễ phát hiện xấu nhất là 60 giây, không phải cả session.

Watchdog, và câu hỏi khó hơn vẻ ngoài của nó: “nó còn sống không”. Đo trên một dự án thật, cùng một instance đồng thời: nằm trong ps, bị xoá mất pid file trong khi vẫn đang chạy, và có một tiến trình con thường trú khiến “còn con” luôn đúng dù vòng lặp đã treo. Không cái nào trong ba tín hiệu đó có thể thành sai khi vòng lặp treo. Thứ có thể thành sai là một dấu thời gian chỉ nhích lên khi vòng lặp chạy trọn một lượt — đó là heartbeat file. Kiểm mtime của nó, đừng kiểm sự tồn tại của nó.

Và đừng bọc nó trong bất cứ thứ gì. Khởi chạy bằng nohup … &, không thêm gì trong pipeline. Tách process group bảo vệ watchdog khỏi tín hiệu gửi cho nhóm của bên gọi, nhưng không bảo vệ được khỏi tín hiệu gửi thẳng vào PID của nó — mà đó đúng là việc một wrapper có timeout làm khi timeout nổ. Đo được: một watchdog khởi chạy từ bên trong một tool call, tool call đó timeout, watchdog thoát trong cùng một giây — sạch sẽ, và không để lại dòng nào giải thích vì sao, vì nhìn từ log thì một lần thoát sạch và một lần bị giết giống hệt nhau. Sau khi phóng, xác nhận bằng ps -o ppid= -p <pid> đọc ra 1; một PID còn sống và không có lỗi in ra không phải cùng một khẳng định với “đã tách hẳn và vẫn đang chạy”.

/loop — nhịp để không ai phải ngồi canh. Watchdog phát hiện pane chết. Có một trạng thái nó không phát hiện được, vì nhìn từ ngoài nó hoàn toàn bình thường: không còn ai làm gì cả — ticket cuối đã merge, không pane nào lỗi, và cũng không ai nhặt việc mới. /loop của Claude Code đặt một nhịp cố định lên chính session Thomas, và mỗi nhịp là một lượt model thật chứ không phải một cron shell:

/loop 12m Thomas: agent còn hoạt động không? Đảm bảo monitoring và watching còn khoẻ.
Hết ticket thì chủ động nhặt ticket mới và làm tiếp. Chỉ dừng khi không còn ticket để
nhặt VÀ không pane nào đang chạy VÀ không có gì chờ merge. Context của Thomas trên 80%
thì chủ động compact.

Ba điều đáng biết trước khi đặt nhịp. Sàn là 60 giây — 15s bị làm tròn lên 1m. Dưới 5m thì phần lớn nhịp không tạo ra thay đổi nào có nghĩa nhưng vẫn tiêu một lượt model đầy đủ, mà pane chết thì herdr-watchdog.sh đã bắt ở nhịp 300 giây rồi — hai thứ này canh hai loại hỏng khác nhau, đừng để nhịp này gánh việc của nhịp kia. Và ở chế độ cron, Thomas không tự dừng được: muốn nó dừng thật thì điều kiện dừng phải kèm một câu bảo nó tự gỡ cron job.

Mỗi Agent Có Pane Riêng An architecture diagram generated by Archify. Thomas · router thường trực · KHÔNG GIAN HERDR Thomas router thường trực ticket:TRA-139 · Builder · KHÔNG GIAN HERDR ticket:TRA-139 Builder ticket:TRA-142 · Builder · KHÔNG GIAN HERDR ticket:TRA-142 Builder spec:TRA-87 · Shaper · KHÔNG GIAN HERDR spec:TRA-87 Shaper qa:TRA-125 · QA · KHÔNG GIAN HERDR qa:TRA-125 QA rin:TRA-125 · Rin · KHÔNG GIAN HERDR rin:TRA-125 Rin dispatch dispatch dispatch dispatch-qa review KHÔNG GIAN HERDR Legend Frontend Backend Security External

Vuốt ngang để xem hết sơ đồ

Xem sơ đồ đầy đủ ↗mở tab mới

required

mattpocock-skills

Toàn bộ phần craft đến từ đây, phiên bản tối thiểu >= 1.3.1, cài dưới dạng plugin.

  • Bước có người gọi. wayfinder, grill-with-docs, to-spec, to-tickets, implement, code-review.
  • Phần craft model tự gọi khi cần. grilling, tdd, codebase-design, domain-modeling, research, prototype, diagnosing-bugs, wizard, pr.

Lợi ích của việc cài một lần là cả team có craft, vì skill model-invoked không cần đấu dây gì thêm.

Đánh đổi. check-requirements.sh fail cứng khi thiếu nó, và địa chỉ /mattpocock-skills:<name> nằm rải khắp các contract. Đổi method là viết lại contract chứ không phải sửa một dòng config.

required

GitHub · Jira · Linear

Astragentic không ship tracker. Nó ship ba adapter là github-issue-tracker, jira-issue-tracker và linear-issue-tracker, mỗi adapter mô tả cách vận hành đúng một backend: status biểu diễn thế nào, claim ghi ở đâu, blocking edge diễn đạt ra sao.

Thứ cố định không phải adapter mà là .agents/tracker-contract.md: năm thứ mà pipeline cần ở bất kỳ tracker nào. Nhờ vậy Thomas đọc docs/agents/issue-tracker.md, biết dự án này dùng adapter nào, rồi thao tác y hệt nhau bất kể backend.

Đánh đổi. Đã nêu ở trang vì sao: mỗi backend mang theo cái bẫy riêng, và GitHub Issues không có trường status thật nên status phải nằm trong label.

required

Python · Bash

Phần Python và Bash tôi tự viết. Ba script đại diện cho ba loại:

  • hook-git-guard.py. Chặn trong lúc quyền còn đang được quyết.
  • herdr-watchdog.sh. Chạy nền suốt session và phải đang chạy trước mọi dispatch.
  • ledger-index.sh. Chạy sau khi payload đổi, không phải sau khi công việc đổi.

Luật tôi rút ra: mỗi script phải có một khoảnh khắc gọi và một người sở hữu. Script thiếu một trong hai là script không ai chạy cho tới khi mọi chuyện đã hỏng.

Đánh đổi. Bản 2.5.0 là bằng chứng ngược: nó ship adapter mang id ticket thật của một dự án khác, một index đã cũ, và hai contract vượt hạn mức chữ. Ba loại lỗi, không loại nào nhìn thấy được bằng cách đọc, tất cả do một giờ làm việc cẩn thận trước đó sinh ra. Bản 2.5.1 là đúng ba cái vá đó và không có gì khác.

optional

archify

Mọi diagram trên trang này được dựng bằng archify. Nguồn là JSON ở content/site/diagrams/<slug>.<type>.json, đầu ra là HTML đứng độc lập cùng SVG nhúng, nên một hình vừa bấm được trên trang vừa đọc được ngoài trang.

Diagram được mô tả bằng dữ liệu thay vì vẽ tay, vì trang này song ngữ. Mỗi diagram có một bản dịch ở content/site/diagrams/vi/, dịch title, label, nhãn edge, tên lane và note, giữ nguyên tên role, tên skill, lệnh, mã AST và tên file. Vẽ tay hai lần thì hai bản sẽ lệch nhau ở lần sửa thứ ba.