do-it ships one workflow kernel (skills, hooks, agents) and six host adapters that map the same advisory signals to each runtime's hook surface. Adapters are honest about capability gaps — we do not copy the full Claude hook stack onto every host.
| Platform | Distribution | Hook depth | Notes |
|---|---|---|---|
| Codex | marketplace-first; do-it setup optional/legacy |
Full | Trust plugin hooks under /hooks; session state via plugin data or CODEX_HOME/do-it-data |
| Claude Code | marketplace-first | Full | ${CLAUDE_PLUGIN_ROOT} hooks; ${CLAUDE_PLUGIN_DATA} session state |
| Cursor | local / Team Import today; public listing pending | Medium | Official marketplace exists; do-it not listed yet. No Claude /plugin commands. |
| OpenCode | independent @tdwhere/do-it-opencode npm package; global vendor fallback |
Medium | TS plugin: transform bootstrap; tool.execute.after; session.idle soft reminder |
| Pi | independent @tdwhere/do-it-pi package or local path |
Medium | TS extension events; skills/prompts always available; namespaced do-it.* agents require optional pi-subagents |
| Kimi Code | repo-root plugin via /plugins install (per-user) |
Full-minus-subagent | kimi.plugin.json at repo root — no build step. No custom subagents: agents not shipped, subagent-stance unwired |
Workflow logic lives once in skills/do-it/ and hooks/. Host-specific install
paths, tool names, and hook event names live in
skills/do-it/references/host-vocabulary.md
and the per-host sheets below.
Hooks and skills share three routing tiers. Tier is an advisory input; boolean
dimensions (dim_*) narrow intensity without changing it. Direct user intent
and model judgment take precedence over router labels.
| Tier | Router output | write-quality-lint | grill-prompt | Completion reminder |
|---|---|---|---|---|
| Light | state-only, quiet | skipped | skipped | advisory only when relevant |
| Standard | state + model-adaptive core guidance: inline rule sentences or one do-it-core pointer |
when dim_touches_code=1 or ≥5 added lines |
skipped (Heavy-only) | advisory only when relevant |
| Heavy | state-only by default; one do-it-architecture pointer for action-shaped interface/schema, migration/cutover, or security-boundary work |
always (advisory) | full grill body when warranted | advisory only when relevant |
Subagent contexts skip write-quality-lint (parent owns integration).
grill-pretool is removed on all hosts.
| Signal | Script | Codex / Claude | Cursor | OpenCode | Pi | Kimi Code |
|---|---|---|---|---|---|---|
| Opt-in feedback capture | behavior-feedback.sh |
UserPromptSubmit plus narrow UserPromptExpansion, silent and default off |
beforeSubmitPrompt, silent and default off |
chat.message, silent and default off; only a confirmed root session is eligible |
not wired | UserPromptSubmit, silent and default off |
| Classify prompt | router.sh |
UserPromptSubmit |
beforeSubmitPrompt |
chat.message |
root before_agent_start |
UserPromptSubmit |
| Grill nudge (Heavy) | grill-prompt.sh |
UserPromptSubmit |
beforeSubmitPrompt |
chat.message (Heavy/explicit, advisory) |
root before_agent_start (Heavy/explicit, advisory) |
UserPromptSubmit (Heavy/explicit, advisory) |
| Subagent stance | subagent-stance.sh |
UserPromptSubmit |
beforeSubmitPrompt |
bootstrap guidance only | child before_agent_start when PI_SUBAGENT_CHILD=1 |
not wired — Subagent events carry empty session_id |
| Write-time quality | write-quality-lint.sh |
PostToolUse (Edit|Write|MultiEdit|NotebookEdit) |
postToolUse / afterFileEdit |
tool.execute.after (bash bridge) |
root tool_result (edit/write) |
PostToolUse (Edit|Write — the only Kimi edit tools) |
| Done claim | verification-gate.sh |
Stop |
stop |
session.idle soft reminder from serialized host messages |
root agent_end capture + agent_settled reminder on the next turn |
Stop; transcript read from session wire.jsonl (no transcript_path on this host) |
router.sh emits Standard core guidance inline for weak/unknown models and as a
single do-it-core pointer for strong models (DO_IT_ADVISORY_MODE overrides).
For Heavy turns it emits a do-it-architecture pointer only when the prompt
requests an interface/schema change, migration/cutover execution, or a
security-boundary change; informational questions and ordinary release/publish
operations do not receive that pointer.
verification-gate.sh quotes the canonical r-verify sentence from
hooks/data/execution-failure-modes.tsv on every host — one voice, never
per-host copies (validate:core-consistency enforces it).
Legacy comments-lint.sh and anti-patterns-lint.sh exec into
write-quality-lint.sh; new installs register only the merged script.
No current do-it hook is a universal permission veto. The router, grill, subagent stance, quality lint, and verification gate are workflow guidance; they must not be described as hard confirmation.
- In Codex, a plugin hook can add context but cannot veto a
PreToolUseorPermissionRequestcall. Use the host's sandbox, approval policy, and command rules for a hard boundary;--yolo/ bypass modes deliberately remove that protection. See the Codex hooks and approval guidance. - Claude Code has a default-off, narrow
PreToolUseprofile for named remote publication and infrastructure-apply commands.DO_IT_STRICT_EXTERNAL_ACTIONS=askrequests a true host confirmation;denystops those named commands. It is not a universal network or MCP guard. Seestrict-external-actions.md. - Cursor, OpenCode, and Pi keep the same advisory workflow contract; configure their native permissions separately when an operation needs enforcement.
- Kimi Code keeps the same advisory contract: do-it hooks always exit 0 and
only add context (
PreToolUse/Stopcan block on this host, but no do-it hook uses that). Configure Kimi's native permission rules for a hard boundary.
Per-host install paths and tool mapping:
host-codex.md,
host-claude.md,
host-cursor.md,
host-opencode.md,
host-pi.md,
host-kimi.md.
Quality is supported in layers. Higher layers do not replace lower ones — they add context when cheaper checks cannot prove a claim.
L0 write-time hook (advisory) → one system-reminder per file per turn; scoped family suppression with a reason (never secrets)
L1 do-it-review → Blocking / Important finding; YAGNI + comments lenses respond to L0 families
L2 verification-gate → edited completion claims receive an advisory reminder quoting the r-verify rule; it does not infer proof from command names
L3 do-it-core (§ Verify) + do-it-verify closeout → claim-specific evidence rollup; `NOT_VERIFIED` and residual risk stay visible
| Layer | Owner | Blocks write? | Blocks done claim? |
|---|---|---|---|
L0 write-quality-lint |
hook | No | No |
L1 do-it-review |
skill / subagent | No | No — unresolved findings shape the final claim |
L2 verification-gate |
hook | No | No — advisory reminder only |
| L3 closeout | do-it-core (§ Verify) + do-it-verify |
No | Claim wording follows available proof |
Family definitions and suppress syntax:
skills/do-it/references/write-quality-families.md.
UserPromptSubmit (plus Cursor beforeSubmitPrompt and Pi
before_agent_start) injection is the main recurring token cost. Targets after simplification:
| Component | Standard turn target | When skipped |
|---|---|---|
behavior-feedback.sh |
0 tokens; no stdout/context | disabled by default; ordinary prompts and unverified child sessions |
router.sh |
Standard: inline ≈ 6 lines / pointer ≈ 1 line; architecture-risk Heavy: 1 pointer | Light and Heavy without architecture risk |
grill-prompt.sh |
0 unless Heavy or explicit | Light; Standard without an explicit grill |
subagent-stance.sh |
one compact line once per subagent session | parent context and later child turns |
| Combined Standard implementation turn | only task-relevant advisory context | no fixed workflow injection |
PostToolUse quality reminders:
- At most one
system-reminderpersession_id+file_path+ user turn (dedup in session state). - Reminder lists matched family IDs only; full regex detail lives in
write-quality-families.md(L3 progressive disclosure). - Light tier: hook does not run — zero post-edit injection.
Bundled agents are optional capability experts. The parent gives a delegated slice its goal and any needed ownership or side-effect boundary; workers inspect independently, return useful evidence or uncertainty, and the parent integrates. There is no fixed delegation contract, agent count, or role matrix.
Hooks resolve per-session state through the canonical search order in
hooks/lib/common.sh (do_it_session_dir):
$CURSOR_PLUGIN_DATA/sessions$CLAUDE_PLUGIN_DATA/sessions$PLUGIN_DATA/sessions$DO_IT_HOOK_DATA/sessions$OPENCODE_DATA/sessions$KIMI_CODE_HOME/do-it-data/sessions$CODEX_HOME/do-it-data/sessions<repo>/.do-it/runtime/sessions${TMPDIR}/do-it-sessions
install/manage.mjs (sessionsBaseDir) and the OpenCode bridge
(resolveSessionStateDir) mirror this order. KIMI_PLUGIN_ROOT is never used
for state — it is a managed plugin copy with read-only semantics.
Missing state degrades to minimal advisory behavior — hooks never block on absence.
State is keyed only by the host-supplied session ID. A child assigned a different session ID does not automatically inherit a parent's no-write boundary; an adapter must pass or verify that relationship explicitly before claiming cross-session inheritance.
- Public routing policy:
routing-matrix.md - Shared references:
skills/do-it/references/ - Hook sources:
hooks/