diff --git a/docs/audit-cafekit-vs-claude-code-2026-07.md b/docs/audit-cafekit-vs-claude-code-2026-07.md new file mode 100644 index 0000000..b9bf91f --- /dev/null +++ b/docs/audit-cafekit-vs-claude-code-2026-07.md @@ -0,0 +1,234 @@ +# Audit toàn diện CafeKit v0.13.2 — đối chiếu Claude Code 2026 + +> **Ngày audit:** 2026-07-13 · **Bản audit:** `@haposoft/cafekit` 0.13.2 (branch `dev`, commit `1250304`) +> **Phương pháp:** duyệt 100% package `packages/spec/` (installer 27 file, 10 hooks + 7 lib, 7 scripts, 30 skills, 13 agents, 8 rules, references, archive, OpenCode port) + tra cứu changelog/docs chính thức Claude Code 02–07/2026 + đối chiếu field test v0.13.0 (`notes/v0.13.0-field-test-post-list-screen.md`). +> **Phạm vi:** không gồm `cafekit-web/`. + +--- + +## PHẦN 1 — GIẢI PHẪU TỪNG THÀNH PHẦN + +### 1.0 Bức tranh tổng thể + +CafeKit = **1 installer + 1 bộ runtime payload**. `npx @haposoft/cafekit` → copy payload vào `.claude/` (hoặc `.opencode/`). Tổng ~35–40K LOC: + +| Khối | Khối lượng | Vai trò | +|---|---|---| +| `bin/` installer | 198 (orchestrator) + 2.855 (lib) + 1.478 (phases) | Cài đặt/upgrade an toàn | +| 30 skills | 7.690 dòng SKILL.md, ~20K+ LOC cả references/scripts | Workflow + domain knowledge | +| 13 agents | 1.375 dòng | Subagent chuyên trách | +| 10 hooks + 7 lib | ~1.500 + 3.000 dòng | Cưỡng chế kỷ luật runtime | +| 7 scripts | ~1.770 dòng | Validator/scaffold deterministic | +| 8 rules + CLAUDE.md | 570 + 130 dòng | Hiến pháp hành vi | +| `status.cjs` | 541 dòng | Statusline đa dòng | +| OpenCode port | AGENTS.md + 7 plugins ~1.440 dòng | Runtime thứ hai | +| Self-test | 1.505 dòng (`run-skill-self-tests.mjs`) | `npm test` | +| `archive-command/` | 1.679 dòng | **Legacy chết** (không được cài) | + +### 1.1 Installer (`bin/`) + +**Kiến trúc:** `install.js` là orchestrator mỏng chạy tuần tự phase handlers, mỗi phase nhận/trả `ctx`. + +``` +lock → context/args → chọn ngôn ngữ (en/ja/vi) → chọn platform → check version +→ snapshot backup → [per-platform: copy payload → runtime files → merge settings +→ CLAUDE.md → rules → metadata] → gitignore → post-install (addressing, Gemini key) +→ skills-setup (venv/pip/npm/Chromium, opt-in) → rtk setup (opt-in) → summary → prune backup +``` + +**4 cơ chế an toàn:** +1. **Process lock** (`.cafekit.lock`) — PID + timestamp, stale-PID reclaim. +2. **Snapshot backup** (`.cafekit-backup//`) — crash → restore tự động; giữ 3 bản. +3. **Ownership manifest** (`cafekit-manifest.json`) — SHA-256 mọi file CafeKit ghi; upgrade so 3 hash (đĩa/baseline/payload) → `absent|pristine|user-modified|user-created`; file user sửa được **preserve** mặc định (chỉ đè khi `--force-overwrite`). Đây là điều plugin system không làm được. +4. **`--dry-run`** — preview không ghi. + +**Flags:** `--dry-run`, `--force-overwrite` (alias `--upgrade/-u/-f`), `--with-skills-deps`, `--with-rtk`, `--yes`, `--lang`, `--help`, `--version`. Có re-exec khi chọn version khác. + +**8 điểm fragile đã xác minh:** +- `bin/lib/i18n.js:373` — `--lang` mã lạ rơi về **ja** thay vì en. +- `bin/phases/claude-settings.js:112` — merge settings dedupe theo **sub-command đầu tiên** → upgrade thêm command vào entry cũ bị nuốt. +- `claude-settings.js:85-88` — user `settings.json` hỏng → throw → abort cả install. +- `install.js:162` — file root OpenCode (`opencode.json`, `AGENTS.md`) **ngoài snapshot** → crash không rollback. +- `opencode-install.js` (866 dòng) — toàn bộ writer OpenCode **bỏ qua ownership model**, không dry-run aware. +- Mất `cafekit-manifest.json` → update thành near-noop (mọi file thành `user-created` → preserve). +- `commands.core: []` → fallback command cũ trong `copy-payload.js:37` là dead code. +- Semver so sánh naive (không prerelease); multi-platform chỉ so version platform đầu. + +### 1.2 CLAUDE.md + 8 rules + +- **CLAUDE.md** (130): 4 khối hành vi (Think-Before-Coding/Simplicity-First/Surgical-Changes/Goal-Driven), Operating Loop, Definition-of-Done, 7 Non-Negotiable Gates. Dòng 61 chấp nhận tool vắng mặt (fallback markdown). **Addressing canary**: danh xưng cố định làm chỉ báo tràn context. +- **8 rules** (570): `workflow` (`PRECHECK_FAIL` > `NO_TESTS`), `ai-dev-rules`, `skill-workflow-routing` + `skill-domain-routing` (advisory router thay hook router đã gỡ), `orchestrator` (status block DONE/CONCERNS/BLOCKED/NEEDS_INFO), `manage-docs`, `state-sync` (Tollgate 2 lớp), `hook-protocols`. +- **Xác minh:** prefix `hapo:` **nhất quán** giữa skills và rules. Lệch chỉ ở `archive-command/` (legacy) và `impact-analysis` (bug). + +### 1.3 Hooks (10) — đọc trực tiếp từng dòng + +Tất cả có crash-wrapper **fail-open** (log `hooks/.logs/hook-log.jsonl`). + +| Hook | Event | Chức năng | +|---|---|---| +| `session.cjs` (260) | SessionStart `startup\|resume\|clear\|compact` | Detect project/PM/framework; ghi 13 env vars vào `CLAUDE_ENV_FILE`; check update npm (cache 12h); cảnh báo sau compact (re-confirm quyền) | +| `docs-sync.cjs` (103) | SessionStart | Git hash source (exclude docs) vs `docs/.sync_hash` → ép tạo/update docs | +| `state.cjs` (286) | SessionStart + PostToolUse(`Agent\|Task\|TaskCreate\|TaskUpdate\|TodoWrite`) + Stop + SubagentStop | Persist `session-state/latest.md` (todos từ transcript + git modified); archive 5 bản, expiry 7 ngày; inject "Prior Execution Context" | +| `agent.cjs` (106) | SubagentStart `*` | Inject ~100 tok (language/paths/venv) qua `hookSpecificOutput.additionalContext` — đúng schema mới | +| `rules.cjs` (122) | UserPromptSubmit | Inject rules reminder ~250 tok, cooldown 5 phút/session | +| `spec-state.cjs` (135) | UserPromptSubmit | **Tollgate**: fingerprint `phase\|done/total` → không đổi = 1 dòng; đổi = block đỏ ~460 tok (bắt sync spec.json + task md + validator) | +| `usage.cjs` (190) | UserPromptSubmit + PostToolUse(Edit/Write), timeout 30 | Quota từ **OAuth API không chính thức** (`api.anthropic.com/api/oauth/usage`, token từ Keychain/`.credentials.json`) → cache cho statusline | +| `privacy-block.cjs` (179) | PreToolUse(Read/Write/Edit/Bash/Glob/Grep) | 15 pattern nhạy cảm; exempt `.env.example`; block + JSON `@@PRIVACY_PROMPT@@` → AskUserQuestion; Bash warn-allow (đường approved) | +| `inspect-block.cjs` (124) | PreToolUse (cùng matcher) | Chặn `node_modules/dist/.git/...` + broad glob; whitelist lệnh build/PM | +| `task-scaffold-guard.cjs` (91) | PreToolUse(`Write`) | Chặn Write vào `specs/*/tasks/task-*.md` → ép scaffold + Edit-fill. 3 van: fail-open thiếu script; message kèm lệnh; escape hatch runtime.json | + +**hooks/lib** (3.000): `config.cjs` 839, `context.cjs` 616, `detect.cjs` 474, `parser.cjs` 182, `git.cjs`, `color.cjs`, `counter.cjs`. +**Chi phí context/turn sau 0.13.0:** thường ~40–60 tok; đỉnh ~700–900 khi state đổi. + +### 1.4 Scripts kiểm định (7) — "enforce bằng code, không van xin bằng prompt" + +1. `validate-spec-output.cjs` (457) — **Layer 1 structural**: task_files khớp đĩa; registry đủ 8 trường; regex tên task; cấm reuse timestamps; placeholder `{{...}}` = hard fail; coverage `R{N}`/`R{N}.{M}` (sub-criteria opt-in); **contract drift** byte-compare; ≥5 task ⇒ bắt validation review. +2. `spec-ground.cjs` (146) — **Layer 2 grounding**: grep work-tree thật — mọi path Modify/Delete/Read phải tồn tại hoặc được Create trước đó trong spec. Active, không né được. `--root` cho monorepo. +3. `spec-scaffold.cjs` (187) — sinh stub để Edit-fill (chống 935K output tokens). `--tasks-only` merge không đè task đã fill. +4. `generate-skill-catalog.cjs` (180) — catalog từ frontmatter. +5. `validate-docs-reconstruct.cjs` (176) — validate bundle as-is 12 file + evidence ID cross-ref. +6. `validate-docs.cjs` (69) — ⚠️ chỉ check link tương đối, **luôn exit 0** — gate trang trí. +7. `browser-tool.cjs` (138) — ⚠️ **mồ côi** (chỉ trong manifest, không ai gọi). + +### 1.5 Skills (30) + +**Core workflow (16):** specs (662 — flagship), develop (263), question (167), brainstorm (190), debug (254, diagnostic-only), hotfix (298), test (193), code-review (96, 3-stage, PASS ≥9.5 & 0 critical), git (66), sync (48), docs (269, `--init/--update/--summarize/--reconstruct`), inspect (222), research (58, facade WebSearch), impact-analysis (276 + 6.6K refs), generate-graph (429 + 5K), ai-multimodal (92 + 5K Gemini scripts). + +**Khái niệm chính trong `specs`:** +- **SDD**: feature đi qua spec máy-đọc-được trước khi code. +- **Creation Mode**: Auto / Stop-after-Design / Step-by-step. +- **5-dimension**: Intent, Hypothesis, Gap size, **Cynefin** (Clear/Complicated/Complex/Chaotic — Chaotic → hotfix), Blast Radius. +- **Execution Tier** Light/Standard/Deep — quality floor (scope_lock, EARS, L1+L2) không bao giờ skip. +- **scope_lock**: `in_scope/out_of_scope/expansion_policy: requires-user-approval`. +- **EARS**: 5 mẫu câu requirement (When/While/If/Where/shall) + ID literal `R{N}.{M}`. +- **DoCT**: 7 yếu tố task hoàn chỉnh, mỗi yếu tố map tới 1 cơ chế enforce. +- **Red-team evidence-gated**: 4 persona; finding không trích dẫn cụ thể bị auto-reject. +- **Complexity smell**: >8 files/>2 services/>12 tasks → challenge; >15 → bắt tách spec. + +**`develop`:** Load (check `ready_for_implementation`) → scout `inspector` bắt buộc → implement (`god-developer`) → Self-Healing Quality Gate (test-runner + code-auditor song song, retry max 3 → COLLAPSE) → **verification receipt** → sync 2 lớp. Modes: Specific-Task / Full-Spec / `--flash` (FLASH_UNVERIFIED) / implementation-notes. + +**Domain (14):** backend, frontend-design, frontend-development, react-best-practices (50 rule), ui-ux-pro-max (664 + 1.3MB CSV), mobile, devops, web-testing, agent-browser, chrome-devtools (**4.454 files — commit cả node_modules Puppeteer, ~300MB Chromium**), pdf/pptx/docx/xlsx (**Anthropic stock skills** © 2025 Anthropic bị re-badge `author: haposoft` — vấn đề provenance). + +### 1.6 Agents (13, 1.375 LOC) + +`god-developer` (sonnet, Single-Track builder), `spec-maker` (opus, 224, phải đọc SKILL specs trước), `code-auditor` (5 trụ, read-only), `debugger` (sonnet, bắt buộc đọc 12 `references/debugger/`), `test-runner` (anti-illusion, verdicts PASS/FAIL/PRECHECK_FAIL/NO_TESTS), `inspector`, `git-ops`, `docs-keeper` (UPDATE-ONLY), `deployer`, `researcher` (haiku, **`memory: user`**), `brainstormer`, `project-manager`, `ui-ux-designer`. Nhiều agent mang toolset swarm `TaskCreate/SendMessage`. + +### 1.7 Statusline + runtime.json + +- `status.cjs` (541): statusline đa dòng — model/git/context bar/tool-agent-todo tracking/usage/timer. ⚠️ Hard-code `AUTOCOMPACT_BUFFER = 45000` (22.5% của **200K**) — sai với model 1M context. +- `runtime.json`: `privacyBlock`, `inspect.enabled`, `gemini.model` (⚠️ `gemma-4-31b-it` lệch với inspect `gemini-3-flash-preview` và script `gemini-3.1-flash-image-preview`), `statusline`, `docs.maxLoc`, `paths`, `locale`, `usage.enabled`, `spec.scaffold_guard`. ⚠️ Template thiếu key hooks có đọc (`spec`, `project`, `paths.plans`); thừa key chết (`skills.research.useGemini` — researcher dùng WebSearch native). + +### 1.8 References / archive / manifest + +- `references/debugger/` (12 file, 409 LOC) — **live**, debugger agent bắt buộc đọc; ship qua `agentReferences.copyRecursive`. +- `archive-command/` (1.679 LOC) — **chết**: path cũ `.specs/`, tên command trần, nhắc agent `code-reviewer` không tồn tại. Không trong manifest. +- `migration-manifest.json` (v2): 30 skills + 13 agents + 5 scripts + 20 runtime files; obsolete: `skill-router.cjs` (router cũ đã gỡ sạch). + +### 1.9 OpenCode port + +`AGENTS.md` (140) + 7 plugins TS (docs-sync, inspect-block, privacy-block, rules, session, state, usage). **Thiếu 3 hooks quan trọng nhất**: `spec-state` (tollgate), `task-scaffold-guard`, `agent` (subagent seeding) → OpenCode mất kỷ luật spec-workflow, chỉ còn "lời dặn". Mâu thuẫn nội bộ: `session.ts:153-159` bảo dùng `AskUserQuestion` trong khi `AGENTS.md:85` nói tool không tồn tại. + +--- + +## PHẦN 2 — CLAUDE CODE 02–07/2026 (nền đánh giá) + +1. **Plugins & Marketplaces** — kênh phân phối **khuyến nghị** thay copy file vào `.claude/`. Plugin ship: skills (`/plugin:skill`), agents, hooks, MCP, statusline. Breaking v2.1.207: plugin config không đọc từ project settings; cấm `${...}` shell expansion trong plugin hooks. +2. **Skills** — frontmatter mở rộng (`disable-model-invocation`, `model`, `allowed-tools`); stacked invocation (max 5); `.claude/commands/` chỉ còn backward-compat. +3. **Hooks** — ~30 events; mới đáng chú ý: **`TaskCreated`/`TaskCompleted`**, **`PreCompact`/`PostCompact`**, `UserPromptExpansion`. Breaking v2.1.195: matcher exact-match (regex `A|B` vẫn OK). `additionalContext` cap 10KB. +4. **Subagents** — background mặc định (v2.1.198), `isolation: "worktree"`, `memory: true`, nesting 5 cấp; `TeamCreate/TeamDelete` đã gỡ (v2.1.178). +5. **Task system** — `TaskCreate/Update/List/Get` + **`blockedBy` dependencies**, chia sẻ đa agent. +6. **Memory** — auto-memory `~/.claude/projects//memory/MEMORY.md`; framework không nên đè. +7. **Context** — compaction hooks; `/rewind` checkpoints; `/effort`, `/fast`. +8. **Statusline** — thêm `subagentStatusLine`. +9. **Settings** — precedence Managed > CLI > Local > Project > User; tolerant parsing. +10. **Verification** — guidance chính thức: *hooks cho must-enforce, CLAUDE.md cho behavioral, skills cho workflow, Tasks cho dependency* — trùng triết lý CafeKit. + +--- + +## PHẦN 3 — ĐÁNH GIÁ & KHUYẾN NGHỊ + +### 3.1 Verdict + +- **Triết lý: phù hợp, thậm chí đi trước.** Enforce bằng hooks, evidence-first, deterministic gates — CafeKit làm từ đầu 2026, nay thành guidance chính thức. Bộ ba validator L1 + grounding L2 + scaffold-guard là tài sản quý nhất (field test chấm spec 9/10). +- **Cơ chế: lệch pha 3 chỗ.** (1) Copy-file vs plugin-first; (2) hạ tầng tự chế đã có native tốt hơn (usage OAuth hack, tollgate mỗi-prompt vs TaskCompleted hook); (3) prompt đồ sộ thiết kế cho model đời cũ — model 2026 tuân thủ tốt, phần "quát tháo" tốn attention hơn được việc. +- **Bài học field test:** 2/3 cơ chế opt-in bị AI né hợp lý → *mọi gate phải mandatory-có-van-xả như scaffold-guard, hoặc đừng làm*. + +### 3.2 GIỮ NGUYÊN + +| Thành phần | Lý do | +|---|---| +| 3 validators + scaffold-guard | Moat thật; pattern chuẩn mực (fail-open chủ đích, van xả, message kèm lệnh) | +| Ownership manifest + snapshot/lock | Plugin không thay được "user sửa file không mất khi update" | +| Two-layer state + verification receipt | Persistent qua session; 0.13.0 bỏ hydration là đúng | +| `privacy-block` AskUserQuestion flow | Native `permissions.deny` không có luồng xin-phép-từng-file | +| Evidence gate + red-team | Nguồn chất lượng thật (field test) | +| `agent.cjs` schema `hookSpecificOutput` | Đã đúng chuẩn mới | + +### 3.3 SỬA NGAY (bug cụ thể, 1–2 ngày) + +1. `skills/specs/SKILL.md:164` — off-by-one "Steps 1-8" → **1-7**. +2. `skills/generate-graph/SKILL.md:3` — frontmatter `description` **rỗng** + thiếu `argument-hint` → vỡ auto-invocation/catalog. +3. `agents/ui-ux-designer.md:29-32` — hard-code path monorepo `packages/spec/src/claude/skills/...` → phải là `.claude/skills/...`. +4. `bin/lib/i18n.js:373` — `--lang` mã lạ → fallback `en` (hiện rơi về `ja`). +5. `bin/phases/claude-settings.js:112` — dedupe theo `hooks[0].command` → so toàn bộ command list. +6. `claude-settings.js:85-88` — try/catch user settings.json hỏng, báo lỗi thân thiện. +7. `runtime.json` — thống nhất model Gemini (3 nguồn 3 tên); bổ sung key `spec`/`project`; xoá `skills.research.useGemini`. +8. `skills/impact-analysis/SKILL.md` — `/review`→`/hapo:code-review`, `/impact-analysis`→`/hapo:impact-analysis`. +9. Xoá `archive-command/` (1.679 dòng chết) + `browser-tool.cjs` khỏi manifest. +10. Trả attribution Anthropic cho pdf/pptx/docx/xlsx (sửa `metadata.author`, giữ LICENSE.txt). +11. `opencode/plugins/session.ts:153-159` — bỏ chỉ dẫn AskUserQuestion (mâu thuẫn AGENTS.md:85). +12. **Validator multi-contract gap** (deferred 0.13.4): `extractTaskContracts` chỉ check block đầu tiên/task — fix ~10–15 dòng (parse mọi ``). +13. `frontend-design` — thêm LICENSE.txt được nhắc trong frontmatter, hoặc bỏ dòng nhắc. +14. `validate-docs.cjs` — exit 1 khi link gãy, hoặc đổi tên khỏi mang tiếng validator. + +### 3.4 NÂNG CẤP (khớp Claude Code 2026) + +1. **Tollgate → event-driven** (đòn bẩy lớn nhất): chuyển enforcement sang **`TaskCompleted` hook** (chạy validator + check receipt, chặn done "chay") + **`Stop` hook** (check sync trước khi kết thúc turn). UserPromptSubmit chỉ giữ 1 dòng nhắc. → Enforcement mạnh hơn, context nhẹ hơn. +2. **`PreCompact`/`PostCompact`** thay cảnh báo compact trong session.cjs; addressing canary chỉ còn là signature UX. +3. **`status.cjs`**: bỏ hard-code 200K/45000 — đọc context limit từ payload; thêm `subagentStatusLine`. +4. **`usage.cjs`**: OAuth endpoint + beta header 2025 là undocumented hack — đánh dấu experimental/fail rõ, thay bằng nguồn chính thức khi có. +5. **`develop` parallel wave**: `task_registry.dependencies` + subagent `isolation: "worktree"` + background default → chạy N task độc lập song song (cắt 1h38m của spec lớn — "đòn bẩy thật" field test đòi). +6. **Rà matchers v2.1.195** + thêm test settings-schema vào self-test suite. +7. **Dọn legacy tool-names** (`state-sync.md:18`, `spec-maker.md`, develop SKILL "Task tool legacy") → chuẩn `Agent`/`TaskCreate`; giữ 1 dòng fallback trong CLAUDE.md là đủ. +8. Mở rộng `memory` cho `inspector`/`debugger` (researcher đã có). + +### 3.5 REMAKE (kiến trúc) + +1. **Plugin-first, installer-second:** + - Plugin `cafekit-core`: workflow skills + agents + hooks + statusline (lưu ý: plugin hooks cấm `${...}` — viết lại exec-form). + - Plugin `cafekit-extras`: 14 domain skills — tách `chrome-devtools` (4.454 files/300MB) + bộ Office khỏi core. + - Installer giữ cho: OpenCode, CLAUDE.md/rules merge, addressing, `runtime.json`, ownership manifest. + - Lộ trình 3 phase: (1) publish marketplace.json; (2) tách extras; (3) co installer. +2. **OpenCode: quyết định chiến lược.** Port nốt 3 hooks thiếu (nếu OpenCode có surface) hoặc chính thức ghi tier-2 "advisory mode". Nửa vời hiện tại là tệ nhất. + +### 3.6 TINH GỌN FLOW (giữ xương sống enforce-bằng-code, cắt mỡ prompt) + +1. `specs` SKILL.md 662 → ~350-400 dòng: rule đã có validator enforce chỉ cần 1 câu "validator sẽ chặn" (hiện lặp ≥3 chỗ). +2. Giảm tông "URGENT/CẤM/🔴" — model 2026 không cần quát; hook chặn thật > 10 dòng caps-lock. +3. Routing rules 177 dòng → dựa native skill discovery (description chuẩn) + bảng rút gọn ~30 dòng cho ca nhập nhằng. +4. Gộp/mỏng: `inspect` internal = wrapper quanh `Explore` native → rút thành reference + giữ nhánh Gemini; cân nhắc gộp `sync` (48 dòng) vào develop/specs. +5. Chốt 1 tên chuẩn cho Evidence heading (hiện 3 alias xuyên 6 file). +6. **Không đụng quality floor**: scope_lock, EARS mandatory; contract markers → làm mandatory cho spec đa tầng BE+FE (hoặc gỡ, tránh "ảo tưởng an toàn"). + +### 3.7 Bảng ưu tiên + +| # | Việc | Loại | Effort | Impact | +|---|---|---|---|---| +| 1 | 14 bug mục 3.3 | Fix | Thấp | Trung bình — có cái gây sai thật (i18n, settings-merge) | +| 2 | Tollgate → TaskCompleted/Stop hooks | Upgrade | Trung bình | **Cao** | +| 3 | Contract marker mandatory cho spec đa tầng (hoặc gỡ) | Fix incentive | Thấp | Cao | +| 4 | Develop parallel wave (worktree) | Upgrade | Trung bình–cao | **Cao** | +| 5 | Tinh gọn specs SKILL + routing | Slim | Trung bình | Trung bình–cao | +| 6 | Plugin-first distribution | Remake | Cao | Cao dài hạn | +| 7 | Số phận OpenCode port | Chiến lược | — | Trung bình | +| 8 | status.cjs 1M-context + usage.cjs de-risk | Upgrade | Thấp | Thấp–trung bình | + +### Câu hỏi mở + +1. Bắt đầu từ gói bug-fix #1 hay tollgate event-driven #2? +2. Plugin-first (#6): tạo spec `/hapo:specs` cho lộ trình 3 phase trước khi động tay? +3. OpenCode: giữ tier-1 hay chấp nhận tier-2 advisory? + +--- + +*Nguồn: audit trực tiếp source `packages/spec/` (path:line trong thân bài); changelog & docs chính thức Claude Code (code.claude.com/docs, github.com/anthropics/claude-code); field test `notes/v0.13.0-field-test-post-list-screen.md`; memory dự án (validator multi-contract gap, hooks backlog 0.13.2).* diff --git a/docs/installer-architecture.md b/docs/installer-architecture.md index 88bb64b..304b8ad 100644 --- a/docs/installer-architecture.md +++ b/docs/installer-architecture.md @@ -47,7 +47,8 @@ bin/lib/ 4. **Snapshot** — back up platform folders + root `CLAUDE.md`/`.gitignore` (skipped in dry-run). 5. **Per platform** — read ownership baseline, start a tracker, then: copy payload → claude-runtime *or* opencode-runtime → write metadata + manifest. -6. **Root config** — ensure `.gitignore` patterns (incl. `.cafekit-backup/`, `.cafekit.lock`). +6. **Root config** — ensure `.gitignore` patterns (incl. `.claude/`, `.opencode/`, + `.cafekit-backup/`, `.cafekit.lock`). 7. **Post-install** — OpenCode model, Gemini, addressing (re-records CLAUDE.md baseline). 8. **Skills setup** — opt-in: Python venv, pip deps, skill npm, Chromium; detect system tools. 9. **rtk setup** — opt-in: rtk binary + hook registration for token-saving on Bash commands. @@ -75,9 +76,16 @@ A file written earlier in the same run (e.g. spec templates copied by the `specs tree, then revisited by the template-sync loop) is treated as pristine via the tracker's in-run record, avoiding false "user-created" classification. -The ownership manifest should be **committed** in the consumer project so a teammate's -clone shares the baseline; otherwise their first install would treat committed -`.claude/` files as user-created and never update them. +By default the installer gitignores the runtime folders (`.claude/`, `.opencode/`) +at project root — reinstall with `npx @haposoft/cafekit` on each machine. The +ownership manifest therefore lives only on disk as a local re-install baseline. +If a team deliberately force-adds and commits the runtime folder, they should +also commit the ownership manifest so teammates share the baseline; otherwise +their first install would treat those files as user-created and never update them. + +A second layer lives inside the runtime: `.claude/.gitignore` / +`.opencode/.gitignore` (from `src/claude/gitignore`) ignore secrets, skill +deps, session state, and logs so force-adds stay safe. ## Safety properties diff --git a/docs/project-changelog.md b/docs/project-changelog.md index 2c8f765..7d14c5d 100644 --- a/docs/project-changelog.md +++ b/docs/project-changelog.md @@ -27,6 +27,23 @@ All notable changes to CafeKit are documented here, following - **`session.cjs` env escaping**: `writeEnv` now escapes `\ $ \` "` (was `"` only), so an attacker-influenced value flowing into `CLAUDE_ENV_FILE` (e.g. a git branch named `` evil$HOME-x`pwd` ``) can no longer expand or execute when the env file is sourced. Matches the canonical `escapeShellValue` semantics in `lib/config.cjs`. - **`privacy-block.cjs` symlink bypass**: the sensitive-file gate now resolves symlink targets via `fs.realpathSync` and checks both the requested name and its real target, closing the bypass where a harmless-looking symlink (e.g. `notes.txt` → `.env`) slipped past the basename check. Exemptions (`.env.example`) still win on either name; fail-open when the path cannot be resolved. +## [0.13.4] - 2026-07-15 + +### Added +- **`hapo:delegate`**: offload a scoped coding task to Codex or Grok CLI from Claude Code (brief file, sandbox, monitor/resume, independent verify). Wired into skill routing + migration manifest. +- Installer dual-layer gitignore: root ignores `.claude/` and `.opencode/`; in-folder `.gitignore` covers secrets, skill deps, session state, and logs. + +### Docs +- CafeKit vs Claude Code audit (2026-07); installer architecture + README gitignore policy. + +## [0.13.3] - 2026-06-22 + +### Added +- Validator placeholder gate for unfilled scaffold stubs (hard-fail on leftover `{{...}}` in task files). + +### Changed +- Specs self-tests / Step 7 wording realigned to process-discipline (not token-cut) framing. + ## [0.13.2] - 2026-06-21 ### Added — Enforce scaffold on task creation diff --git a/packages/spec/CHANGELOG.md b/packages/spec/CHANGELOG.md index 972945f..914b706 100644 --- a/packages/spec/CHANGELOG.md +++ b/packages/spec/CHANGELOG.md @@ -35,12 +35,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **`spec-state.cjs` tollgate reminder slimmed**: state-change path is now a compact English block (≤7 lines: feature, phase, task counts, next unblocked task, sync/validate rule, Stop-gate note). Removed the red ALL-CAPS / bilingual MANDATORY wall (`URGENT`, `BẮT BUỘC`, `CẤM`). One-line unchanged-fingerprint path is unchanged. Completion enforcement moved to `spec-gate.cjs` on Stop. - Installer obsolete mechanism removes directories recursively and prunes ownership-manifest entries by prefix (`tracker.prunePrefix`), enabling skill-level cleanup on upgrade. +## [0.13.4] - 2026-07-15 + +### Added +- **`hapo:delegate` skill**: dispatch a scoped implementation task from Claude Code to an external agent CLI (**Codex** or **Grok**). Covers file-based task briefs, non-interactive dispatch, minimum permissions, background monitoring/resume, and **independent verification** of the returned work (agent claims are not evidence). +- Codex / Grok reference guides under `skills/delegate/references/` with verified CLI flags and pitfalls. +- Workflow routing: assign/offload intents map to `/hapo:delegate` in `skill-workflow-routing.md`. +- `migration-manifest.json`: `delegate` added to required skills so the installer ships it. + +### Changed — Installer gitignore (runtime out of git by default) +- **Root `.gitignore`**: `ensureGitignore` now also adds `.claude/` and `.opencode/` so the local CafeKit payload is not committed. Reinstall with `npx @haposoft/cafekit` on each machine. Existing equivalent forms (`.claude` without trailing slash) are treated as already present. +- **In-folder `.claude/.gitignore` / `.opencode/.gitignore`**: expanded template (`src/claude/gitignore`) with layered ignores for secrets, skill venvs/`node_modules`, session state, hook/plugin logs, and update cache — defense in depth for force-adds and partial un-ignores. + +### Docs +- Audit note: `docs/audit-cafekit-vs-claude-code-2026-07.md` (full package inventory vs Claude Code practices as of v0.13.2). +- Installer architecture + package README document the dual-layer gitignore policy. + +## [0.13.3] - 2026-06-22 + +### Added +- **Validator placeholder gate (`validate-spec-output.cjs`)**: a task file that still carries an unfilled `{{...}}` scaffold placeholder now hard-fails (previously a prompt-only DoCT rule); a leftover `.../` path fragment warns. Fill-side complement to the scaffold-guard hook — it proves every scaffolded stub was actually completed, closing the "stub created but not filled" gap. + +### Changed +- Self-tests realigned to the Specs-v2 `SKILL.md` wording (`validate guardrail`, `init-is-never-a-stop-point`): the invariants are unchanged, only the asserted phrasing. +- `skills/specs/SKILL.md` Step 7: dropped the misleading "scaffold cuts output tokens" claim — scaffold enforces process discipline, not a token cut. + ## [0.13.2] - 2026-06-21 ### Added — Enforce scaffold on task creation - **`task-scaffold-guard.cjs` (PreToolUse hook)**: hard-blocks any `Write` whose path matches `specs//tasks/task-*.md`, so task files can only be created via `spec-scaffold.cjs` and then `Edit`-filled. Closes the dodge where the model hand-`Write`s task files and bypasses the (previously opt-in) scaffold step. Narrow scope: only the `Write` tool on a task-file path is blocked; `Edit`/`MultiEdit` and `Write` to any other file are untouched, and the scaffold script (writing via Node fs through Bash) is never blocked. - **Three safety valves**: fail-open when `spec-scaffold.cjs` is absent (a hook shipped without its script must not deadlock task creation); actionable block message carrying the exact scaffold command; escape hatch via `"spec": { "scaffold_guard": false }` in `.claude/runtime.json`. -- **Validator placeholder gate (`validate-spec-output.cjs`)**: a task file that still carries an unfilled `{{...}}` scaffold placeholder now hard-fails (previously a prompt-only DoCT rule). A leftover `.../` path fragment warns. This is the fill-side complement to the guard — the hook forces task files through the scaffold; this proves the resulting stubs were actually completed, closing the "stub created but not filled" gap. ### Changed - `settings/settings.json`: registered the guard under a dedicated `Write` matcher in `PreToolUse` (separate entry so the settings-merge dedupe does not swallow it). diff --git a/packages/spec/README.md b/packages/spec/README.md index b9cc23e..77b520b 100644 --- a/packages/spec/README.md +++ b/packages/spec/README.md @@ -2,7 +2,7 @@ > Claude Code-first spec-driven workflow and runtime bundle for AI coding assistants. -[![Version](https://img.shields.io/badge/version-0.9.3-blue.svg)](https://github.com/haposoft/cafekit) +[![Version](https://img.shields.io/badge/version-0.13.4-blue.svg)](https://github.com/haposoft/cafekit) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) [![Claude%20Code](https://img.shields.io/badge/Claude%20Code-Primary-orange.svg)](https://claude.ai/code) @@ -46,6 +46,26 @@ Requirements: - Node.js 18+ - Claude Code project with `.claude/`, OpenCode project with `.opencode/` or `opencode.json`, or choose a runtime when prompted +## Git ignore policy + +On install, CafeKit updates the **project-root** `.gitignore` with: + +```text +# CafeKit / Ecosystem +specs/_shared/ +plans/ +!plans/templates/ +.cafekit-backup/ +.cafekit.lock +.claude/ +.opencode/ +``` + +Runtime folders are local — reinstall with `npx @haposoft/cafekit` rather than +committing them. Inside the runtime, CafeKit also installs `.claude/.gitignore` +(or `.opencode/.gitignore`) so secrets, skill dependencies, session state, and +hook logs stay out of git even if someone force-adds the folder. + ## What Gets Installed Claude Code targets: diff --git a/packages/spec/bin/phases/root-config.js b/packages/spec/bin/phases/root-config.js index bcddeb7..60a2213 100644 --- a/packages/spec/bin/phases/root-config.js +++ b/packages/spec/bin/phases/root-config.js @@ -1,13 +1,29 @@ /** * Phase: root project configuration (.gitignore). * - * Ensures the root .gitignore carries CafeKit-managed patterns, including the - * new install backup dir and lock file so they never get committed. Honors dry-run. + * Ensures the root .gitignore carries CafeKit-managed patterns: + * - workflow dirs (plans, shared research) + * - install safety artifacts (backup, lock) + * - runtime folders (.claude/, .opencode/) — reinstall via + * `npx @haposoft/cafekit`; do not commit the local payload + * + * Layered with the in-folder `.claude/.gitignore` / + * `.opencode/.gitignore` templates (secrets, skill deps, session + * state) so force-adds and partial un-ignores stay safe. + * + * Honors dry-run. */ const fs = require('fs'); const path = require('path'); +/** True if `lines` already carries `pattern` with or without a trailing slash. */ +function hasPattern(lines, pattern) { + const bare = pattern.replace(/\/$/, ''); + const withSlash = bare + '/'; + return lines.includes(pattern) || lines.includes(bare) || lines.includes(withSlash); +} + function ensureGitignore(ctx) { const gitignorePath = path.join(process.cwd(), '.gitignore'); const header = '# CafeKit / Ecosystem'; @@ -16,7 +32,10 @@ function ensureGitignore(ctx) { 'plans/', '!plans/templates/', '.cafekit-backup/', - '.cafekit.lock' + '.cafekit.lock', + // Local runtime payload — reinstall with npx; keep out of git + '.claude/', + '.opencode/' ]; const prefix = ctx.dryRun ? '[dry-run] ' : ''; @@ -30,7 +49,7 @@ function ensureGitignore(ctx) { const content = fs.readFileSync(gitignorePath, 'utf8'); const lines = content.split('\n').map((l) => l.trim()); - const missing = patterns.filter((p) => !lines.includes(p)); + const missing = patterns.filter((p) => !hasPattern(lines, p)); if (missing.length > 0) { let newContent = content; @@ -46,4 +65,4 @@ function ensureGitignore(ctx) { } } -module.exports = { ensureGitignore }; +module.exports = { ensureGitignore, hasPattern }; diff --git a/packages/spec/scripts/run-skill-self-tests.mjs b/packages/spec/scripts/run-skill-self-tests.mjs index f5ca32b..c2d7c89 100644 --- a/packages/spec/scripts/run-skill-self-tests.mjs +++ b/packages/spec/scripts/run-skill-self-tests.mjs @@ -179,7 +179,20 @@ async function runStaticSemanticTests() { assert: (content) => content.includes("session-state/") && content.includes("hooks/.logs/") && - content.includes("skills/**/node_modules/"), + content.includes("plugins/.logs/") && + content.includes("skills/**/node_modules/") && + content.includes("skills/**/.venv/") && + content.includes(".cafekit-update-cache.json"), + }, + { + label: "installer root gitignore ignores runtime folders", + file: "bin/phases/root-config.js", + assert: (content) => + content.includes("'.claude/'") && + content.includes("'.opencode/'") && + content.includes("'.cafekit-backup/'") && + content.includes("'.cafekit.lock'") && + content.includes("function hasPattern"), }, { label: "hapo:specs handoff block points to hapo:develop", diff --git a/packages/spec/src/claude/gitignore b/packages/spec/src/claude/gitignore index 28b6339..c7b02db 100644 --- a/packages/spec/src/claude/gitignore +++ b/packages/spec/src/claude/gitignore @@ -1,19 +1,26 @@ -# Environment and Sandbox credentials within .claude +# CafeKit local runtime (.claude/ or .opencode/) +# Also ignored at project root by the installer. This file protects +# force-adds (`git add -f`) and partial un-ignores of the runtime folder. + +# Secrets and local credentials .env .env.* !.env.example -# Virtual environments for python scripts (skills) +# Skill dependency installs (Python venv + npm) skills/.venv/ +skills/**/.venv/ +skills/**/node_modules/ .venv/ venv/ -skills/**/node_modules/ __pycache__/ +**/__pycache__/ *.pyc -# System generated state, caches, and logs +# Generated session state, caches, and logs session-state/ hooks/.logs/ +plugins/.logs/ agent-memory/ settings.bak.json .mcp.json diff --git a/packages/spec/src/claude/migration-manifest.json b/packages/spec/src/claude/migration-manifest.json index 42a2003..a097314 100644 --- a/packages/spec/src/claude/migration-manifest.json +++ b/packages/spec/src/claude/migration-manifest.json @@ -13,6 +13,7 @@ "chrome-devtools", "code-review", "debug", + "delegate", "develop", "devops", "docs", diff --git a/packages/spec/src/claude/rules/skill-workflow-routing.md b/packages/spec/src/claude/rules/skill-workflow-routing.md index 083a5d6..b113e84 100644 --- a/packages/spec/src/claude/rules/skill-workflow-routing.md +++ b/packages/spec/src/claude/rules/skill-workflow-routing.md @@ -66,6 +66,14 @@ Do not turn reconstructed docs directly into implementation. Human review must a Use `/hapo:research` for external knowledge. Use `/hapo:inspect` for local source truth. +## Delegation Workflow + +| User intent | Suggested skill | +|---|---| +| assign/offload an implementation task to an external agent CLI (codex, grok) | `/hapo:delegate` | + +Claude Code remains the orchestrator: it writes the task brief, dispatches, monitors, and independently verifies the returned work. + ## Output Artifact Workflow | User intent | Suggested skill | diff --git a/packages/spec/src/claude/skills/delegate/SKILL.md b/packages/spec/src/claude/skills/delegate/SKILL.md new file mode 100644 index 0000000..41befae --- /dev/null +++ b/packages/spec/src/claude/skills/delegate/SKILL.md @@ -0,0 +1,124 @@ +--- +name: hapo:delegate +description: "Delegate implementation tasks from Claude Code to external CLI agents (Codex or Grok). Covers task-brief authoring, non-interactive dispatch, permission setup, background monitoring, resume, and independent verification of the returned work." +user-invocable: true +when_to_use: "Invoke when the user asks to assign/offload a coding task to codex or grok, or to run work on an external agent CLI." +category: orchestration +keywords: [delegate, codex, grok, external-agent, offload, assign] +argument-hint: " " +metadata: + author: haposoft + version: "1.0.0" +--- +# Delegate to External Agents (Codex / Grok) + +Dispatch a well-scoped implementation task to an external agentic CLI — **Codex** (OpenAI) or **Grok** (xAI Grok Build) — from a Claude Code session acting as orchestrator. Claude Code stays responsible for: writing the task brief, choosing safe permissions, monitoring, and **independently verifying** the result before reporting completion. + +**Mantra:** Brief precisely, sandbox tightly, verify independently. + +## When to Use + +- User explicitly asks to hand a task to codex/grok ("giao cho codex", "assign to grok"). +- Parallel workstreams: Claude Code keeps orchestrating while an external agent implements a scoped task. +- Cross-checking: a second model implements or reviews independently. + +Do NOT delegate: tasks touching secrets/`.env`, deploys to shared environments, destructive migrations on live data, or tasks whose scope is still unclear (clarify first — a vague brief wastes an entire agent run). + +## Workflow + +### 1. Write the task brief (mandatory, file-based) + +External agents run **fresh-context** — they see none of your conversation. Write the brief to a file (convention: `plans/-task.md` in the target repo), never inline-only. Follow the orchestrator prompt rules (`.claude/rules/orchestrator.md`): the brief must be self-contained. + +Required sections: + +```markdown +# Task: + +> Self-contained brief for a fresh-context agent. Date: <YYYY-MM-DD>. +> FOUNDATION: <state of the working tree the agent builds on — branch, +> uncommitted changes it must NOT revert, verified test/build status> + +## Context — project, architecture, why this task exists +## Scope — numbered work items with exact file paths +## Constraints — what must NOT be touched (staging data, .env, deploys, + unrelated refactors); repo rules to obey (CLAUDE.md) +## Completion Criteria — verifiable, numbered +## Evidence required — exact commands whose output proves completion +``` + +Rules of thumb: +- Name exact files and line-level anchors where known; agents burn tokens rediscovering what you already know. +- State dependency order explicitly if this task builds on another agent's uncommitted work ("do NOT revert/stash existing changes"). +- Put user-pending decisions in Constraints as forbidden actions (e.g. "do NOT touch staging rows until user confirms"). + +### 2. Protect the working tree + +Before dispatch, snapshot state you cannot afford to lose: + +```bash +git stash push -u -m "backup: <reason>" && git stash apply -q # snapshot, keep tree intact +``` + +Prefer isolation when the task is risky or parallel to other edits: +- Grok: `--worktree=<name>` (built-in). +- Codex: run with `-C <worktree-dir>` after creating a git worktree yourself. + +If the agent must build on uncommitted changes, isolation is not possible — use the stash-backup pattern above and say so in the brief. + +### 3. Dispatch + +Load the matching reference for exact flags, permission model, and pitfalls: +- **Codex:** `./references/codex-delegation.md` +- **Grok:** `./references/grok-delegation.md` + +Common principles: +- Run non-interactive/headless mode in a **background** shell; both CLIs stream progress to stdout. +- Grant the **minimum** permission set that lets the agent write code and run its Evidence commands (npm/node). Never grant full-access/bypass modes for routine tasks. +- Model/effort overrides: pass explicitly rather than relying on user config, so the run is reproducible. +- Capture the output file path; check progress after ~20–30s to confirm the agent actually started (auth errors, bad flags, and permission blocks surface early). + +### 4. Monitor + +- Poll the background output periodically; look for permission-block messages — both CLIs degrade to "design-only" output instead of failing loudly when a write tool is blocked. +- If blocked on permissions: **resume the same session** with corrected flags (both CLIs support resume; see references) — context is preserved, work continues instead of restarting. +- Apply the 3-strike rule from `.claude/rules/orchestrator.md`: same failure 3+ times → stop, escalate to user with evidence. + +### 5. Verify independently (non-negotiable) + +External-agent claims are **not** evidence (CLAUDE.md: no completion claim without fresh proof from the current run). After the agent reports done: + +1. `git status` / `git diff` — confirm the changed file set matches the brief's Scope; flag out-of-scope edits. +2. Run the brief's Evidence commands yourself (tests, build). The agent's transcript of a test run does not count. +3. Check Completion Criteria one by one. +4. Report to user: what was delegated, what came back, verification results, and any deviations. + +### 6. Sync + +- Keep the brief file updated (checklist ticks / blockers) so it doubles as task state. +- If a spec (`specs/<slug>/`) governs the work, follow the Tollgate Protocol (`.claude/rules/state-sync.md`): update `spec.json` + task files only after verification passes. +- The user decides commit/merge/deploy — delegation ends at verified working-tree changes unless told otherwise. + +## Choosing Codex vs Grok + +Both are capable general coding agents; prefer the one the user names. If unspecified: + +| Factor | Codex | Grok | +|---|---|---| +| Isolation | manual git worktree + `-C` | built-in `--worktree=<name>` | +| Structured output | `--output-schema` (JSON Schema) | `--json-schema` | +| Self-verification | ask in the brief | `--check` flag appends a verify loop | +| Resume | `codex exec resume <id>` | `grok --resume <id>` | + +## Rules + +- Never grant `--dangerously-bypass-approvals-and-sandbox` (codex) or `bypassPermissions` (grok) for routine delegation. +- Never let an external agent touch `.env`, secrets, staging/production data, or run deploys. +- Never report the agent's own success claim as completion — verify first. +- Never re-dispatch a blocked task unchanged (BLOCKED ≠ retry; fix the cause: permissions, context, or scope). +- One writer per file set: don't run two agents (or an agent + yourself) editing the same files concurrently. + +## References + +- `./references/codex-delegation.md` — Codex CLI: exec mode, sandbox/approval model, resume, pitfalls +- `./references/grok-delegation.md` — Grok CLI: headless mode, worktree, permission rules, resume, pitfalls diff --git a/packages/spec/src/claude/skills/delegate/references/codex-delegation.md b/packages/spec/src/claude/skills/delegate/references/codex-delegation.md new file mode 100644 index 0000000..9dc456a --- /dev/null +++ b/packages/spec/src/claude/skills/delegate/references/codex-delegation.md @@ -0,0 +1,71 @@ +# Delegating to Codex CLI + +Verified against codex-cli 0.144.4 (2026-07). Re-check `codex exec --help` if flags fail — the CLI evolves quickly. + +## Preflight + +```bash +which codex && codex --version # installed? +codex doctor # auth + runtime health (slow; run only when suspicious) +``` + +User-level defaults live in `~/.codex/config.toml` (`model`, `model_reasoning_effort`, agents, MCP servers). Overrides via `-m` and `-c key=value` beat config — pass them explicitly for reproducible runs. + +## Non-interactive dispatch: `codex exec` + +Reads the prompt from an argument, or from **stdin** when the argument is `-`. Prefer stdin + brief file: + +```bash +codex exec \ + -m gpt-5.6-terra \ + -c model_reasoning_effort='"max"' \ + --sandbox workspace-write \ + -o /tmp/codex-last-message.txt \ + - < plans/<slug>-task.md +``` + +Run it in a background shell and poll the output. + +### Key flags + +| Flag | Notes | +|---|---| +| `-m <model>` | model ID, e.g. `gpt-5.6-terra` (note spelling: *terra*) | +| `-c model_reasoning_effort='"max"'` | TOML-parsed value — keep the inner quotes | +| `--sandbox <mode>` | `read-only` \| `workspace-write` \| `danger-full-access` | +| `-o <file>` | write the agent's final message to a file — easiest completion check | +| `-C <dir>` | working root (use for delegating into a git worktree) | +| `--add-dir <dir>` | extra writable dirs alongside the workspace | +| `--output-schema <file>` | JSON Schema constraining the final response | +| `--json` | JSONL event stream on stdout (machine parsing) | +| `--ephemeral` | don't persist session files | + +### Pitfalls + +- **`-a` / `--ask-for-approval` is TUI-only.** `codex exec` rejects it (`error: unexpected argument '-a' found`). Exec mode is implicitly `approval: never` — sandbox mode is your only control there. +- **`workspace-write` limits writes, not reads**, to: workdir, `/tmp`, `$TMPDIR`. Network is available. Commands needing writes outside (global installs) will fail — keep Evidence commands repo-local. +- **Effort value is TOML**: `-c model_reasoning_effort='"max"'` (double-quoted inside single quotes). Bare `max` may parse as a literal string too, but the quoted form is unambiguous. +- Startup banner echoes `model:`, `reasoning effort:`, `sandbox:` — **verify these lines** ~20s after dispatch instead of assuming flags took effect. +- User config may define agents/hooks/MCP servers that activate automatically; `--ignore-user-config` gives a clean run if they interfere. + +## Monitor & verify liveness + +```bash +# ~20-30s after dispatch: banner shows model/sandbox; then agent narration follows +head -c 1200 <output-file> +tail -c 1500 <output-file> # progress +cat /tmp/codex-last-message.txt # exists → run finished; content = final report +``` + +## Resume + +```bash +codex exec resume --last "<follow-up>" # most recent session +codex exec resume <SESSION_ID> "<follow-up>" # by id (session id printed in banner) +``` + +Use resume (not a fresh dispatch) when: permission-blocked mid-run, follow-up fixes after your verification failed, or continuing a design into implementation. + +## Review mode + +`codex review` (or `codex exec review`) runs a non-interactive code review of the current repo — useful as an independent second-opinion pass on another agent's diff. diff --git a/packages/spec/src/claude/skills/delegate/references/grok-delegation.md b/packages/spec/src/claude/skills/delegate/references/grok-delegation.md new file mode 100644 index 0000000..64dfe84 --- /dev/null +++ b/packages/spec/src/claude/skills/delegate/references/grok-delegation.md @@ -0,0 +1,84 @@ +# Delegating to Grok CLI (Grok Build) + +Verified against grok 0.2.101 (2026-07). Re-check `grok --help` if flags fail. + +## Preflight + +```bash +which grok && grok --version +grok models # available model IDs +``` + +## Non-interactive dispatch + +Two forms: + +```bash +# single-turn from a brief file (preferred for delegation) +grok --prompt-file plans/<slug>-task.md \ + --worktree=<slug> \ + --check \ + --permission-mode acceptEdits \ + --allow "Bash(npm:*)" --allow "Bash(node:*)" \ + --output-format plain + +# short single-turn prompt +grok -p "<prompt>" +``` + +Run in a background shell and poll the output. + +### Key flags + +| Flag | Notes | +|---|---| +| `--prompt-file <path>` | single-turn prompt from file | +| `-p, --single <prompt>` | single-turn inline prompt | +| `--worktree=<name>` | built-in git worktree isolation (grok-managed; see pitfalls) | +| `--check` | appends a self-verification loop (headless only) — use it | +| `--permission-mode <mode>` | `default` \| `acceptEdits` \| `auto` \| `dontAsk` \| `bypassPermissions` \| `plan` | +| `--allow "<RULE>"` / `--deny "<RULE>"` | permission rules, Claude Code syntax: `Bash(npm:*)`, `Write`, `Edit` | +| `-m <model>` / `--reasoning-effort` | model + effort overrides | +| `--max-turns <N>` | hard cap on agent turns | +| `--json-schema '<schema>'` | structured final output | +| `--output-format plain\|json\|streaming-json` | headless output format | +| `--resume <SESSION_ID>` | continue a session (context preserved) | +| `--best-of-n <N>` | run task N ways in parallel, pick best (headless) | + +## Permission model — the #1 pitfall + +`--permission-mode acceptEdits` **does not reliably unblock file writes in headless runs**; grok may report "Write tool blocked" and quietly degrade to a **design-only** response that reads like progress. It still exits 0. + +Mitigations: +- Add explicit allow rules for write tools on the first dispatch: `--allow "Write" --allow "Edit" --allow "StrReplace"` alongside `--allow "Bash(npm:*)" --allow "Bash(node:*)"`. +- After ~30s, grep the output for `blocked`/`chặn` — catch degradation early. +- If the run finished design-only: **resume the same session** with widened allows and an explicit apply instruction; grok picks up its own design and implements without re-exploring: + +```bash +grok --resume <SESSION_ID> --no-plan \ + --permission-mode acceptEdits \ + --allow "Write" --allow "Edit" --allow "StrReplace" \ + --allow "Bash(npm:*)" --allow "Bash(node:*)" \ + --check -p "Continue: apply the designed changes, run tests, report results." +``` + +Even with allows granted, shell may still be policy-restricted (runs finish with "npm test BLOCKED — shell not pre-approved"). That's fine: **you run the Evidence commands yourself during verification** — do not loosen to `bypassPermissions` just to make the agent self-verify. + +## Worktree pitfalls + +- `--worktree=<name>` worktrees are **grok-managed**: they may not appear in the target repo's `git worktree list` and `grok worktree list` may still say "No worktrees found". **Do not trust either listing** — after the run, check `git status` in the main repo to find where changes actually landed. In practice (0.2.101, resumed sessions) grok can write **directly into the main working tree** despite the flag. +- Consequence: always take a stash-backup snapshot before dispatch (`git stash push -u -m "backup: ..." && git stash apply -q`), and treat the main tree as potentially modified. + +## Session management + +```bash +grok sessions list # ids + summaries +grok --resume <SESSION_ID> [flags] -p "..." # continue with same context +grok export <SESSION_ID> # transcript as Markdown +``` + +## Quirks + +- Grok reads the target repo's `CLAUDE.md` and obeys it (including tone rules) — repo constraints apply automatically, but so do repo-wide bans; account for that in the brief. +- `--check` produces a self-verification section in the final report — useful signal, **not** a substitute for your independent verification. +- Exit code 0 means the CLI ran, not that the task succeeded. Judge by diff + your own Evidence runs.