From e8bc2b3a868d3a402e98737a1df4a6cc33ae7303 Mon Sep 17 00:00:00 2001 From: Dat Date: Fri, 12 Jun 2026 09:14:18 +0700 Subject: [PATCH] feat(skills): complete engineering-workflow skill set + codex target + worktree support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fill out dat-devkit into a full engineering loop (align → specify → decompose → execute → verify → ship → maintain → triage → hand off), add the codex/gemini skill target, and make the harness work inside git worktrees. Workflow skills (Claude + Codex), inspired by mattpocock/skills: - /grill relentless one-question-at-a-time alignment interview - /prd synthesize conversation into .devkit/prd.md (optional GitHub issue) - /to-issues decompose a plan into vertical-slice GitHub issues (AFK/HITL) - /zoom-out map unfamiliar code a layer up; persist terms to CONTEXT.md - /improve-architecture find shallow-module friction, propose deepening + ADRs - /triage GitHub issue triage state machine with agent briefs - /handoff compact a session into a temp-dir handoff doc - /worktree create a git worktree and install the harness into it Worktree support: - bin/devkit-worktree.sh — add/sync/sync-all/list; resolves the main checkout via git-common-dir and syncs .claude/ with correct excludes (worktrees/, .devkit/ state) - rewrite rules/worktree.md around the helper (was a manual rsync) Shared CONTEXT.md glossary convention (_shared/context-doc.md) tying the alignment skills to the project's domain language. install.sh: codex/gemini installers now also copy _shared/ (fixes dangling ../_shared/*.md references in those targets). Docs: CLAUDE.md skill registry + README updated to the full loop. --- README.md | 88 ++++++++--- harness/codex/_shared/context-doc.md | 47 ++++++ harness/codex/_shared/github-access.md | 51 +++++++ harness/codex/skills/audit/SKILL.md | 56 +++++++ harness/codex/skills/bugfix/SKILL.md | 92 ++++++++++++ harness/codex/skills/diagnose/SKILL.md | 111 ++++++++++++++ harness/codex/skills/feature/SKILL.md | 120 +++++++++++++++ harness/codex/skills/grill/SKILL.md | 66 +++++++++ harness/codex/skills/handoff/SKILL.md | 77 ++++++++++ .../skills/improve-architecture/LANGUAGE.md | 40 +++++ .../skills/improve-architecture/SKILL.md | 74 ++++++++++ harness/codex/skills/pr/SKILL.md | 80 ++++++++++ harness/codex/skills/prd/SKILL.md | 82 +++++++++++ harness/codex/skills/review/SKILL.md | 77 ++++++++++ harness/codex/skills/tdd/SKILL.md | 100 +++++++++++++ harness/codex/skills/to-issues/SKILL.md | 91 ++++++++++++ harness/codex/skills/triage/AGENT-BRIEF.md | 43 ++++++ harness/codex/skills/triage/SKILL.md | 80 ++++++++++ harness/codex/skills/worktree/SKILL.md | 51 +++++++ harness/codex/skills/zoom-out/SKILL.md | 51 +++++++ harness/common/CLAUDE.md | 28 +++- harness/common/bin/devkit-worktree.sh | 138 ++++++++++++++++++ harness/common/rules/worktree.md | 62 +++++--- harness/common/skills/_shared/context-doc.md | 47 ++++++ harness/common/skills/grill/SKILL.md | 69 +++++++++ harness/common/skills/handoff/SKILL.md | 79 ++++++++++ .../skills/improve-architecture/LANGUAGE.md | 40 +++++ .../skills/improve-architecture/SKILL.md | 78 ++++++++++ harness/common/skills/prd/SKILL.md | 84 +++++++++++ harness/common/skills/to-issues/SKILL.md | 93 ++++++++++++ harness/common/skills/triage/AGENT-BRIEF.md | 43 ++++++ harness/common/skills/triage/SKILL.md | 83 +++++++++++ harness/common/skills/worktree/SKILL.md | 65 +++++++++ harness/common/skills/zoom-out/SKILL.md | 62 ++++++++ install.sh | 118 +++++++++++++-- .../gitlab/skills-codex/gitlab-pr/SKILL.md | 49 +++++++ .../skills-codex/prd-authoring/SKILL.md | 50 +++++++ 37 files changed, 2613 insertions(+), 52 deletions(-) create mode 100644 harness/codex/_shared/context-doc.md create mode 100644 harness/codex/_shared/github-access.md create mode 100644 harness/codex/skills/audit/SKILL.md create mode 100644 harness/codex/skills/bugfix/SKILL.md create mode 100644 harness/codex/skills/diagnose/SKILL.md create mode 100644 harness/codex/skills/feature/SKILL.md create mode 100644 harness/codex/skills/grill/SKILL.md create mode 100644 harness/codex/skills/handoff/SKILL.md create mode 100644 harness/codex/skills/improve-architecture/LANGUAGE.md create mode 100644 harness/codex/skills/improve-architecture/SKILL.md create mode 100644 harness/codex/skills/pr/SKILL.md create mode 100644 harness/codex/skills/prd/SKILL.md create mode 100644 harness/codex/skills/review/SKILL.md create mode 100644 harness/codex/skills/tdd/SKILL.md create mode 100644 harness/codex/skills/to-issues/SKILL.md create mode 100644 harness/codex/skills/triage/AGENT-BRIEF.md create mode 100644 harness/codex/skills/triage/SKILL.md create mode 100644 harness/codex/skills/worktree/SKILL.md create mode 100644 harness/codex/skills/zoom-out/SKILL.md create mode 100644 harness/common/bin/devkit-worktree.sh create mode 100644 harness/common/skills/_shared/context-doc.md create mode 100644 harness/common/skills/grill/SKILL.md create mode 100644 harness/common/skills/handoff/SKILL.md create mode 100644 harness/common/skills/improve-architecture/LANGUAGE.md create mode 100644 harness/common/skills/improve-architecture/SKILL.md create mode 100644 harness/common/skills/prd/SKILL.md create mode 100644 harness/common/skills/to-issues/SKILL.md create mode 100644 harness/common/skills/triage/AGENT-BRIEF.md create mode 100644 harness/common/skills/triage/SKILL.md create mode 100644 harness/common/skills/worktree/SKILL.md create mode 100644 harness/common/skills/zoom-out/SKILL.md create mode 100644 plugins/gitlab/skills-codex/gitlab-pr/SKILL.md create mode 100644 plugins/notion-prd/skills-codex/prd-authoring/SKILL.md diff --git a/README.md b/README.md index 8d3e044..059477c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Drop it into any repo with one command and every Claude Code session in that pro | **Rules** | 13 common + TypeScript + Python | Coding style, naming, paradigms, design principles, testing, security, git workflow, code review, agent behavior, context hygiene, worktrees, dangerous-action guardrails. Language layers override common where they conflict. | | **Hooks** | 13 | Guards and automations fired on tool events — block dangerous bash, block credential writes, block pushes to protected branches, run tests before push, scan for secrets before commit, validate branch/commit format, lint on write, monitor context, remind about PR review, resume/track workflow, auth check. | | **Agents** | 5 | `planner`, `coder`, `tester`, `reviewer`, `security` — each with model routing (deep-reasoning models for planning/review, faster models for mechanical work). | -| **Skills** | 7 core | `/feature`, `/bugfix`, `/review`, `/audit`, `/pr`, `/tdd`, `/diagnose`. | +| **Skills** | 15 core | Full engineering loop — align (`/grill`, `/prd`, `/to-issues`) → execute (`/feature`, `/bugfix`, `/tdd`, `/diagnose`) → verify & ship (`/review`, `/audit`, `/pr`) → maintain (`/zoom-out`, `/improve-architecture`, `/triage`, `/handoff`, `/worktree`). | | **Plugins** | 2 optional | `gitlab` (MR creation via `glab`), `notion-prd` (write PRDs in Notion). Opt-in with `--with`. | Everything is plain files — Markdown rules, Bash hooks, JSON settings. No runtime, no daemon, no lock-in. Read any of it. @@ -63,13 +63,15 @@ Language rules install into per-language subdirectories so they never overwrite | Target | Output | Notes | |---|---|---| | `claude` (default) | `.claude/` with full harness | Rules, hooks, agents, skills, bin, settings | -| `codex` | `.codex/AGENTS.md` | All rules concatenated into one instruction file (hooks/skills/agents are Claude-only and skipped) | -| `gemini` | `.gemini/GEMINI.md` | Same concatenated-rules bundle for the Gemini CLI | +| `codex` | `.codex/AGENTS.md` + `.codex//SKILL.md` | All rules concatenated into `AGENTS.md`; skills installed as Codex skill directories (hooks/agents are Claude-only and skipped) | +| `gemini` | `.gemini/GEMINI.md` + `.gemini//SKILL.md` | Same concatenated-rules bundle for the Gemini CLI, with the same skill-directory layout as Codex | ```bash ./install.sh typescript --target codex ~/path/to/project ``` +Under the `codex` (and `gemini`) target, each core skill lands as `.codex//SKILL.md` and each `--with` plugin's skills land in the same shape under `plugins//skills-codex/`. They are plain Markdown — Codex and Gemini pick them up automatically, no extra wiring needed. + ### Plugins (`--with`, repeatable) ```bash @@ -131,27 +133,66 @@ Project configuration lives in `.claude/devkit-plan.json`. It is created on firs ## Skills Type the slash command in Claude Code, or just describe the task and the skill auto-triggers. +The skills compose into the full engineering loop: +**align → specify → decompose → execute → verify → ship → maintain → triage → hand off.** + +### Align & specify + +| Skill | Use it for | +|---|---| +| `/grill` | Relentless one-question-at-a-time interview that stress-tests a plan **before** any code — the fix for agent misalignment. | +| `/prd` | Synthesize the conversation (ideally after `/grill`) into `.devkit/prd.md`; optionally open it as a GitHub issue. | +| `/to-issues` | Decompose a PRD/plan into many thin **vertical-slice** GitHub issues, labeled AFK/HITL and sequenced by dependency. | + +### Execute | Skill | Use it for | |---|---| | `/feature` | Full feature flow: plan → code → test → review. Orchestrates the agents end to end. | | `/bugfix` | Reproduce → fix → test → review for a single defect. | +| `/tdd` | Test-first workflow: red → green → refactor, enforcing coverage. | +| `/diagnose` | Systematic root-cause investigation for a failing test, flaky behavior, or confusing error. | + +### Verify & ship + +| Skill | Use it for | +|---|---| | `/review` | Structured code review of the current diff; auto-escalates to a security pass when auth/PII is touched. | | `/audit` | Security audit of the codebase + dependency vulnerability scan. | | `/pr` | Guided branch → commit → PR creation following your `devkit-plan.json` conventions (GitHub `gh` by default). | -| `/tdd` | Test-first workflow: red → green → refactor, enforcing coverage. | -| `/diagnose` | Systematic root-cause investigation for a failing test, flaky behavior, or confusing error. | + +### Understand & maintain + +| Skill | Use it for | +|---|---| +| `/zoom-out` | Map an unfamiliar area by going **up** a layer; persists durable domain terms to a project-root `CONTEXT.md`. | +| `/improve-architecture` | Find shallow-module / ball-of-mud friction, propose deepening refactors, optionally record an ADR. | +| `/triage` | Move GitHub issues through a triage state machine into actionable, labeled work with agent briefs. | +| `/handoff` | Compact the session into a temp-dir handoff doc a fresh agent can pick up cold. | +| `/worktree` | Create a git worktree and install the harness into it — parallel work with isolated workflow state. | ```text +/grill I want to add multi-tenant billing +/prd +/to-issues /feature add a rate limiter to the login endpoint /bugfix login returns 500 when email is missing +/tdd parse ISO-8601 durations +/diagnose why does the cache test fail only in CI /review /audit /pr -/tdd parse ISO-8601 durations -/diagnose why does the cache test fail only in CI +/zoom-out how does the payments subsystem fit together +/improve-architecture the order module is a mess +/triage +/handoff finish the billing slice next session +/worktree make a worktree for the billing refactor ``` +Several skills share a project-root **`CONTEXT.md`** — a small, human-maintained glossary +of the project's domain language — so specs, issues, and reviews all speak your terms +instead of generic boilerplate. + --- ## Hooks @@ -183,12 +224,18 @@ Plugins are optional, self-contained integrations with a specific tool, kept out ``` plugins// -├── plugin.json # manifest -├── skills//SKILL.md # (optional) skills it adds -├── rules/*.md # (optional) rules it adds -└── hooks/*.sh # (optional) hooks it adds +├── plugin.json # manifest +├── skills//SKILL.md # Claude target: skills it adds +├── skills-codex//SKILL.md# codex / gemini targets: same skills, codex-shaped +├── rules/*.md # (optional) rules it adds +└── hooks/*.sh # (optional) hooks it adds ``` +Skills are duplicated per target because Claude skills use the Claude frontmatter +(`disable-model-invocation`, model routing, sub-agent dispatch) which doesn't +apply to Codex/Gemini. The `codex` and `gemini` versions are stripped down to +plain Markdown that any tool can pick up. + ### `plugin.json` schema ```json @@ -216,6 +263,9 @@ plugins// | `gitlab` | `/gitlab-pr` skill (GitLab MR creation) | `glab` CLI or a GitLab MCP server | | `notion-prd` | `/prd-authoring` skill (write PRDs in Notion) | Notion MCP server + integration token | +Each plugin ships both a Claude version (`skills//SKILL.md`) and a +codex/gemini version (`skills-codex//SKILL.md`). + ### Writing your own 1. Create `plugins//plugin.json` with the schema above. @@ -255,11 +305,15 @@ dat-devkit/ │ │ ├── settings.json # hook wiring │ │ ├── settings.local.json # statusline (engineer-local override) │ │ ├── devkit-plan.json # git workflow + token budgets (kept on update) -│ │ ├── rules/*.md # 13 common rules -│ │ ├── hooks/*.sh # 13 hooks + _lib.sh +│ │ ├── rules/*.md # common rules (incl. worktree hygiene) +│ │ ├── hooks/*.sh # hooks + _lib.sh │ │ ├── agents/*.md # planner, coder, tester, reviewer, security -│ │ ├── skills/ # feature, bugfix, review, audit, pr, tdd, diagnose -│ │ └── bin/ # statusline, doctor, state, usage scripts +│ │ ├── skills/ # Claude-target skills (15): align → execute → ship → maintain +│ │ │ └── _shared/ # github-access.md, context-doc.md references +│ │ └── bin/ # statusline, doctor, state, worktree, usage scripts +│ ├── codex/ # codex/gemini-target skills (same set, in codex shape) +│ │ ├── _shared/ # github-access.md, context-doc.md references +│ │ └── skills//SKILL.md │ ├── typescript/ │ │ ├── rules/*.md # TS coding-style, type-safety, testing, security, graphql │ │ └── hooks/ # post-write-graphql.sh + hooks-extend.json @@ -267,8 +321,8 @@ dat-devkit/ │ └── rules/*.md # Python coding-style, type-safety, testing, security └── plugins/ ├── README.md - ├── gitlab/ # /gitlab-pr skill (opt-in) - └── notion-prd/ # /prd-authoring skill (opt-in) + ├── gitlab/ # /gitlab-pr skill (opt-in) — skills/ for Claude, skills-codex/ for codex/gemini + └── notion-prd/ # /prd-authoring skill (opt-in) — same shape ``` --- diff --git a/harness/codex/_shared/context-doc.md b/harness/codex/_shared/context-doc.md new file mode 100644 index 0000000..3dcc9f6 --- /dev/null +++ b/harness/codex/_shared/context-doc.md @@ -0,0 +1,47 @@ +# CONTEXT.md — Shared Project Language (Shared Reference) + +Several skills (`/grill`, `/prd`, `/to-issues`, `/zoom-out`, `/improve-architecture`) read +and write a project-root `CONTEXT.md`. It's the kit's antidote to **verbosity and +misalignment**: a shared glossary so the agent and the codebase use the same words, which +cuts re-explanation and keeps specs/issues/reports in the project's own vocabulary. + +## What it is + +A short, durable, human-maintained file at the **project root** (`./CONTEXT.md`). It is +*not* documentation of how the code works — that's what the code and `/zoom-out` are for. +It's the **vocabulary and load-bearing facts** a newcomer (human or agent) needs to talk +about the project correctly. + +## What goes in it + +- **Domain glossary** — the project's nouns and verbs with one-line definitions. ("A + *Tenant* is a billing account; *Members* belong to exactly one Tenant.") +- **Key concepts / invariants** — rules that are always true and easy to violate. ("All + money is integer minor units; never floats.") +- **Module names that carry meaning** — deepened modules named during + `/improve-architecture`, so future sessions reuse the term. +- **Pointers, not prose** — "Auth lives behind the `Session` seam; see `docs/adr/004`." + +## What does NOT go in it + +- File-by-file tours, call graphs, or anything that goes stale on refactor (use `/zoom-out` + live instead). +- Secrets, credentials, or PII. +- Requirements or plans — those are `/prd` and issues. + +## How skills use it + +| Skill | Reads it to… | Writes to it when… | +|---|---|---| +| `/grill` | ask in the project's terms | (read-only) | +| `/prd` | spec in the project's terms | (read-only) | +| `/to-issues` | name issues in the project's terms | (read-only) | +| `/zoom-out` | explain in the project's terms | a new load-bearing term is discovered | +| `/improve-architecture` | reason about modules in the project's terms | a deepened module is named | + +## Bootstrapping + +If `CONTEXT.md` doesn't exist when a skill needs it, create a minimal one (title + empty +Glossary / Concepts sections) and add the terms you have. Keep it short — a CONTEXT.md +nobody maintains is worse than none. Pair it with ADRs in `docs/adr/` for *decisions* +(CONTEXT.md is for *vocabulary*). diff --git a/harness/codex/_shared/github-access.md b/harness/codex/_shared/github-access.md new file mode 100644 index 0000000..73c80d2 --- /dev/null +++ b/harness/codex/_shared/github-access.md @@ -0,0 +1,51 @@ +# GitHub Access — Shared Reference (Codex) + +Use this whenever a Codex skill needs to read or write GitHub data (PR metadata, diffs, comments, reviews). This devkit is GitHub-only and uses the `gh` CLI. + +## Step 1 — Confirm `gh` is authenticated + +```bash +gh auth status +``` + +- If it reports a logged-in account, you're ready — use `gh` commands directly. +- If it errors or says "not logged in", tell the user to run `gh auth login` + (or set `GH_TOKEN` in their environment). Do not attempt to store tokens yourself. + +## Step 2 — Common operations + +```bash +# Default branch of the current repo +gh repo view --json defaultBranchRef --jq .defaultBranchRef.name + +# PR metadata (base branch matters for diffs and reviews) +gh pr view --json number,title,baseRefName,headRefName,url + +# PR diff +gh pr diff + +# Create a PR +gh pr create --title "" --body "<body>" --base <default-branch> + +# Comment on a PR (general note) +gh pr comment <number|url> --body "<comment>" + +# Submit a review (approve / request changes / comment) +gh pr review <number|url> --comment --body "<findings>" +``` + +## Step 3 — API fallback + +When a `gh` subcommand doesn't cover what you need, drop to the REST API via +`gh api` — it reuses the same authentication: + +```bash +# Example: list review comments on a PR +gh api repos/{owner}/{repo}/pulls/<number>/comments + +# Example: post an inline review comment anchored to a line +gh api repos/{owner}/{repo}/pulls/<number>/comments \ + -f body="<comment>" -f commit_id="<sha>" -f path="<file>" -F line=<n> -f side=RIGHT +``` + +Resolve `{owner}/{repo}` with `gh repo view --json nameWithOwner --jq .nameWithOwner`. diff --git a/harness/codex/skills/audit/SKILL.md b/harness/codex/skills/audit/SKILL.md new file mode 100644 index 0000000..125993e --- /dev/null +++ b/harness/codex/skills/audit/SKILL.md @@ -0,0 +1,56 @@ +--- +name: audit +description: Runs an OWASP Top 10 security audit (access control, cryptographic failures, injection, insecure design, misconfiguration, vulnerable components, auth failures, data integrity, logging failures, SSRF) and a dependency CVE scan against the project's package manager, then writes a PASS/FAIL report to .devkit/security-audit.md and optionally posts findings to a GitHub PR. Use when the user says "audit", "security audit", "OWASP", "compliance check", "scan dependencies", "check for vulnerabilities", or before merging. +--- + +# Audit Workflow + +Run an OWASP Top 10 review and a package vulnerability scan. + +> GitHub access: follow [`_shared/github-access.md`](../_shared/github-access.md). + +> Codex note: state lives in `.devkit/`. No `devkit-state.sh` binary — bump +> `.devkit/state.json` between phases. + +## Step 1 — Determine scope + +- GitHub PR (number or URL) provided: fetch the diff with `gh pr diff <number|url>`. +- No PR given: use the local diff, or scan the entire project. + +Initialize state: +```bash +mkdir -p .devkit +SLUG="<pr-number-or-slug>" +cat > .devkit/state.json <<JSON +{ + "workflow": "audit", + "slug": "$SLUG", + "current_step": 1, + "steps": ["security", "complete"] +} +JSON +``` + +## Step 2 — Security + +Run the audit yourself in this session: +- OWASP Top 10 checks: access control, cryptographic failures, injection, + insecure design, misconfiguration, vulnerable components, auth failures, + data integrity, logging failures, SSRF +- Dependency vulnerability scan: `npm audit` (Node) or `pip-audit` (Python) +- Write the report to `.devkit/security-audit.md` with findings and a + `PASS/FAIL` verdict + +Print `## AUDIT COMPLETE`. Bump `current_step` to 2. + +## Step 3 — Complete + +```bash +cat > .devkit/state.json <<JSON +{ "workflow": "audit", "slug": "$SLUG", "status": "complete" } +JSON +``` +Print the audit summary and overall PASS/FAIL verdict. + +If a PR was provided, offer to post the audit: +- `gh pr comment <number|url> --body "<audit summary>"` diff --git a/harness/codex/skills/bugfix/SKILL.md b/harness/codex/skills/bugfix/SKILL.md new file mode 100644 index 0000000..bc3458d --- /dev/null +++ b/harness/codex/skills/bugfix/SKILL.md @@ -0,0 +1,92 @@ +--- +name: bugfix +description: End-to-end bug-fix workflow that runs /diagnose first to produce a disciplined root-cause report (.devkit/diagnose.md), then drives coder → tester → reviewer phases inline. Adds a regression test, verifies against clean-code conventions, and ships a tested, reviewed fix on a branch. Use when the user says "fix this bug", "fix and ship", "debug and fix X", "there's a regression — fix it", or hands off a stack trace and wants a tested, reviewed fix. +--- + +# Bug Fix Workflow + +Diagnose, fix, test, and review a single bug. The diagnosis discipline lives in +`/diagnose` — this skill consumes its output and drives the rest. + +> Codex note: state lives in `.devkit/`. No `devkit-state.sh` binary — bump +> `.devkit/state.json` between phases. + +## Step 1 — Initialize + +Ask for: +1. Bug description or ticket reference (optional) +2. Error logs or stack trace, if available +3. Coder mode: `auto` (Codex writes the fix) or `engineer` (Codex stops at the + fix plan, you write it) + +```bash +mkdir -p .devkit +SLUG="<ticket-or-slug>" +cat > .devkit/state.json <<JSON +{ + "workflow": "bugfix", + "slug": "$SLUG", + "coder_mode": "<auto|engineer>", + "current_step": 1, + "steps": ["diagnose", "code", "test", "review", "complete"] +} +JSON +``` + +## Step 2 — Diagnose + +Run `/diagnose` on the bug. It produces `.devkit/diagnose.md` containing the +feedback loop, ranked hypotheses, root cause, and fix plan. + +**Wait for `## DIAGNOSE COMPLETE`** before continuing. If `/diagnose` prints +`## DIAGNOSE BLOCKED` (no Phase 1 feedback loop could be built), stop here and +surface the blockers — fixing without a repro means the fix cannot be verified. + +Bump `current_step` to 2. + +## Step 3 — Code (or engineer pause) + +- `--coder auto`: apply the Phase 5 fix plan from `.devkit/diagnose.md` + directly in this session. Immutability, function-size, type-safety, and + conventional-commit rules from `/feature` apply. Wait for `## CODE COMPLETE`. +- `--coder engineer`: print the Phase 5 fix plan and wait for the engineer to + apply it. Resume on "done". + +Bump `current_step` to 3. + +## Step 4 — Test + +Write tests in this session. The regression test is specified in +`.devkit/diagnose.md` Phase 5 — write it at that seam. If the report says +"no correct seam exists", write the broadest test you can and note the gap. + +Run the Phase 1 feedback loop against the un-minimised scenario to confirm the +original symptom is gone. Print `## TESTS COMPLETE`. Bump `current_step` to 4. + +## Step 5 — Review + +Review the diff yourself. Output: `.devkit/review.md` with CRITICAL / HIGH / +MEDIUM findings. Block on CRITICAL. Surface HIGH for the engineer to decide. +MEDIUM is informational. Bump `current_step` to 5. + +## Step 6 — Complete + +```bash +cat > .devkit/state.json <<JSON +{ "workflow": "bugfix", "slug": "$SLUG", "status": "complete" } +JSON +``` + +Print a summary: files changed, regression test name, reviewer verdict. Run +the Phase 6 cleanup checklist from `.devkit/diagnose.md` — verify no +`[DEBUG-...]` strings leaked into the diff and no throwaway scripts are left +behind. + +If the bug touched auth, secrets, PII, financial logic, or external API code: +suggest `/audit` before opening the PR. End by suggesting "/pr to open a +pull request". + +## Out of scope + +- Disciplined investigation — `/diagnose` owns the diagnosis loop. +- Writing the PR and pushing — `/pr` does that. diff --git a/harness/codex/skills/diagnose/SKILL.md b/harness/codex/skills/diagnose/SKILL.md new file mode 100644 index 0000000..ef8176c --- /dev/null +++ b/harness/codex/skills/diagnose/SKILL.md @@ -0,0 +1,111 @@ +--- +name: diagnose +description: Disciplined six-phase debugging loop (build feedback loop → reproduce → hypothesise → instrument → fix + regression test → cleanup) for hard bugs and performance regressions. Output is a written root-cause report at .devkit/diagnose.md that /bugfix can consume to drive the actual fix. Use when the user says "diagnose this", "debug this", "what's causing this", "why is this slow", "this is flaky", reports a regression, pastes a stack trace / error log, or describes a bug that resists guess-and-check. +--- + +# Diagnose + +A discipline for hard bugs. Skip phases only when explicitly justified — and +write the justification into `.devkit/diagnose.md`. + +## Phase 1 — Build a feedback loop + +**This is the skill.** A fast, deterministic, Codex-runnable pass/fail signal +makes the bug 90% solved. Without one, no amount of code-staring helps. Try, +roughly in order: + +1. **Failing test** at the deepest seam that reaches the bug — `jest` for + TS/JS, `pytest` for Python. +2. **HTTP repro** — `curl` against a local dev server. +3. **CLI fixture** — feed a captured payload through one function, diff stdout + against a known-good snapshot. +4. **Headless browser** — Playwright drives the UI, asserts on DOM / console / + network. +5. **Replay a captured trace** — save a real request/payload/event log, replay + it through the code path in isolation. +6. **Throwaway harness** — minimal subset (one module, mocked deps) hitting + the bug path with one call. +7. **Property / fuzz loop** — for "sometimes wrong output", run 1000 random + inputs. +8. **Bisection harness** — automate "boot, check, repeat" so `git bisect run` + can drive it. +9. **Differential loop** — same input through old vs new (or two configs); + diff outputs. +10. **HITL loop** — last resort. If a human must click, drive *them* with a + scripted prompt-and-capture loop so the output still feeds back to you. + +### Iterate the loop itself + +Once you have *a* loop, sharpen it: faster (cache setup, narrow scope), sharper +signal (assert the specific symptom, not "didn't crash"), more deterministic +(pin time, seed RNG, isolate filesystem, freeze network). A 2-second +deterministic loop is a superpower; a 30-second flaky loop barely beats none. + +### Non-deterministic bugs + +Aim for a higher reproduction rate, not a clean repro. Loop the trigger 100×, +parallelise, add stress, narrow timing windows. 50% flake = debuggable; 1% = +not — keep raising until it is. + +### When you cannot build a loop + +Stop. Write `.devkit/diagnose.md` listing what you tried, print +`## DIAGNOSE BLOCKED`, and ask the user for: (a) access to an env that +reproduces, (b) a captured artifact (HAR, log dump, recording with timestamps), +or (c) permission to add temporary instrumentation. Do **not** hypothesise +without a loop. + +## Phase 2 — Reproduce + +Run the loop. Confirm it produces the failure the **user** described (not a +nearby one), reproduces across runs (or at a high enough rate), and that you +captured the exact symptom so Phase 6 can verify the fix. + +## Phase 3 — Hypothesise + +Generate **3–5 ranked, falsifiable hypotheses** before testing any. +> Format: "If <X> is the cause, then <changing Y> makes the bug disappear / +> <changing Z> makes it worse." + +If you cannot state a prediction, it's a vibe — sharpen or discard. Show the +ranked list to the user before instrumenting; they often re-rank instantly +with domain knowledge. + +## Phase 4 — Instrument + +Each probe maps to one prediction from Phase 3. **Change one variable at a +time.** Prefer debugger / REPL > targeted logs > "log everything and grep" +(never). Tag every debug log with a unique prefix like `[DEBUG-a4f2]` so +cleanup is one grep. For performance bugs, measure first (timing harness, +profiler, `EXPLAIN ANALYZE`) — logs lie. + +## Phase 5 — Fix + regression test + +Write the regression test **before the fix** — but only if a **correct seam** +exists. A correct seam exercises the real bug pattern at the call site. If the +only seam is too shallow, a test there gives false confidence — **note that +absence as the finding** in `.devkit/diagnose.md`. If a correct seam exists: +turn the minimised repro into a failing test, watch it fail, apply the fix, +watch it pass, then re-run the Phase 1 loop against the **un-minimised** +scenario. + +## Phase 6 — Cleanup + handoff + +- [ ] Original repro no longer reproduces (re-run Phase 1 loop) +- [ ] Regression test passes (or absence of a seam is documented) +- [ ] All `[DEBUG-...]` instrumentation removed (`grep -r` to verify) +- [ ] Throwaway prototypes / scripts deleted (or moved under `.devkit/`) +- [ ] The correct hypothesis is recorded in `.devkit/diagnose.md` and the + commit message + +## Report format + +Write `.devkit/diagnose.md` with: **Symptom**, **Phase 1 feedback loop** (the +exact command), **Ranked hypotheses**, **Root cause** (file:line), **Fix plan** +(files to change + the regression-test seam), and **Cleanup checklist**. Print +`## DIAGNOSE COMPLETE` when written. If running under `/bugfix`, control +returns there with the diagnosis as input. + +## Out of scope + +- Applying the fix beyond the regression test — `/bugfix` orchestrates that. diff --git a/harness/codex/skills/feature/SKILL.md b/harness/codex/skills/feature/SKILL.md new file mode 100644 index 0000000..ce58a0c --- /dev/null +++ b/harness/codex/skills/feature/SKILL.md @@ -0,0 +1,120 @@ +--- +name: feature +description: Orchestrates a full feature delivery pipeline (plan → code → test → review → security audit). Writes artifacts to .devkit/ and drives each phase inline in the current session. Produces a tested, reviewed, security-audited implementation ready to commit. Use when the user says "build feature X", "implement Y", "add capability Z", "ship a new endpoint/page/module", or hands off a spec to execute end-to-end. +--- + +# Feature Workflow + +End-to-end feature development driven directly by Codex. Each phase writes an +artifact under `.devkit/` and the next phase reads it. No sub-agents and no +state binary — Codex owns the whole pipeline in one session. + +> Codex note: there is no separate `devkit-state.sh` binary. State lives as +> files in `.devkit/` plus a small `.devkit/state.json` you maintain by +> editing it (advancing a step = deleting it from the `pending` list). + +## Step 1 — Initialize + +Ask for: +1. A short ticket reference (optional — e.g. `#142`, or a slug) or a feature description +2. Coder mode: "Should I write the code, or will you? (auto/engineer)" + +Set up the working directory and a minimal state file: +```bash +mkdir -p .devkit +SLUG="<ticket-or-slug>" +cat > .devkit/state.json <<JSON +{ + "workflow": "feature", + "slug": "$SLUG", + "coder_mode": "<auto|engineer>", + "current_step": 1, + "steps": ["plan", "code", "test", "review", "security", "complete"] +} +JSON +``` + +## Step 2 — Plan + +Do the planning work directly in this session: +- Scan the repo: `ls -la` and `find . -name "*.ts" -o -name "*.tsx" -o -name "*.py" | head -40` +- Grep for similar features / patterns +- Draft a phased plan with: files to create/modify, test strategy per task + (happy path, error, edge case), acceptance criteria, immutability / + function-size / type-safety rules +- Write the plan to `.devkit/plan.md` + +Print `## PLAN COMPLETE`. Bump `current_step` to 2 in `.devkit/state.json`. + +## Step 3 — Code (or engineer pause) + +**If coder_mode == auto:** implement the plan in this session. +- Immutability: create new objects, never mutate existing ones +- Functions < 50 lines, files < 800 lines +- TypeScript: no `any`, UPPER_CASE enum values, validate input at boundaries +- Python: modern typing (`X | None`, `list[T]`), Pydantic v2 for schemas +- Make atomic commits (one logical change each), conventional-commit format: + `<type>(scope?): <subject>` — present tense, not capitalized, no period, + max 72 chars. Prepend `[<ticket>]` after the colon only if a ticket exists. + Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert. +- Run the project linter on each file you write. + +Print `## CODE COMPLETE`. Bump `current_step` to 3. + +**If coder_mode == engineer:** print the plan and wait for the engineer to +implement. Resume on "done", then bump. + +## Step 4 — Test + +Write the tests in this session: +- Behaviour-first: tests describe what the system does through its public + interface, not how it does it +- One assertion per behaviour; minimal mocking (only at system boundaries: + network, clock, filesystem) +- ≥80% lines / functions / branches coverage +- TypeScript: `npx jest` (or project test script) +- Python: `pytest` (or project test script) + +Run the suite. Print `## TESTS COMPLETE`. Bump `current_step` to 4. + +## Step 5 — Review + +Review the diff yourself against clean-code conventions: +- Read `git diff` (or `git diff <base>...HEAD`) +- Output: `.devkit/review.md` with `CRITICAL` / `HIGH` / `MEDIUM` findings, + file:line references, and a `PASS/FAIL` verdict +- Block on CRITICAL. Surface HIGH for the engineer to decide. MEDIUM is + informational. + +Print `## REVIEW COMPLETE`. If verdict is NEEDS FIXES, print the findings and +ask: "Fix them now, or continue to the security audit?". + +Bump `current_step` to 5. + +## Step 6 — Security + +Audit the diff for OWASP Top 10 issues: +- Access control, cryptographic failures, injection, insecure design, + misconfiguration, vulnerable components, auth failures, data integrity, + logging failures, SSRF +- Run a dependency CVE scan: `npm audit` (Node) or `pip-audit` (Python) +- Write `.devkit/security-audit.md` with findings and a `PASS/FAIL` verdict + +Print `## AUDIT COMPLETE`. Bump `current_step` to 6. + +## Step 7 — Complete + +Mark complete: +```bash +cat > .devkit/state.json <<JSON +{ "workflow": "feature", "slug": "$SLUG", "status": "complete" } +JSON +``` + +Print a summary: steps completed / skipped, review verdict, security verdict. +Then suggest: "Run /pr to open a pull request." + +## Skipping / pausing + +- Skip a step: write a one-line note in `.devkit/state.json` (`"skipped": {"test": "no logic changes"}`) and continue. +- Pause: print "Workflow paused. Run /resume to continue." and stop. diff --git a/harness/codex/skills/grill/SKILL.md b/harness/codex/skills/grill/SKILL.md new file mode 100644 index 0000000..46e5d7a --- /dev/null +++ b/harness/codex/skills/grill/SKILL.md @@ -0,0 +1,66 @@ +--- +name: grill +description: Relentless one-question-at-a-time interview that stress-tests a plan or design before any code is written, walking every branch of the decision tree and resolving dependencies until you and the user share the same mental model. Prefers reading the codebase over asking when a question is answerable from code. Use when the user says "grill me", "stress-test this plan", "interrogate my design", "what am I missing", "poke holes in this", or is about to build something underspecified. +--- + +# Grill + +The fix for **agent misalignment**: before building, force every ambiguity to the +surface by interviewing the user one question at a time. The output is a *shared +understanding* — not a document. When you're done, you could both describe the plan the +same way. + +## The one rule that matters + +**Ask exactly one question per turn.** Never batch. Never present a numbered list of +five questions. A single question lets the user's answer reshape the next one — batching +freezes the tree before you've walked it. + +## Workflow (a loop, not a script) + +1. **Take the plan or topic.** A feature idea, a design, a ticket, a vague "I want to + build X". If a ticket/issue is referenced, fetch it first + (`gh issue view <n>` — see [`_shared/github-access.md`](../_shared/github-access.md)). + +2. **Find the next unresolved branch.** Scan the plan for the decision with the most + downstream impact that's still ambiguous. Resolve high-leverage branches first — + they collapse whole subtrees of later questions. + +3. **Try the codebase before the user.** If the question is "how does auth work here?" + or "what's the existing pattern for X?", answer it yourself by reading the code. Only + ask the user what the code *cannot* tell you: intent, priorities, constraints, + trade-offs, external facts. + +4. **Ask one question — with a recommended answer.** Always propose a default and say + why. *"I'd default to optimistic locking here because writes are rare and you said + latency matters — agree, or is contention higher than I think?"* A recommendation + turns a vague interview into a fast yes/no/adjust. + +5. **Record the resolution, resolve dependencies, repeat.** Each answer may unlock or + prune later branches. Carry decisions forward; never re-ask something settled. + +## When to stop + +Stop when there are **no unresolved branches that would change what gets built** — i.e. +shared understanding. Then summarise the resolved decisions back in 5–10 bullets and ask +the user to confirm. Don't drag the interview past the point of diminishing returns. + +## What to grill on + +- **Scope edges** — what's explicitly *out*? What's the smallest shippable version? +- **The unhappy paths** — errors, empty states, concurrent access, partial failure. +- **Data shape & lifecycle** — source of truth, validation boundary, migration story. +- **Integration seams** — what it talks to, what talks to it, what breaks if it changes. +- **Non-functionals** — latency, scale, security/PII surface, observability. +- **Definition of done** — how the user will know it works. + +## Composition + +- Run **before** `/prd` — grilling produces the resolved decisions; `/prd` writes them up. +- Run **before** `/feature` or `/to-issues` when the request is underspecified. +- `/improve-architecture` reuses this grilling loop in its Phase 3 to pin down a refactor. + +## Out of scope + +- Writing the spec — that's `/prd`. Grill resolves the unknowns; PRD records them. +- Implementing anything. No code is written during a grill. diff --git a/harness/codex/skills/handoff/SKILL.md b/harness/codex/skills/handoff/SKILL.md new file mode 100644 index 0000000..3fc6d11 --- /dev/null +++ b/harness/codex/skills/handoff/SKILL.md @@ -0,0 +1,77 @@ +--- +name: handoff +description: Compacts the current session into a single self-contained handoff document a fresh agent can pick up from cold — context, decisions made, open questions, references to existing artifacts (by path/URL, not duplicated), suggested next skills — with secrets and PII redacted. Written to the OS temp dir, tailored to the next session's stated focus. Use when the user says "hand this off", "write a handoff", "I'm running low on context", "summarize for a new session", "pause and save state", or before a context reset. +--- + +# Handoff + +Compress everything a *fresh* agent needs to continue this work into one document. +Optimized for a cold start: a new session reading only this file should know where things +stand and what to do next. + +## Workflow + +1. **Take the next-session focus.** The user's argument describes what the next session + will work on (e.g. "finish the auth refactor", "address review comments"). Tailor the + whole document to that focus — emphasize what's relevant, prune what isn't. + +2. **Read the conversation.** Understand what was discussed, decided, built, and left open. + +3. **Inventory existing artifacts.** Find what's already captured — `.devkit/prd.md`, + `.devkit/plan.md`, `.devkit/diagnose.md`, `.devkit/review.md`, `docs/adr/`, open issues, + commits, the working diff. **Reference these by path/URL; never paste their contents.** + Duplicated content drifts and bloats the handoff. + +4. **Redact sensitive data.** Scan for API keys, tokens, passwords, PII. Redact them. + The handoff is a plain file — treat it as shareable. + +5. **Write the document** (structure below) to the **OS temp directory**, not the + workspace — it's ephemeral and shouldn't be committed: + - macOS/Linux: `"${TMPDIR:-/tmp}/handoff-<slug>.md"` + - Print the absolute path so the user can hand it to the next session. + +## Document structure + +``` +# Handoff — <slug> + +## Next session focus +What the next agent should work on (from the user's argument). + +## Context / background +Where the project / task stands right now, in a few sentences. + +## Decisions made +The key conclusions reached this session, each with its one-line rationale. + +## Open questions +Unresolved items the next agent must settle — ideally pointing at who/what can answer. + +## State of the work +What's done, what's in progress, what hasn't started. Reference the diff/commits/branch. + +## References +Paths/URLs to existing artifacts (PRD, plan, ADRs, issues, commits). Links only. + +## Suggested skills +Which kit skills the next agent should run next, in order — e.g. "resume with /grill on +the open question, then /feature". (Always include this section.) + +## Sensitive data +Confirmation that secrets/PII were scanned for and redacted. +``` + +## Rules + +- **Save to temp, not the repo.** A handoff is not a project artifact. +- **Reference, don't duplicate.** Link `.devkit/*` and `docs/adr/*` by path. +- **Always redact** secrets/PII, and always include the **Suggested skills** section. + +## Composition + +- Pairs with the kit's workflow-state files: if a `/feature` or `/bugfix` run is mid-flight + (`.devkit/` state present), point the next session at the current step. + +## Out of scope + +- Continuing the work itself. This skill only packages context for the next agent. diff --git a/harness/codex/skills/improve-architecture/LANGUAGE.md b/harness/codex/skills/improve-architecture/LANGUAGE.md new file mode 100644 index 0000000..1adab07 --- /dev/null +++ b/harness/codex/skills/improve-architecture/LANGUAGE.md @@ -0,0 +1,40 @@ +# Architecture Vocabulary + +Shared terms for `/improve-architecture` (and `/zoom-out`). Use these words consistently +so reports and discussions stay precise. + +- **Module** — a unit with a public interface and a hidden implementation. A file, class, + package, or service. Not defined by size. + +- **Interface** — what a module exposes: its public functions, types, and contracts. The + *cost* a caller pays to use it. Smaller is better. + +- **Implementation** — everything hidden behind the interface. The *value* the module + provides. Larger (more behavior absorbed) is better. + +- **Depth** — the ratio of implementation value to interface cost. A **deep** module hides + significant behavior behind a tiny interface (e.g. a `parse(text) → AST` that hides a + thousand lines). A **shallow** module's interface is nearly as complex as what it does + (a pass-through wrapper, a class of getters/setters). *Prefer deep modules.* — John + Ousterhout, *A Philosophy of Software Design*. + +- **Seam** — a boundary where you can substitute behavior without editing the code on + either side (an interface + an injection point). Seams are where tests plug in. + +- **Adapter** — a concrete implementation behind a seam (e.g. a `PostgresUserRepo` behind + a `UserRepo` seam). **One adapter is a hypothetical seam; two adapters confirm a real + one.** Don't introduce a seam for a single implementation you imagine you *might* swap. + +- **Leverage** — how much behavior a small interface unlocks. Depth comes from leverage: + a five-method interface that drives ten thousand lines of correct behavior. + +- **Locality** — related code living together. A concept smeared across many tiny modules + has poor locality even if each module is "clean". + +- **The deletion test** — to check if a module is truly shallow: imagine deleting it and + inlining its callers. If complexity concentrates painfully elsewhere, it was earning its + keep. If little is lost, it was shallow. + +- **The interface is the test surface** — you test a module through its public interface, + not its internals. A well-shaped interface is therefore also a well-shaped test boundary; + if something is hard to test, the interface is usually the problem. diff --git a/harness/codex/skills/improve-architecture/SKILL.md b/harness/codex/skills/improve-architecture/SKILL.md new file mode 100644 index 0000000..5ac70d7 --- /dev/null +++ b/harness/codex/skills/improve-architecture/SKILL.md @@ -0,0 +1,74 @@ +--- +name: improve-architecture +description: Surfaces architectural friction and proposes deepening opportunities — turning shallow modules (interface nearly as complex as implementation) into deep ones, consolidating scattered concepts, and sealing leaky seams — optimizing for testability and navigability. Explores with the codebase map, presents ranked candidates, then grills the chosen one into a concrete design and optionally records an ADR. Use when the user says "improve the architecture", "this code is a mess", "reduce complexity", "find refactor opportunities", "deepen the modules", or wants periodic design hygiene. +--- + +# Improve Architecture + +Find where the codebase fights you, and propose refactors that make modules **deeper** — +a small interface hiding significant behavior — so the code is easier to test and easier +to navigate. Run it every few days as hygiene, not just in crisis. + +> Architecture vocabulary (module, interface, seam, adapter, depth): [`LANGUAGE.md`](./LANGUAGE.md). +> Domain vocabulary: [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Phase 1 — Explore for friction + +Read `CONTEXT.md` and `docs/adr/` first (vocabulary + prior decisions). Then walk the +codebase looking for friction: + +- **Shallow modules** — the interface is nearly as complex as the implementation (thin + wrappers, pass-through classes, getters/setters with no behavior). +- **Scattered concepts** — one idea smeared across many tiny files with no locality. +- **Leaky seams** — a module's internals bleed across its boundary; callers reach inside. +- **Testability pain** — code that's hard to test, or pure functions extracted *only* for + testability with no natural home. + +**Apply the deletion test** to a suspected-shallow module: imagine deleting it and +inlining its callers. If complexity *concentrates* badly elsewhere, the module was earning +its keep — not shallow. If nothing much is lost, it's a candidate. + +## Phase 2 — Present ranked candidates + +Show the candidates as a list (or, if the user wants something shareable, a self-contained +HTML report in the temp dir). Each candidate card: + +- **Files / area** involved. +- **Problem** — why today's shape causes friction. +- **Solution** — the change, in plain English. +- **Benefits** — framed as locality, leverage, testability. +- **Before → After** — a small sketch or Mermaid diagram of the shallow→deep shift. +- **Strength** — `Strong` / `Worth exploring` / `Speculative`. + +Use `CONTEXT.md` terms for the domain and `LANGUAGE.md` terms for the architecture. +Surface ADR conflicts **only when the friction is real**. End with a single top +recommendation, then ask which candidate to explore. **Propose no concrete interfaces yet.** + +## Phase 3 — Grill the chosen candidate + +Once the user picks one, run the `/grill` loop on the design: constraints, dependencies, +the deepened module's shape, what sits behind the seam, which tests survive the change. +Decisions crystallize inline: + +- Naming a new deepened module → add the term to `CONTEXT.md`. +- The user rejects a candidate **with a load-bearing reason** → offer to record an ADR in + `docs/adr/` so future runs don't re-suggest the same refactor. + +Guiding principles: *the interface is the test surface*; *one adapter is a hypothetical +seam, two adapters confirm a real one*; *depth = leverage at the interface*. + +## Rules + +- **Don't refactor in this skill.** It produces a design + (optionally) an ADR. Execution + is a separate `/feature` or `/tdd` run against the agreed design. +- **No speculative interfaces** before the user picks a candidate. +- **Real friction only** — don't invent problems to justify a rewrite. + +## Composition + +- Reuses `/grill` in Phase 3; reads/writes the same `CONTEXT.md` as `/zoom-out`. +- Hand the agreed design to `/feature` or `/tdd` to execute, then `/review`. + +## Out of scope + +- Applying the refactor. Recording unrelated decisions (just use an ADR directly). diff --git a/harness/codex/skills/pr/SKILL.md b/harness/codex/skills/pr/SKILL.md new file mode 100644 index 0000000..07570b4 --- /dev/null +++ b/harness/codex/skills/pr/SKILL.md @@ -0,0 +1,80 @@ +--- +name: pr +description: Guided GitHub flow with the gh CLI — create a branch, auto-format changed files, write a conventional commit, then open a pull request with a generated title and body. Use when the user says "open a PR", "create a pull request", "ship this", "commit and PR", "push my changes", or finishes a feature and wants it on GitHub. +--- + +# PR Workflow + +A guided GitHub flow using `gh`. Read `.claude/devkit-plan.json` `git_workflow` +for branch/commit/ticket conventions (tickets are OPTIONAL). For auth see +[`_shared/github-access.md`](../_shared/github-access.md). + +Detect the default branch once and reuse it: +```bash +BASE=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name) +``` + +## Step A — Create a branch + +Ask for the change type (from `git_workflow.branch_types`) and an optional +ticket. Branch name: `<type>/<ticket>` if a ticket exists, else +`<type>/<short-slug>`. + +```bash +git checkout "$BASE" && git pull origin "$BASE" +git checkout -b "<type>/<ticket-or-slug>" +``` + +Skip this step if the user is already on a feature branch. + +## Step B — Auto-format, then commit + +Detect the formatter from `package.json` + config files and run it on changed +files only: + +```bash +CHANGED=$(git diff --name-only --diff-filter=ACMR) +``` +- `package.json` "format"/"lint:fix" script → run it (e.g. `npm run format`) +- `biome.json` → `npx biome format --write $CHANGED` +- `.prettierrc*` → `npx prettier --write $CHANGED` +- `.eslintrc*` / eslint config → `npx eslint --fix $CHANGED` +- `pyproject.toml` `[tool.ruff]` → `ruff format $CHANGED && ruff check --fix $CHANGED` + +If none found: warn "No formatter detected — skipping auto-format" and continue. + +Write a conventional commit: `<type>(scope?): <subject>` — present tense, not +capitalized, no period, ≤72 chars. Prepend `[<ticket>]` after the colon only if +a ticket exists. Then: +```bash +git add $CHANGED +git commit -m "<message>" +git push -u origin "$(git branch --show-current)" +``` + +## Step C — Generate the PR title and body + +Title: `<subject>` (prefix `[<ticket>] ` if a ticket exists). + +Body template: +``` +## What changed +<one-paragraph summary of the diff> + +## How to test +<numbered steps to verify locally> + +## Checklist +- [ ] Self-tested locally +- [ ] /review run on the diff +- [ ] Tests pass +``` + +## Step D — Create the PR + +```bash +gh pr create --title "<title>" --body "<body>" --base "$BASE" +``` + +Print the PR URL returned by `gh pr create`. Suggest running `/review` if not +yet done. diff --git a/harness/codex/skills/prd/SKILL.md b/harness/codex/skills/prd/SKILL.md new file mode 100644 index 0000000..40db08b --- /dev/null +++ b/harness/codex/skills/prd/SKILL.md @@ -0,0 +1,82 @@ +--- +name: prd +description: Synthesizes the current conversation (ideally after a /grill session) into a concise product requirements doc at .devkit/prd.md — problem, users, scope in/out, requirements, acceptance criteria, risks — and optionally opens it as a GitHub issue. Uses the project's own domain vocabulary, references existing ADRs, and avoids stale file paths. Use when the user says "write a PRD", "spec this out", "turn this into requirements", "document what we decided", or finishes grilling a design and wants it captured. +--- + +# PRD + +Turn resolved understanding into a durable spec. A PRD answers **what** and **why**, never +**how** — no file paths, no class names, no implementation. Those go stale; intent doesn't. + +> GitHub access (optional issue creation): [`_shared/github-access.md`](../_shared/github-access.md). +> Shared vocabulary: [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Before you write + +- **Prefer running `/grill` first.** A PRD written over unresolved ambiguity just encodes + the ambiguity. If decisions are still fuzzy, say so and offer to grill first. +- **Speak the project's language.** Read `CONTEXT.md` (if present) and reuse its terms. + Read `docs/adr/` so the PRD doesn't contradict a recorded decision. + +## Document structure + +Write `.devkit/prd.md`: + +``` +# PRD — <title> + +## Problem +What's broken or missing, and why it matters now. One paragraph. + +## Users / actors +Who touches this and what they're trying to do. + +## Goals +Bulleted, outcome-shaped. "A user can X" — not "build a Y". + +## Non-goals (explicitly out of scope) +The boundaries. This is the most valuable section — it prevents scope creep. + +## Requirements +Numbered, testable statements of behavior. Each one is something /to-issues can slice +and /tdd can verify. Mark MUST / SHOULD / MAY. + +## Acceptance criteria +A checklist the finished work must satisfy. Observable, not internal. + +## Risks & open questions +What could go wrong, what's still unknown, what assumptions we're making. + +## References +Links to the source conversation decisions, related ADRs, prior issues. Reference by +path/URL — do not paste their contents. +``` + +## Rules + +- **Behavior, not implementation.** "Rejects an order with a negative total" — not "add a + guard clause in OrderService". +- **Every requirement must be testable.** If you can't imagine the test, it's not a + requirement yet — it's a wish. Sharpen or drop it. +- **Non-goals are mandatory.** An empty non-goals section means scope wasn't pinned down. +- **Cite, don't copy.** Reference ADRs and prior issues by link. + +## Optional — open as a GitHub issue + +If the user wants it tracked, ask first, then: +```bash +gh issue create --title "<title>" --body-file .devkit/prd.md +``` +Print the issue URL. Do not auto-label or assign unless asked. + +## Composition + +- After `/grill` resolves the unknowns, this records them. +- Hand the PRD to `/to-issues` to decompose into vertical-slice tickets, or to `/feature` + to execute directly. + +## Out of scope + +- Resolving ambiguity — that's `/grill`. +- Breaking work into tickets — that's `/to-issues`. +- Any implementation or test code. diff --git a/harness/codex/skills/review/SKILL.md b/harness/codex/skills/review/SKILL.md new file mode 100644 index 0000000..3939817 --- /dev/null +++ b/harness/codex/skills/review/SKILL.md @@ -0,0 +1,77 @@ +--- +name: review +description: Reviews code changes against clean-code conventions and an OWASP security checklist, with automatic security escalation when the diff touches authentication, authorization, secrets, or PII. Works on a local diff, the current branch, or a GitHub PR (number or URL). Output is CRITICAL / HIGH / MEDIUM findings with file:line references and a PASS/FAIL verdict. Use when the user says "review", "code review", "check this PR", "look at my changes", "is this safe to ship", or pastes a GitHub PR URL. +--- + +# Review Workflow + +Review code changes with automatic security escalation. + +> GitHub access: follow [`_shared/github-access.md`](../_shared/github-access.md). + +> Codex note: state lives in `.devkit/`. No `devkit-state.sh` binary — bump +> `.devkit/state.json` between phases. + +## Step 1 — Determine scope + +- GitHub PR (number or URL) provided: fetch metadata and diff. + ```bash + gh pr view <number|url> --json number,title,baseRefName,headRefName,url + gh pr diff <number|url> + ``` +- No PR given: use the local diff (staged + unstaged, or the branch diff vs the + default branch). + +Initialize state: +```bash +mkdir -p .devkit +SLUG="<pr-number-or-ticket>" +cat > .devkit/state.json <<JSON +{ + "workflow": "review", + "slug": "$SLUG", + "current_step": 1, + "steps": ["review", "security", "complete"] +} +JSON +``` + +## Step 2 — Review + +Review the diff yourself in this session: +- Clean-code conventions: immutability, function size, type safety, naming, + cohesion/coupling, error handling, test coverage of the change +- Output: `.devkit/review.md` with `CRITICAL` / `HIGH` / `MEDIUM` findings, + file:line references, and a `PASS/FAIL` verdict +- For a PR: "Review PR <number> (<head> → <base>). Get the diff via `gh pr diff`." +- For local: "Review local changes. Run `git diff`." + +Print `## REVIEW COMPLETE`. Bump `current_step` to 2. + +## Step 3 — Security check (auto-trigger) + +Scan the diff for auth/secret/PII indicators: +```bash +git diff HEAD~N | grep -iE "(auth|login|password|jwt|token|secret|pii|encrypt|permission|role)" | head -5 +``` +(For a PR, pipe `gh pr diff <number>` instead of `git diff`.) + +- Matches found: print "Auth/secret/PII changes detected — running security + audit automatically." and run the OWASP Top 10 review yourself, writing + `.devkit/security-audit.md`. Bump `current_step` to 3. +- No matches: skip security, note the skip reason in `.devkit/state.json`. + +## Step 4 — Complete + +```bash +cat > .devkit/state.json <<JSON +{ "workflow": "review", "slug": "$SLUG", "status": "complete" } +JSON +``` + +Print the review summary (CRITICAL / HIGH / MEDIUM + PASS/FAIL) and the +security verdict if it ran. + +If a PR was provided, offer to post the findings: +- General note: `gh pr comment <number|url> --body "<findings>"` +- Formal review: `gh pr review <number|url> --comment --body "<findings>"` diff --git a/harness/codex/skills/tdd/SKILL.md b/harness/codex/skills/tdd/SKILL.md new file mode 100644 index 0000000..755a952 --- /dev/null +++ b/harness/codex/skills/tdd/SKILL.md @@ -0,0 +1,100 @@ +--- +name: tdd +description: Red-green-refactor test-driven development with tracer-bullet vertical slicing. Enforces one test → one implementation cycles, behavior-over-implementation tests, deep modules, and refactor only while GREEN. Use when the user says "TDD this", "red-green-refactor", "write tests first", "drive this with tests", or is implementing a new behavior (endpoint, component, calculator, validator) and wants test-first discipline rather than test-after. +--- + +# Test-Driven Development + +Red → Green → Refactor, one vertical slice at a time. Tests verify **behavior +through public interfaces**, never implementation details. Respect the +project's testing rule (coverage ≥80%, framework per language). + +## Anti-pattern: horizontal slicing + +**NEVER write all tests first, then all implementation.** Bulk-written tests +describe imagined behavior, test data shapes instead of user-visible outcomes, +and pass while real behavior breaks. + +``` +WRONG (horizontal): + RED: test1, test2, test3, test4 + GREEN: impl1, impl2, impl3, impl4 + +RIGHT (vertical / tracer-bullet): + RED→GREEN: test1 → impl1 + RED→GREEN: test2 → impl2 +``` + +Each test responds to what the previous cycle taught you. + +## Workflow + +### 1. Plan (with the user) + +Before any code is written: +- [ ] Confirm the public interface shape (params, return type, errors raised) +- [ ] List the behaviors to test — by **what the system does**, not internal steps +- [ ] Rank: critical paths? complex logic? edge cases? +- [ ] Prefer deep modules — small interface, deep implementation +- [ ] Name tests by observable behavior ("rejects an order with a negative + total", not "calls service.foo") +- [ ] Get user approval + +Ask: *"What should the public interface look like, and which behaviors matter +most?"* You can't test everything — focus on critical paths and complex logic. + +### 2. Tracer bullet + +ONE test for ONE behavior end-to-end: `RED` (write test → it fails) then +`GREEN` (minimal code → it passes). Proves the full path works. + +TypeScript (Jest): +```typescript +it('returns 50_000 interest for a standard 10-year loan', () => { + expect(calculateInterest({ principal: 100_000, rate: 0.05, years: 10 })).toBe(50_000) +}) +``` + +Python (pytest): +```python +@pytest.mark.unit +def test_calculate_interest_standard_loan_returns_expected() -> None: + assert calculate_interest(principal=100_000, rate=0.05, years=10) == 50_000 +``` + +### 3. Incremental loop + +For each remaining behavior, repeat `RED → GREEN`. One test at a time; only +enough code to pass the current test; don't anticipate future tests. + +### 4. Refactor (only while GREEN) + +After tests pass: extract duplication, deepen modules, apply SOLID where +natural (not preemptively), and re-run the suite after **each** refactor step. +**Never refactor while RED** — reach GREEN first. + +## Per-cycle checklist + +``` +[ ] Test describes behavior, not implementation +[ ] Test uses the public interface only (no private probes, no DB queries to verify) +[ ] Test would survive an internal refactor +[ ] Implementation is minimal for this test +[ ] No speculative features added +[ ] Mocks limited to system boundaries (network, clock, filesystem) — not internals +``` + +## Composition + +- `/feature` orchestrates plan → code → test → review → security. Inside its + **code** and **test** steps, drive the work with this skill rather than + batching tests. +- `/bugfix` consumes `.devkit/diagnose.md` and adds a regression test before + the fix — that regression test is the RED in cycle 1. +- After all cycles pass, run `/review` to catch missed edge cases or test + smells. + +## Coverage gate + +Minimum **80% lines, functions, branches**. Run the project's coverage +command (`jest --coverage`, `pytest --cov`) before declaring done. diff --git a/harness/codex/skills/to-issues/SKILL.md b/harness/codex/skills/to-issues/SKILL.md new file mode 100644 index 0000000..c9292bf --- /dev/null +++ b/harness/codex/skills/to-issues/SKILL.md @@ -0,0 +1,91 @@ +--- +name: to-issues +description: Decomposes a plan or PRD into many thin, independent vertical-slice GitHub issues — each touching every layer (data → logic → UI → test) so it's demoable on its own — rather than horizontal layer-by-layer tickets. Classifies each slice as AFK (agent-implementable) or HITL (needs a human decision), sequences by dependency, gets user sign-off, then publishes in order. Use when the user says "break this into issues", "decompose this plan", "create tickets", "slice this PRD", or has a spec ready to turn into trackable work. +--- + +# To Issues + +Carve a plan into **tracer-bullet vertical slices**. Each slice is a thin end-to-end path +that touches every integration layer it needs — schema, logic, endpoint, UI, test — so it +can be built, demoed, and verified on its own. **Prefer many thin slices over few thick +ones.** + +> GitHub access: [`_shared/github-access.md`](../_shared/github-access.md). +> Domain vocabulary: [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Anti-pattern: horizontal slicing + +``` +WRONG (horizontal — nothing works until the last ticket lands): + #1 build all the DB tables + #2 build all the API endpoints + #3 build all the UI + +RIGHT (vertical — each ticket is a working sliver): + #1 user can create one draft (table + endpoint + form + test) + #2 user can publish a draft (state field + endpoint + button + test) +``` + +## Workflow + +1. **Gather context.** Use the conversation, or fetch the source: `.devkit/prd.md`, or a + referenced issue (`gh issue view <n>`). Read `CONTEXT.md` and `docs/adr/` so issue + language matches the domain and respects prior decisions. + +2. **Explore the codebase (optional).** Understand the current state so slices are + grounded in what exists. + +3. **Draft the slices.** For each, decide: + - **Title** — short, behavior-shaped. + - **Type** — `AFK` (implementable end-to-end with no human decision) or `HITL` + (needs an architectural call, design review, or product judgment). Prefer AFK. + - **Blocked by** — which other slices must land first. + +4. **Quiz the user.** Present the numbered breakdown (title / type / blocked-by / which + requirements it covers) and ask: Is the granularity right? Are the dependencies + correct? Should any slice be split or merged? Are the AFK/HITL labels accurate? + **Iterate until the user approves.** Do not publish before approval. + +5. **Publish in dependency order.** Publishing parents first means children can cite real + issue numbers in "Blocked by". For each slice: + ```bash + gh issue create --title "<title>" --body "<body from template>" + ``` + +## Issue body template + +``` +## Parent +<link to the source PRD/issue, or "None"> + +## What to build +The end-to-end behavior, described by outcome. Name domain concepts, NOT file paths — +paths go stale fast. (A decision-dense prototype sketch is fine where it adds clarity.) + +## Acceptance criteria +- [ ] <observable behavior 1> +- [ ] <observable behavior 2> + +## Type +AFK | HITL + +## Blocked by +<#issue refs, or "None — can start immediately"> +``` + +## Rules + +- **No horizontal/layered tickets.** If a ticket can't be demoed alone, re-slice it. +- **No hardcoded file paths** in bodies — they rot. Describe behavior and domain concepts. +- **Don't mark HITL work as AFK** to make it look ready. Be honest about what needs a human. +- **Never close or edit the source** PRD/issue. This skill only creates new issues. + +## Composition + +- Consumes `/prd` output (or any plan). +- Each published issue can later be picked up by `/feature` (AFK) or `/grill` then + `/feature` (HITL). + +## Out of scope + +- Writing the spec — `/prd`. Implementing a slice — `/feature` / `/tdd`. diff --git a/harness/codex/skills/triage/AGENT-BRIEF.md b/harness/codex/skills/triage/AGENT-BRIEF.md new file mode 100644 index 0000000..619de7d --- /dev/null +++ b/harness/codex/skills/triage/AGENT-BRIEF.md @@ -0,0 +1,43 @@ +# Agent Brief Format + +Posted as a comment when an issue moves to `ready-for-agent` (or `ready-for-human`). It's +the bridge between triage and execution: a fresh agent reading only this comment should be +able to start. Behavior and intent — **no stale file paths**. + +Begin with the mandatory marker, then: + +``` +> *This was generated by AI during triage.* + +## Summary +One paragraph: what this issue asks for and why it matters. + +## Reproduction (bugs only) +The exact command / steps that produce the failure, and the observed vs expected behavior. +Reference the /diagnose feedback loop if one was built. + +## Scope +- In: <what this work covers> +- Out: <what it explicitly does not> + +## Acceptance criteria +- [ ] <observable outcome 1> +- [ ] <observable outcome 2> + +## Suggested approach +A short, non-binding sketch — domain concepts and seams, not file paths. The implementing +agent owns the real design. + +## Blocked by +<#issue refs, or "None — can start immediately"> + +## Suggested skill +Which kit skill to run next: /feature, /bugfix, /tdd, /grill, … +``` + +For `ready-for-human`, add: + +``` +## Why this can't be delegated +The specific decision, access, or judgment a human must supply before an agent can proceed. +``` diff --git a/harness/codex/skills/triage/SKILL.md b/harness/codex/skills/triage/SKILL.md new file mode 100644 index 0000000..f3861e4 --- /dev/null +++ b/harness/codex/skills/triage/SKILL.md @@ -0,0 +1,80 @@ +--- +name: triage +description: Moves GitHub issues through a triage state machine — categorize as bug or enhancement, then drive needs-triage → needs-info → ready-for-agent / ready-for-human / wontfix — reproducing bugs and grilling thin reports before deciding. Shows an oldest-first attention queue, writes an agent brief for ready work, and marks AI-generated comments. Use when the user says "triage", "go through the issues", "what needs triaging", "process the backlog", "triage #42", or wants to turn raw issues into actionable, labeled work. +--- + +# Triage + +Turn raw incoming issues into labeled, actionable work via a small state machine. The kit +is GitHub-native; labels live on the repo. + +> GitHub access: [`_shared/github-access.md`](../_shared/github-access.md). +> Agent-brief format: [`AGENT-BRIEF.md`](./AGENT-BRIEF.md). + +## State machine + +**Category** (exactly one): `bug` | `enhancement`. + +**State** (exactly one): +``` +needs-triage → needs-info ↔ needs-triage + → ready-for-agent + → ready-for-human + → wontfix +``` +Unlabeled issues enter at `needs-triage`. `needs-info` returns to `needs-triage` when the +reporter replies. A maintainer can override any state at any time. + +> **Labels**: these are the canonical role names. If the repo uses different label +> strings, the user should supply a mapping; otherwise create labels matching these names +> (`gh label create`) on first run and confirm with the user. + +## What the agent does + +### 1. Show the attention queue +Three buckets, oldest-first, with counts and one-line summaries: +- **Unlabeled** (never triaged) +- **`needs-triage`** (categorized, not yet routed) +- **`needs-info`** with new reporter activity since the last triage note + +```bash +gh issue list --search "sort:created-asc" --label needs-triage --json number,title,updatedAt +``` + +### 2. Triage one issue +Read the full issue **and prior triage notes** (don't re-ask resolved questions). Check +`.out-of-scope/` for similar past rejections. Recommend a category + state with reasoning, +then act: +- **Bug** → **reproduce first** (trace the code, run tests, build a repro per `/diagnose` + Phase 1) before grilling. A bug you can't reproduce is `needs-info`. +- **Thin/underspecified** → **grill** it via `/grill` to flesh it out. +- **Apply the outcome:** + - `ready-for-agent` → post an **agent brief** (see `AGENT-BRIEF.md`). + - `ready-for-human` → agent brief **plus** a "why this can't be delegated" note. + - `needs-info` → triage note: what's established so far + the *specific* questions blocking progress. + - `wontfix` (bug) → polite close with the reason. + - `wontfix` (enhancement) → write a short rationale into `.out-of-scope/` and link it in a closing comment. + +### 3. Quick override +On a direct command ("move #42 to ready-for-agent"), confirm, apply the label, and ask +whether to write an agent brief. + +## Resuming +Re-read prior notes, check for reporter replies, surface what's still outstanding, and +never re-ask a resolved question. + +## Posting rule + +**Every comment or issue this skill posts must begin with:** +``` +> *This was generated by AI during triage.* +``` + +## Composition + +- Reproduces with `/diagnose`'s feedback-loop discipline; grills with `/grill`. +- `ready-for-agent` issues feed `/feature` (or `/bugfix` for bugs). + +## Out of scope + +- Implementing fixes. Closing/editing issues outside the state transitions above. diff --git a/harness/codex/skills/worktree/SKILL.md b/harness/codex/skills/worktree/SKILL.md new file mode 100644 index 0000000..3853353 --- /dev/null +++ b/harness/codex/skills/worktree/SKILL.md @@ -0,0 +1,51 @@ +--- +name: worktree +description: Creates a git worktree for parallel work on a branch and installs the dat-devkit harness into it so the new worktree behaves like the main checkout — while keeping each worktree's workflow state isolated. Also syncs an existing worktree. Use when the user says "make a worktree", "work on this in parallel", "spin up a worktree for X", "my worktree has no skills", or "sync my worktree". +--- + +# Worktree + +A new git worktree starts with **no harness directory** (`.codex/` here), so skills and +shared docs don't load there. This skill creates the worktree and copies the harness into +it with the right excludes, keeping each worktree's workflow state isolated. + +> Codex note: the Codex target has no `bin/` — there's no `devkit-worktree.sh`. Use raw +> `git worktree` + a scoped `rsync`, as below. + +## Workflow + +1. **Confirm intent.** Get the worktree path and branch. Place worktrees as a sibling of + the repo (`../<repo>-<feature>`) unless told otherwise. Name the branch per the + project's conventions. + +2. **Resolve the main checkout** (source of truth for the harness): + ```bash + MAIN="$(dirname "$(git rev-parse --git-common-dir)")" + ``` + +3. **Create the worktree:** + ```bash + git worktree add -b <type>/<slug> <path> + ``` + +4. **Copy the harness in, excluding nested worktrees and per-worktree state:** + ```bash + rsync -a --exclude 'worktrees/' --exclude '.devkit/' "$MAIN/.codex/" "<path>/.codex/" + ``` + (Adjust `.codex` → `.gemini` on the Gemini target.) + +5. **Tell the user to open the agent in the new worktree.** Skills load there next session. + Any `/feature` or `/bugfix` run keeps its own `.devkit/` state, isolated per worktree. + +## Notes + +- **Don't `cp -r` the whole harness dir by hand** — it drags `worktrees/` and other + worktrees' `.devkit/` state in. The `rsync` excludes above prevent that. +- **Don't symlink** the harness dir — keep per-worktree state isolated. +- After upgrading the devkit in the main checkout, re-run the `rsync` (step 4) for each + active worktree so they pick up new skills. + +## Out of scope + +- Removing worktrees — use `git worktree remove <path>` directly. +- Branch/PR mechanics once you're working in the worktree — that's `/pr`. diff --git a/harness/codex/skills/zoom-out/SKILL.md b/harness/codex/skills/zoom-out/SKILL.md new file mode 100644 index 0000000..d9912de --- /dev/null +++ b/harness/codex/skills/zoom-out/SKILL.md @@ -0,0 +1,51 @@ +--- +name: zoom-out +description: Builds a higher-level mental map of an unfamiliar part of the codebase by going UP a layer of abstraction instead of drilling down — which modules exist, how they connect, who calls what, where the seams are — and writes the durable terms into CONTEXT.md so the whole kit speaks the project's language. Use when the user says "zoom out", "help me understand this area", "how does X fit together", "I'm lost in this code", "explain this subsystem", or is about to change code they don't yet have a map of. +--- + +# Zoom Out + +When you don't know a part of the codebase, the instinct is to dive deeper. Resist it. +**Go up a layer** and build a map of how things connect before you touch anything. + +> Shared vocabulary lives in `CONTEXT.md` — see [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Workflow + +1. **Name the unfamiliar area.** A module, a feature, a directory, a symbol the user + pointed at. That's the anchor. + +2. **Build the map — don't read everything.** Find the entry points and follow the call + graph outward at the map level: `grep` for the symbol, then trace who **calls** it + (the *purpose*) and what it **calls** (the *machinery*). Going up to the callers is the + "go up a layer" move. Resist opening every file — you want the shape, not the detail. + (If a code-intelligence index is available, prefer it over grep for call/caller lookups.) + +3. **Speak the project's language.** Read `CONTEXT.md` first; describe the area using its + existing terms. If you discover a load-bearing concept that isn't named there, that's a + finding for step 5. + +4. **Explain up, not down.** Deliver: the handful of modules that matter, their + responsibilities in one line each, the call/data flow between them, the seams (where it + talks to the outside or to other subsystems), and where the user's intended change + would land. A small diagram (Mermaid) helps when the shape is graph-like. + +5. **Persist the vocabulary.** Add genuinely new, durable domain/architecture terms you + surfaced to `CONTEXT.md` (create it if absent — see the shared doc). Don't dump the + whole map there; record the *terms* future sessions need to share your understanding. + +## Rules + +- **Stay zoomed out.** The deliverable is a map, not a line-by-line tour. If the user + needs depth on one node afterward, that's a follow-up. +- **Don't change code.** This is comprehension only. + +## Composition + +- Run before `/feature`, `/bugfix`, or `/improve-architecture` on code you don't know. +- `/improve-architecture` reads the same `CONTEXT.md` this skill enriches. + +## Out of scope + +- Modifying code, or proposing refactors — that's `/improve-architecture`. +- Deep single-symbol detail — zoom back in after the map. diff --git a/harness/common/CLAUDE.md b/harness/common/CLAUDE.md index b17a7a5..2300086 100644 --- a/harness/common/CLAUDE.md +++ b/harness/common/CLAUDE.md @@ -19,16 +19,34 @@ Language-specific rules override common rules where they conflict. ## Available Skills -### Workflows (orchestrated multi-agent) +The skills cover the full engineering loop: +**align → specify → decompose → execute → verify → ship → maintain → triage → hand off.** + +### Align & specify (front of funnel) +- /grill — relentless one-question-at-a-time interview that stress-tests a plan before any code (kills agent misalignment) +- /prd — synthesize the conversation into `.devkit/prd.md`; optionally open it as a GitHub issue +- /to-issues — decompose a PRD/plan into thin, independent vertical-slice GitHub issues (AFK/HITL, dependency-ordered) + +### Execute (orchestrated multi-agent) - /feature — full feature: plan → code → test → review → security - /bugfix — bug fix: diagnose → code → test → review +- /tdd — red-green-refactor TDD (write failing test → minimal code → refactor) +- /diagnose — systematic debugging loop (reproduce → hypothesise → instrument → fix + regression test); writes `.devkit/diagnose.md` consumed by /bugfix + +### Verify & ship - /review — code review (+ auto security review if auth/secrets/external data detected) - /audit — OWASP security audit + dependency CVE scan - -### Standalone - /pr — guided GitHub workflow: branch → commit → PR via the `gh` CLI -- /tdd — red-green-refactor TDD (write failing test → minimal code → refactor) -- /diagnose — systematic debugging loop (reproduce → hypothesise → instrument → fix + regression test); writes `.devkit/diagnose.md` consumed by /bugfix + +### Understand & maintain (codebase hygiene) +- /zoom-out — map an unfamiliar area by going UP a layer; persists durable terms to `CONTEXT.md` +- /improve-architecture — find shallow-module / ball-of-mud friction, propose deepening refactors, optionally record an ADR +- /triage — move GitHub issues through a triage state machine into actionable, labeled work +- /handoff — compact the session into a temp-dir handoff doc for a fresh agent / new session +- /worktree — create a git worktree and install the harness into it (parallel work, isolated state) + +Several skills share a project-root `CONTEXT.md` glossary so the kit speaks your domain's +language — see `skills/_shared/context-doc.md`. ## Automatic Hooks diff --git a/harness/common/bin/devkit-worktree.sh b/harness/common/bin/devkit-worktree.sh new file mode 100644 index 0000000..5eb2e8b --- /dev/null +++ b/harness/common/bin/devkit-worktree.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +# devkit-worktree.sh — make dat-devkit work inside git worktrees. +# +# A freshly-created worktree has no `.claude/`, so the harness (rules, hooks, +# skills, agents, settings) doesn't load. This script copies the harness from +# the MAIN checkout into a worktree, with the right excludes, so every worktree +# behaves like the main checkout — while keeping per-worktree state isolated. +# +# Usage: +# devkit-worktree.sh add <path> [<branch>] [--base <ref>] +# git worktree add the path (creating <branch> if given), then sync .claude/. +# devkit-worktree.sh sync [<path>] +# Copy .claude/ from the main checkout into <path> (default: cwd's worktree). +# Run after creating a worktree by hand, or after upgrading the devkit. +# devkit-worktree.sh sync-all +# Sync every worktree of this repo. +# devkit-worktree.sh list +# List worktrees and whether each has .claude/ installed. +# +# Safe to re-run. Never copies worktrees/ or per-worktree state back in. +set -euo pipefail + +# ── Resolve the main checkout (where .git lives as a real directory) ──────── +# In a worktree, `.git` is a file and `git-common-dir` points at the main +# repo's .git; its parent is the main working tree that holds the source .claude/. +main_worktree() { + local common + common="$(git rev-parse --git-common-dir 2>/dev/null)" || return 1 + # Make absolute (git may print a relative path like ".git"). + case "$common" in + /*) : ;; + *) common="$(cd "$(dirname "$common")" && pwd)/$(basename "$common")" ;; + esac + dirname "$common" +} + +repo_root() { git rev-parse --show-toplevel 2>/dev/null; } + +die() { printf 'devkit-worktree: %s\n' "$*" >&2; exit 1; } + +command -v git >/dev/null 2>&1 || die "git not found" +command -v rsync >/dev/null 2>&1 || die "rsync not found" +git rev-parse --git-dir >/dev/null 2>&1 || die "not inside a git repository" + +MAIN="$(main_worktree)" || die "could not resolve the main checkout" +SRC="$MAIN/.claude" + +# Excludes shared by every sync: +# worktrees/ — never recurse worktree dirs back into a worktree +# .devkit/ — workflow STATE lives in the worktree CWD, stays per-worktree +# .claude/.devkit/ — hook logs, isolated per worktree +RSYNC_EXCLUDES=( + --exclude 'worktrees/' + --exclude '.devkit/' +) + +sync_one() { + local dest_root="$1" + [ -d "$dest_root" ] || die "worktree path does not exist: $dest_root" + [ -d "$SRC" ] || die "main checkout has no .claude/ — run install.sh in $MAIN first" + + # Don't sync onto the main checkout itself. + if [ "$(cd "$dest_root" && pwd)" = "$(cd "$MAIN" && pwd)" ]; then + printf '· %s is the main checkout — nothing to sync\n' "$dest_root" + return 0 + fi + + mkdir -p "$dest_root/.claude" + # Preserve each worktree's own hook logs: exclude .claude/.devkit/ from delete. + rsync -a "${RSYNC_EXCLUDES[@]}" --exclude '.devkit/' "$SRC/" "$dest_root/.claude/" + printf '✓ synced .claude/ -> %s/.claude/\n' "$dest_root" +} + +cmd_add() { + local path="" branch="" base="" + while [ $# -gt 0 ]; do + case "$1" in + --base) base="$2"; shift 2 ;; + -b|--branch) branch="$2"; shift 2 ;; + *) if [ -z "$path" ]; then path="$1" + elif [ -z "$branch" ]; then branch="$1" + fi; shift ;; + esac + done + [ -n "$path" ] || die "usage: devkit-worktree.sh add <path> [<branch>] [--base <ref>]" + + if [ -n "$branch" ]; then + if [ -n "$base" ]; then + git worktree add -b "$branch" "$path" "$base" + else + git worktree add -b "$branch" "$path" + fi + else + git worktree add "$path" + fi + + sync_one "$path" + printf '\nWorktree ready. cd %s and open Claude Code — the harness will load.\n' "$path" +} + +cmd_sync() { + local path="${1:-$(repo_root)}" + sync_one "$path" +} + +cmd_sync_all() { + git worktree list --porcelain \ + | awk '/^worktree /{print substr($0,10)}' \ + | while IFS= read -r wt; do + sync_one "$wt" || true + done +} + +cmd_list() { + printf '%-50s %-10s %s\n' "WORKTREE" "BRANCH" ".claude/" + git worktree list --porcelain | awk ' + /^worktree /{wt=substr($0,10)} + /^branch /{br=substr($0,8); sub(/^refs\/heads\//,"",br)} + /^detached/{br="(detached)"} + /^$/{ if (wt!="") { print wt "\t" br; wt=""; br="" } } + END{ if (wt!="") print wt "\t" br } + ' | while IFS=$'\t' read -r wt br; do + marker="—" + [ -d "$wt/.claude" ] && marker="yes" + [ "$(cd "$wt" && pwd)" = "$(cd "$MAIN" && pwd)" ] && marker="main" + printf '%-50s %-10s %s\n' "$wt" "${br:-?}" "$marker" + done +} + +cmd="${1:-}" +shift || true +case "$cmd" in + add) cmd_add "$@" ;; + sync) cmd_sync "$@" ;; + sync-all) cmd_sync_all ;; + list) cmd_list ;; + *) die "usage: devkit-worktree.sh {add|sync|sync-all|list}" ;; +esac diff --git a/harness/common/rules/worktree.md b/harness/common/rules/worktree.md index 606f1da..60e05aa 100644 --- a/harness/common/rules/worktree.md +++ b/harness/common/rules/worktree.md @@ -1,35 +1,57 @@ # Worktree Hygiene -When creating or entering a git worktree for this project, copy the project-level -`.claude/` contents — **excluding** the `worktrees/` subdirectory — into the -worktree before starting work. +A freshly-created git worktree has **no `.claude/`**, so none of the harness (rules, +hooks, skills, agents, settings) loads there until it's copied in. The devkit ships a +helper that does this correctly — use it instead of copying by hand. + +## Create or sync a worktree ```bash -rsync -a --exclude='worktrees/' .claude/ <worktree-path>/.claude/ +# Create a worktree on a new branch AND install the harness into it: +.claude/bin/devkit-worktree.sh add ../my-feature -b feature/my-feature + +# Already created a worktree by hand? Install the harness into it: +.claude/bin/devkit-worktree.sh sync ../my-feature + +# Re-sync every worktree (e.g. after upgrading the devkit in the main checkout): +.claude/bin/devkit-worktree.sh sync-all + +# See which worktrees have the harness installed: +.claude/bin/devkit-worktree.sh list ``` -This keeps the repo-specific harness (rules, hooks, skills, agents, settings) -available inside isolated worktrees so behavior stays consistent with the main -checkout, without copying nested worktree directories back in. +The `/worktree` skill wraps this — say "make a worktree for X" and the agent runs it. + +The helper resolves the **main checkout** via `git rev-parse --git-common-dir` and copies +its `.claude/` into the worktree, **excluding** `worktrees/` (never recurse worktree state +back in) and `.devkit/` (workflow state — see below). It's safe to re-run. ## When to run -- Immediately after `git worktree add <path> <branch>` -- The first time you `cd` into a worktree that doesn't yet have `.claude/` -- After installing or upgrading the devkit in the main checkout — re-sync each - active worktree so they pick up the new rules/hooks +- Right after `git worktree add` — or just use `devkit-worktree.sh add`, which does both. +- The first time you enter a worktree that has no `.claude/` yet. +- After installing or upgrading the devkit in the main checkout — `sync-all` so every + active worktree picks up the new rules/hooks/skills. ## What this gives you -- Hooks (branch/commit validation, pre-push tests, secret scan) fire inside the - worktree the same way they fire in the main checkout -- Skills and slash commands resolve correctly -- `devkit-plan.json` (statusline budgets, ticket-format config) is shared +- Hooks (branch/commit validation, pre-push tests, secret scan) fire inside the worktree + exactly as in the main checkout. They use `git rev-parse --git-dir`, which resolves + correctly through a worktree's `.git` *file*. +- Skills and slash commands resolve. +- `devkit-plan.json` (statusline budgets, ticket-format config) is shared. + +## What stays isolated per worktree + +- **`.devkit/`** — `/feature` and `/bugfix` workflow STATE lives in the worktree's CWD, so + two worktrees can run independent workflows without clobbering each other. The helper + never copies it between worktrees. +- **`.claude/.devkit/` hook logs** — each worktree keeps its own. ## Don't -- Don't symlink `.claude/` — Claude Code resolves hook paths relative to - `$CLAUDE_PROJECT_DIR` and some hooks write logs under `.claude/.devkit/`, - which you want isolated per worktree. -- Don't include `worktrees/` in the copy — that recurses worktree state back - into worktrees. +- **Don't symlink `.claude/`.** Claude Code resolves hook paths relative to + `$CLAUDE_PROJECT_DIR`, and hooks write logs under `.claude/.devkit/` — you want those + isolated per worktree, not shared through a symlink. +- **Don't hand-copy with a bare `cp -r`** — you'll drag `worktrees/` and another + worktree's `.devkit/` state in with it. Use the helper, which excludes both. diff --git a/harness/common/skills/_shared/context-doc.md b/harness/common/skills/_shared/context-doc.md new file mode 100644 index 0000000..3dcc9f6 --- /dev/null +++ b/harness/common/skills/_shared/context-doc.md @@ -0,0 +1,47 @@ +# CONTEXT.md — Shared Project Language (Shared Reference) + +Several skills (`/grill`, `/prd`, `/to-issues`, `/zoom-out`, `/improve-architecture`) read +and write a project-root `CONTEXT.md`. It's the kit's antidote to **verbosity and +misalignment**: a shared glossary so the agent and the codebase use the same words, which +cuts re-explanation and keeps specs/issues/reports in the project's own vocabulary. + +## What it is + +A short, durable, human-maintained file at the **project root** (`./CONTEXT.md`). It is +*not* documentation of how the code works — that's what the code and `/zoom-out` are for. +It's the **vocabulary and load-bearing facts** a newcomer (human or agent) needs to talk +about the project correctly. + +## What goes in it + +- **Domain glossary** — the project's nouns and verbs with one-line definitions. ("A + *Tenant* is a billing account; *Members* belong to exactly one Tenant.") +- **Key concepts / invariants** — rules that are always true and easy to violate. ("All + money is integer minor units; never floats.") +- **Module names that carry meaning** — deepened modules named during + `/improve-architecture`, so future sessions reuse the term. +- **Pointers, not prose** — "Auth lives behind the `Session` seam; see `docs/adr/004`." + +## What does NOT go in it + +- File-by-file tours, call graphs, or anything that goes stale on refactor (use `/zoom-out` + live instead). +- Secrets, credentials, or PII. +- Requirements or plans — those are `/prd` and issues. + +## How skills use it + +| Skill | Reads it to… | Writes to it when… | +|---|---|---| +| `/grill` | ask in the project's terms | (read-only) | +| `/prd` | spec in the project's terms | (read-only) | +| `/to-issues` | name issues in the project's terms | (read-only) | +| `/zoom-out` | explain in the project's terms | a new load-bearing term is discovered | +| `/improve-architecture` | reason about modules in the project's terms | a deepened module is named | + +## Bootstrapping + +If `CONTEXT.md` doesn't exist when a skill needs it, create a minimal one (title + empty +Glossary / Concepts sections) and add the terms you have. Keep it short — a CONTEXT.md +nobody maintains is worse than none. Pair it with ADRs in `docs/adr/` for *decisions* +(CONTEXT.md is for *vocabulary*). diff --git a/harness/common/skills/grill/SKILL.md b/harness/common/skills/grill/SKILL.md new file mode 100644 index 0000000..738472b --- /dev/null +++ b/harness/common/skills/grill/SKILL.md @@ -0,0 +1,69 @@ +--- +name: grill +description: Relentless one-question-at-a-time interview that stress-tests a plan or design before any code is written, walking every branch of the decision tree and resolving dependencies until you and the user share the same mental model. Prefers reading the codebase over asking when a question is answerable from code. Use when the user says "grill me", "stress-test this plan", "interrogate my design", "what am I missing", "poke holes in this", or is about to build something underspecified. +version: 1.0.0 +author: Dat +--- + +# Grill + +The fix for **agent misalignment**: before building, force every ambiguity to the +surface by interviewing the user one question at a time. The output is a *shared +understanding* — not a document. When you're done, you could both describe the plan the +same way. + +## The one rule that matters + +**Ask exactly one question per turn.** Never batch. Never present a numbered list of +five questions. A single question lets the user's answer reshape the next one — batching +freezes the tree before you've walked it. + +## Workflow (a loop, not a script) + +1. **Take the plan or topic.** A feature idea, a design, a ticket, a vague "I want to + build X". If a ticket/issue is referenced, fetch it first + (`gh issue view <n>` — see [`_shared/github-access.md`](../_shared/github-access.md)). + +2. **Find the next unresolved branch.** Scan the plan for the decision with the most + downstream impact that's still ambiguous. Resolve high-leverage branches first — + they collapse whole subtrees of later questions. + +3. **Try the codebase before the user.** If the question is "how does auth work here?" + or "what's the existing pattern for X?", answer it yourself — `codegraph_context`, + `codegraph_search`, read the code. Only ask the user what the code *cannot* tell you: + intent, priorities, constraints, trade-offs, external facts. + +4. **Ask one question — with a recommended answer.** Always propose a default and say + why. *"I'd default to optimistic locking here because writes are rare and you said + latency matters — agree, or is contention higher than I think?"* A recommendation + turns a vague interview into a fast yes/no/adjust. + +5. **Record the resolution, resolve dependencies, repeat.** Each answer may unlock or + prune later branches. Carry decisions forward; never re-ask something settled. + +## When to stop + +Stop when there are **no unresolved branches that would change what gets built** — i.e. +shared understanding. Then summarise the resolved decisions back in 5–10 bullets and ask +the user to confirm. Don't drag the interview past the point of diminishing returns; +trivia the user doesn't care about is noise, not rigor. + +## What to grill on + +- **Scope edges** — what's explicitly *out*? What's the smallest shippable version? +- **The unhappy paths** — errors, empty states, concurrent access, partial failure. +- **Data shape & lifecycle** — source of truth, validation boundary, migration story. +- **Integration seams** — what it talks to, what talks to it, what breaks if it changes. +- **Non-functionals** — latency, scale, security/PII surface, observability. +- **Definition of done** — how the user will know it works. + +## Composition + +- Run **before** `/prd` — grilling produces the resolved decisions; `/prd` writes them up. +- Run **before** `/feature` or `/to-issues` when the request is underspecified. +- `/improve-architecture` reuses this grilling loop in its Phase 3 to pin down a refactor. + +## Out of scope + +- Writing the spec — that's `/prd`. Grill resolves the unknowns; PRD records them. +- Implementing anything. No code is written during a grill. diff --git a/harness/common/skills/handoff/SKILL.md b/harness/common/skills/handoff/SKILL.md new file mode 100644 index 0000000..1c6756f --- /dev/null +++ b/harness/common/skills/handoff/SKILL.md @@ -0,0 +1,79 @@ +--- +name: handoff +description: Compacts the current session into a single self-contained handoff document a fresh agent can pick up from cold — context, decisions made, open questions, references to existing artifacts (by path/URL, not duplicated), suggested next skills — with secrets and PII redacted. Written to the OS temp dir, tailored to the next session's stated focus. Use when the user says "hand this off", "write a handoff", "I'm running low on context", "summarize for a new session", "pause and save state", or before a context reset. +version: 1.0.0 +author: Dat +--- + +# Handoff + +Compress everything a *fresh* agent needs to continue this work into one document. +Optimized for a cold start: a new session reading only this file should know where things +stand and what to do next. + +## Workflow + +1. **Take the next-session focus.** The user's argument describes what the next session + will work on (e.g. "finish the auth refactor", "address review comments"). Tailor the + whole document to that focus — emphasize what's relevant, prune what isn't. + +2. **Read the conversation.** Understand what was discussed, decided, built, and left open. + +3. **Inventory existing artifacts.** Find what's already captured — `.devkit/prd.md`, + `.devkit/plan.md`, `.devkit/diagnose.md`, `.devkit/review.md`, `docs/adr/`, open issues, + commits, the working diff. **Reference these by path/URL; never paste their contents.** + Duplicated content drifts and bloats the handoff. + +4. **Redact sensitive data.** Scan for API keys, tokens, passwords, PII. Redact them. + The handoff is a plain file — treat it as shareable. + +5. **Write the document** (structure below) to the **OS temp directory**, not the + workspace — it's ephemeral and shouldn't be committed: + - macOS/Linux: `"${TMPDIR:-/tmp}/handoff-<slug>.md"` + - Print the absolute path so the user can hand it to the next session. + +## Document structure + +``` +# Handoff — <slug> + +## Next session focus +What the next agent should work on (from the user's argument). + +## Context / background +Where the project / task stands right now, in a few sentences. + +## Decisions made +The key conclusions reached this session, each with its one-line rationale. + +## Open questions +Unresolved items the next agent must settle — ideally pointing at who/what can answer. + +## State of the work +What's done, what's in progress, what hasn't started. Reference the diff/commits/branch. + +## References +Paths/URLs to existing artifacts (PRD, plan, ADRs, issues, commits). Links only. + +## Suggested skills +Which kit skills the next agent should run next, in order — e.g. "resume with /grill on +the open question, then /feature". (Always include this section.) + +## Sensitive data +Confirmation that secrets/PII were scanned for and redacted. +``` + +## Rules + +- **Save to temp, not the repo.** A handoff is not a project artifact. +- **Reference, don't duplicate.** Link `.devkit/*` and `docs/adr/*` by path. +- **Always redact** secrets/PII, and always include the **Suggested skills** section. + +## Composition + +- Pairs with the kit's workflow-state files: if a `/feature` or `/bugfix` run is mid-flight + (`.devkit/` state present), point the next session at the current step. + +## Out of scope + +- Continuing the work itself. This skill only packages context for the next agent. diff --git a/harness/common/skills/improve-architecture/LANGUAGE.md b/harness/common/skills/improve-architecture/LANGUAGE.md new file mode 100644 index 0000000..1adab07 --- /dev/null +++ b/harness/common/skills/improve-architecture/LANGUAGE.md @@ -0,0 +1,40 @@ +# Architecture Vocabulary + +Shared terms for `/improve-architecture` (and `/zoom-out`). Use these words consistently +so reports and discussions stay precise. + +- **Module** — a unit with a public interface and a hidden implementation. A file, class, + package, or service. Not defined by size. + +- **Interface** — what a module exposes: its public functions, types, and contracts. The + *cost* a caller pays to use it. Smaller is better. + +- **Implementation** — everything hidden behind the interface. The *value* the module + provides. Larger (more behavior absorbed) is better. + +- **Depth** — the ratio of implementation value to interface cost. A **deep** module hides + significant behavior behind a tiny interface (e.g. a `parse(text) → AST` that hides a + thousand lines). A **shallow** module's interface is nearly as complex as what it does + (a pass-through wrapper, a class of getters/setters). *Prefer deep modules.* — John + Ousterhout, *A Philosophy of Software Design*. + +- **Seam** — a boundary where you can substitute behavior without editing the code on + either side (an interface + an injection point). Seams are where tests plug in. + +- **Adapter** — a concrete implementation behind a seam (e.g. a `PostgresUserRepo` behind + a `UserRepo` seam). **One adapter is a hypothetical seam; two adapters confirm a real + one.** Don't introduce a seam for a single implementation you imagine you *might* swap. + +- **Leverage** — how much behavior a small interface unlocks. Depth comes from leverage: + a five-method interface that drives ten thousand lines of correct behavior. + +- **Locality** — related code living together. A concept smeared across many tiny modules + has poor locality even if each module is "clean". + +- **The deletion test** — to check if a module is truly shallow: imagine deleting it and + inlining its callers. If complexity concentrates painfully elsewhere, it was earning its + keep. If little is lost, it was shallow. + +- **The interface is the test surface** — you test a module through its public interface, + not its internals. A well-shaped interface is therefore also a well-shaped test boundary; + if something is hard to test, the interface is usually the problem. diff --git a/harness/common/skills/improve-architecture/SKILL.md b/harness/common/skills/improve-architecture/SKILL.md new file mode 100644 index 0000000..f53f692 --- /dev/null +++ b/harness/common/skills/improve-architecture/SKILL.md @@ -0,0 +1,78 @@ +--- +name: improve-architecture +description: Surfaces architectural friction and proposes deepening opportunities — turning shallow modules (interface nearly as complex as implementation) into deep ones, consolidating scattered concepts, and sealing leaky seams — optimizing for testability and navigability. Explores with the codebase map, presents ranked candidates, then grills the chosen one into a concrete design and optionally records an ADR. Use when the user says "improve the architecture", "this code is a mess", "reduce complexity", "find refactor opportunities", "deepen the modules", or wants periodic design hygiene. +version: 1.0.0 +author: Dat +disable-model-invocation: true +--- + +# Improve Architecture + +Find where the codebase fights you, and propose refactors that make modules **deeper** — +a small interface hiding significant behavior — so the code is easier to test and easier +for both humans and agents to navigate. Run it every few days as hygiene, not just in crisis. + +> Architecture vocabulary (module, interface, seam, adapter, depth): [`LANGUAGE.md`](./LANGUAGE.md). +> Domain vocabulary: [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Phase 1 — Explore for friction + +Read `CONTEXT.md` and `docs/adr/` first (vocabulary + prior decisions). Then walk the +codebase looking for friction — use `codegraph_context` / `codegraph_impact` to see how +concepts spread and what depends on what: + +- **Shallow modules** — the interface is nearly as complex as the implementation (thin + wrappers, pass-through classes, getters/setters with no behavior). +- **Scattered concepts** — one idea smeared across many tiny files with no locality. +- **Leaky seams** — a module's internals bleed across its boundary; callers reach inside. +- **Testability pain** — code that's hard to test, or pure functions extracted *only* for + testability with no natural home. + +**Apply the deletion test** to a suspected-shallow module: imagine deleting it and +inlining its callers. If complexity *concentrates* badly elsewhere, the module was earning +its keep — not shallow. If nothing much is lost, it's a candidate. + +## Phase 2 — Present ranked candidates + +Show the candidates as a list (or, if the user wants something shareable, a self-contained +HTML report in the temp dir). Each candidate card: + +- **Files / area** involved. +- **Problem** — why today's shape causes friction. +- **Solution** — the change, in plain English. +- **Benefits** — framed as locality, leverage, testability. +- **Before → After** — a small sketch or Mermaid diagram of the shallow→deep shift. +- **Strength** — `Strong` / `Worth exploring` / `Speculative`. + +Use `CONTEXT.md` terms for the domain and `LANGUAGE.md` terms for the architecture. +Surface ADR conflicts **only when the friction is real**. End with a single top +recommendation, then ask which candidate to explore. **Propose no concrete interfaces yet.** + +## Phase 3 — Grill the chosen candidate + +Once the user picks one, run the `/grill` loop on the design: constraints, dependencies, +the deepened module's shape, what sits behind the seam, which tests survive the change. +Decisions crystallize inline: + +- Naming a new deepened module → add the term to `CONTEXT.md`. +- The user rejects a candidate **with a load-bearing reason** → offer to record an ADR in + `docs/adr/` so future runs don't re-suggest the same refactor. + +Guiding principles: *the interface is the test surface*; *one adapter is a hypothetical +seam, two adapters confirm a real one*; *depth = leverage at the interface*. + +## Rules + +- **Don't refactor in this skill.** It produces a design + (optionally) an ADR. Execution + is a separate `/feature` or `/tdd` run against the agreed design. +- **No speculative interfaces** before the user picks a candidate. +- **Real friction only** — don't invent problems to justify a rewrite. + +## Composition + +- Reuses `/grill` in Phase 3; reads/writes the same `CONTEXT.md` as `/zoom-out`. +- Hand the agreed design to `/feature` or `/tdd` to execute, then `/review`. + +## Out of scope + +- Applying the refactor. Recording unrelated decisions (just use an ADR directly). diff --git a/harness/common/skills/prd/SKILL.md b/harness/common/skills/prd/SKILL.md new file mode 100644 index 0000000..55fe83a --- /dev/null +++ b/harness/common/skills/prd/SKILL.md @@ -0,0 +1,84 @@ +--- +name: prd +description: Synthesizes the current conversation (ideally after a /grill session) into a concise product requirements doc at .devkit/prd.md — problem, users, scope in/out, requirements, acceptance criteria, risks — and optionally opens it as a GitHub issue. Uses the project's own domain vocabulary, references existing ADRs, and avoids stale file paths. Use when the user says "write a PRD", "spec this out", "turn this into requirements", "document what we decided", or finishes grilling a design and wants it captured. +version: 1.0.0 +author: Dat +--- + +# PRD + +Turn resolved understanding into a durable spec. A PRD answers **what** and **why**, never +**how** — no file paths, no class names, no implementation. Those go stale; intent doesn't. + +> GitHub access (optional issue creation): [`_shared/github-access.md`](../_shared/github-access.md). +> Shared vocabulary: [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Before you write + +- **Prefer running `/grill` first.** A PRD written over unresolved ambiguity just encodes + the ambiguity. If decisions are still fuzzy, say so and offer to grill first. +- **Speak the project's language.** Read `CONTEXT.md` (if present) and reuse its terms. + Read `docs/adr/` so the PRD doesn't contradict a recorded decision. + +## Document structure + +Write `.devkit/prd.md`: + +``` +# PRD — <title> + +## Problem +What's broken or missing, and why it matters now. One paragraph. + +## Users / actors +Who touches this and what they're trying to do. + +## Goals +Bulleted, outcome-shaped. "A user can X" — not "build a Y". + +## Non-goals (explicitly out of scope) +The boundaries. This is the most valuable section — it prevents scope creep. + +## Requirements +Numbered, testable statements of behavior. Each one is something /to-issues can slice +and /tdd can verify. Mark MUST / SHOULD / MAY. + +## Acceptance criteria +A checklist the finished work must satisfy. Observable, not internal. + +## Risks & open questions +What could go wrong, what's still unknown, what assumptions we're making. + +## References +Links to the source conversation decisions, related ADRs, prior issues. Reference by +path/URL — do not paste their contents. +``` + +## Rules + +- **Behavior, not implementation.** "Rejects an order with a negative total" — not "add a + guard clause in OrderService". +- **Every requirement must be testable.** If you can't imagine the test, it's not a + requirement yet — it's a wish. Sharpen or drop it. +- **Non-goals are mandatory.** An empty non-goals section means scope wasn't pinned down. +- **Cite, don't copy.** Reference ADRs and prior issues by link. + +## Optional — open as a GitHub issue + +If the user wants it tracked, ask first, then: +```bash +gh issue create --title "<title>" --body-file .devkit/prd.md +``` +Print the issue URL. Do not auto-label or assign unless asked. + +## Composition + +- After `/grill` resolves the unknowns, this records them. +- Hand the PRD to `/to-issues` to decompose into vertical-slice tickets, or to `/feature` + to execute directly. + +## Out of scope + +- Resolving ambiguity — that's `/grill`. +- Breaking work into tickets — that's `/to-issues`. +- Any implementation or test code. diff --git a/harness/common/skills/to-issues/SKILL.md b/harness/common/skills/to-issues/SKILL.md new file mode 100644 index 0000000..6efcbab --- /dev/null +++ b/harness/common/skills/to-issues/SKILL.md @@ -0,0 +1,93 @@ +--- +name: to-issues +description: Decomposes a plan or PRD into many thin, independent vertical-slice GitHub issues — each touching every layer (data → logic → UI → test) so it's demoable on its own — rather than horizontal layer-by-layer tickets. Classifies each slice as AFK (agent-implementable) or HITL (needs a human decision), sequences by dependency, gets user sign-off, then publishes in order. Use when the user says "break this into issues", "decompose this plan", "create tickets", "slice this PRD", or has a spec ready to turn into trackable work. +version: 1.0.0 +author: Dat +--- + +# To Issues + +Carve a plan into **tracer-bullet vertical slices**. Each slice is a thin end-to-end path +that touches every integration layer it needs — schema, logic, endpoint, UI, test — so it +can be built, demoed, and verified on its own. **Prefer many thin slices over few thick +ones.** + +> GitHub access: [`_shared/github-access.md`](../_shared/github-access.md). +> Domain vocabulary: [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Anti-pattern: horizontal slicing + +``` +WRONG (horizontal — nothing works until the last ticket lands): + #1 build all the DB tables + #2 build all the API endpoints + #3 build all the UI + +RIGHT (vertical — each ticket is a working sliver): + #1 user can create one draft (table + endpoint + form + test) + #2 user can publish a draft (state field + endpoint + button + test) +``` + +## Workflow + +1. **Gather context.** Use the conversation, or fetch the source: `.devkit/prd.md`, or a + referenced issue (`gh issue view <n>`). Read `CONTEXT.md` and `docs/adr/` so issue + language matches the domain and respects prior decisions. + +2. **Explore the codebase (optional).** Understand the current state with + `codegraph_context` so slices are grounded in what exists. + +3. **Draft the slices.** For each, decide: + - **Title** — short, behavior-shaped. + - **Type** — `AFK` (implementable end-to-end with no human decision) or `HITL` + (needs an architectural call, design review, or product judgment). Prefer AFK. + - **Blocked by** — which other slices must land first. + +4. **Quiz the user.** Present the numbered breakdown (title / type / blocked-by / which + requirements it covers) and ask: Is the granularity right? Are the dependencies + correct? Should any slice be split or merged? Are the AFK/HITL labels accurate? + **Iterate until the user approves.** Do not publish before approval. + +5. **Publish in dependency order.** Publishing parents first means children can cite real + issue numbers in "Blocked by". For each slice: + ```bash + gh issue create --title "<title>" --body "<body from template>" + ``` + +## Issue body template + +``` +## Parent +<link to the source PRD/issue, or "None"> + +## What to build +The end-to-end behavior, described by outcome. Name domain concepts, NOT file paths — +paths go stale fast. (A decision-dense prototype sketch is fine where it adds clarity.) + +## Acceptance criteria +- [ ] <observable behavior 1> +- [ ] <observable behavior 2> + +## Type +AFK | HITL + +## Blocked by +<#issue refs, or "None — can start immediately"> +``` + +## Rules + +- **No horizontal/layered tickets.** If a ticket can't be demoed alone, re-slice it. +- **No hardcoded file paths** in bodies — they rot. Describe behavior and domain concepts. +- **Don't mark HITL work as AFK** to make it look ready. Be honest about what needs a human. +- **Never close or edit the source** PRD/issue. This skill only creates new issues. + +## Composition + +- Consumes `/prd` output (or any plan). +- Each published issue can later be picked up by `/feature` (AFK) or `/grill` then + `/feature` (HITL). + +## Out of scope + +- Writing the spec — `/prd`. Implementing a slice — `/feature` / `/tdd`. diff --git a/harness/common/skills/triage/AGENT-BRIEF.md b/harness/common/skills/triage/AGENT-BRIEF.md new file mode 100644 index 0000000..619de7d --- /dev/null +++ b/harness/common/skills/triage/AGENT-BRIEF.md @@ -0,0 +1,43 @@ +# Agent Brief Format + +Posted as a comment when an issue moves to `ready-for-agent` (or `ready-for-human`). It's +the bridge between triage and execution: a fresh agent reading only this comment should be +able to start. Behavior and intent — **no stale file paths**. + +Begin with the mandatory marker, then: + +``` +> *This was generated by AI during triage.* + +## Summary +One paragraph: what this issue asks for and why it matters. + +## Reproduction (bugs only) +The exact command / steps that produce the failure, and the observed vs expected behavior. +Reference the /diagnose feedback loop if one was built. + +## Scope +- In: <what this work covers> +- Out: <what it explicitly does not> + +## Acceptance criteria +- [ ] <observable outcome 1> +- [ ] <observable outcome 2> + +## Suggested approach +A short, non-binding sketch — domain concepts and seams, not file paths. The implementing +agent owns the real design. + +## Blocked by +<#issue refs, or "None — can start immediately"> + +## Suggested skill +Which kit skill to run next: /feature, /bugfix, /tdd, /grill, … +``` + +For `ready-for-human`, add: + +``` +## Why this can't be delegated +The specific decision, access, or judgment a human must supply before an agent can proceed. +``` diff --git a/harness/common/skills/triage/SKILL.md b/harness/common/skills/triage/SKILL.md new file mode 100644 index 0000000..4a034c1 --- /dev/null +++ b/harness/common/skills/triage/SKILL.md @@ -0,0 +1,83 @@ +--- +name: triage +description: Moves GitHub issues through a triage state machine — categorize as bug or enhancement, then drive needs-triage → needs-info → ready-for-agent / ready-for-human / wontfix — reproducing bugs and grilling thin reports before deciding. Shows an oldest-first attention queue, writes an agent brief for ready work, and marks AI-generated comments. Use when the user says "triage", "go through the issues", "what needs triaging", "process the backlog", "triage #42", or wants to turn raw issues into actionable, labeled work. +version: 1.0.0 +author: Dat +disable-model-invocation: true +--- + +# Triage + +Turn raw incoming issues into labeled, actionable work via a small state machine. The kit +is GitHub-native; labels live on the repo. + +> GitHub access: [`_shared/github-access.md`](../_shared/github-access.md). +> Agent-brief format: [`AGENT-BRIEF.md`](./AGENT-BRIEF.md). + +## State machine + +**Category** (exactly one): `bug` | `enhancement`. + +**State** (exactly one): +``` +needs-triage → needs-info ↔ needs-triage + → ready-for-agent + → ready-for-human + → wontfix +``` +Unlabeled issues enter at `needs-triage`. `needs-info` returns to `needs-triage` when the +reporter replies. A maintainer can override any state at any time. + +> **Labels**: these are the canonical role names. If the repo uses different label +> strings, the user should supply a mapping; otherwise create labels matching these names +> (`gh label create`) on first run and confirm with the user. + +## What the agent does + +### 1. Show the attention queue +Three buckets, oldest-first, with counts and one-line summaries: +- **Unlabeled** (never triaged) +- **`needs-triage`** (categorized, not yet routed) +- **`needs-info`** with new reporter activity since the last triage note + +```bash +gh issue list --search "sort:created-asc" --label needs-triage --json number,title,updatedAt +``` + +### 2. Triage one issue +Read the full issue **and prior triage notes** (don't re-ask resolved questions). Check +`.out-of-scope/` for similar past rejections. Recommend a category + state with reasoning, +then act: +- **Bug** → **reproduce first** (trace code with `codegraph_context`, run tests, build a + repro per `/diagnose` Phase 1) before grilling. A bug you can't reproduce is `needs-info`. +- **Thin/underspecified** → **grill** it via `/grill` to flesh it out. +- **Apply the outcome:** + - `ready-for-agent` → post an **agent brief** (see `AGENT-BRIEF.md`). + - `ready-for-human` → agent brief **plus** a "why this can't be delegated" note. + - `needs-info` → triage note: what's established so far + the *specific* questions blocking progress. + - `wontfix` (bug) → polite close with the reason. + - `wontfix` (enhancement) → write a short rationale into `.out-of-scope/` and link it in a closing comment. + +### 3. Quick override +On a direct command ("move #42 to ready-for-agent"), confirm, apply the label, and ask +whether to write an agent brief. + +## Resuming +Re-read prior notes, check for reporter replies, surface what's still outstanding, and +never re-ask a resolved question. + +## Posting rule + +**Every comment or issue this skill posts must begin with:** +``` +> *This was generated by AI during triage.* +``` + +## Composition + +- Reproduces with `/diagnose`'s feedback-loop discipline; grills with `/grill`. +- `ready-for-agent` issues feed `/feature` (or `/bugfix` for bugs). + +## Out of scope + +- Implementing fixes. Closing/editing issues outside the state transitions above. diff --git a/harness/common/skills/worktree/SKILL.md b/harness/common/skills/worktree/SKILL.md new file mode 100644 index 0000000..d58f4e0 --- /dev/null +++ b/harness/common/skills/worktree/SKILL.md @@ -0,0 +1,65 @@ +--- +name: worktree +description: Creates a git worktree for parallel work on a branch and installs the dat-devkit harness (rules, hooks, skills, agents, settings) into it so the new worktree behaves exactly like the main checkout — while keeping each worktree's workflow state isolated. Also syncs an existing worktree or re-syncs all of them after a devkit upgrade. Use when the user says "make a worktree", "work on this in parallel", "spin up a worktree for X", "my worktree has no skills/hooks", or "sync my worktrees". +version: 1.0.0 +author: Dat +--- + +# Worktree + +A new git worktree starts with **no `.claude/`**, so the harness doesn't load there. This +skill creates the worktree and installs the harness into it correctly — the right files, +the right excludes, workflow state kept per-worktree. + +> Background and the don't-symlink rationale: [`../../rules/worktree.md`](../../rules/worktree.md). + +## The helper does the work + +All operations go through `${CLAUDE_PROJECT_DIR}/.claude/bin/devkit-worktree.sh`. It +resolves the main checkout (`git rev-parse --git-common-dir`) as the source of truth and +rsyncs its `.claude/` into the target, excluding `worktrees/` and `.devkit/` state. + +## Workflow + +1. **Confirm intent.** Get the worktree path and branch. Conventionally place worktrees as + a sibling of the repo (`../<repo>-<feature>`) or under `.claude/worktrees/<name>` — ask + if unspecified. Pick a branch name following the project's `git_workflow.branch_types` + (see `.claude/devkit-plan.json`). + +2. **Create + install in one step:** + ```bash + "${CLAUDE_PROJECT_DIR}/.claude/bin/devkit-worktree.sh" add <path> -b <type>/<slug> + ``` + This runs `git worktree add` and then syncs `.claude/` into the new worktree. + +3. **For an existing worktree** that's missing the harness: + ```bash + "${CLAUDE_PROJECT_DIR}/.claude/bin/devkit-worktree.sh" sync <path> + ``` + +4. **After upgrading the devkit** in the main checkout, refresh every worktree: + ```bash + "${CLAUDE_PROJECT_DIR}/.claude/bin/devkit-worktree.sh" sync-all + ``` + +5. **Inspect** which worktrees have the harness: + ```bash + "${CLAUDE_PROJECT_DIR}/.claude/bin/devkit-worktree.sh" list + ``` + +6. **Tell the user to open Claude Code in the new worktree.** Hooks and skills load on the + next session there. Any `/feature` or `/bugfix` run inside it keeps its own `.devkit/` + state, isolated from the main checkout and other worktrees. + +## Notes + +- **Don't `cp -r .claude` by hand** — it drags `worktrees/` and other worktrees' `.devkit/` + state in. The helper excludes both. +- **Don't symlink `.claude/`** — hook logs under `.claude/.devkit/` must stay per-worktree. +- This is the `claude` target. On `codex`/`gemini` there's no `bin/`; the codex variant of + this skill falls back to raw `git worktree add` + a scoped `rsync`. + +## Out of scope + +- Removing worktrees — use `git worktree remove <path>` directly. +- Branch/PR mechanics once you're working in the worktree — that's `/pr`. diff --git a/harness/common/skills/zoom-out/SKILL.md b/harness/common/skills/zoom-out/SKILL.md new file mode 100644 index 0000000..265c4ff --- /dev/null +++ b/harness/common/skills/zoom-out/SKILL.md @@ -0,0 +1,62 @@ +--- +name: zoom-out +description: Builds a higher-level mental map of an unfamiliar part of the codebase by going UP a layer of abstraction instead of drilling down — which modules exist, how they connect, who calls what, where the seams are — and writes the durable terms into CONTEXT.md so the whole kit speaks the project's language. Use when the user says "zoom out", "help me understand this area", "how does X fit together", "I'm lost in this code", "explain this subsystem", or is about to change code they don't yet have a map of. +version: 1.0.0 +author: Dat +disable-model-invocation: true +--- + +# Zoom Out + +When you don't know a part of the codebase, the instinct is to dive deeper. Resist it. +**Go up a layer** and build a map of how things connect before you touch anything. + +> Shared vocabulary lives in `CONTEXT.md` — see [`_shared/context-doc.md`](../_shared/context-doc.md). + +## Workflow + +1. **Name the unfamiliar area.** A module, a feature, a directory, a symbol the user + pointed at. That's the anchor. + +2. **Build the map structurally — don't read everything.** This kit has CodeGraph; use + it. It answers "how does this connect" in a handful of sub-millisecond calls that + grep + read cannot: + - `codegraph_context "<area>"` — entry points, related symbols, key code, in one call. + - `codegraph_callers <symbol>` / `codegraph_callees <symbol>` — who drives this, what + it drives. This is the "go up a layer" move: callers show the *purpose*, callees the + *machinery*. + - `codegraph_trace <from> <to>` — the actual path between two points (incl. dynamic + dispatch). Ideal for "how does a request reach this handler". + - `codegraph_files <dir>` — what lives here. + If CodeGraph isn't initialized, fall back to `grep`/read, but stay at the map level — + resist opening every file. + +3. **Speak the project's language.** Read `CONTEXT.md` first; describe the area using its + existing terms. If you discover a load-bearing concept that isn't named there, that's a + finding for step 5. + +4. **Explain up, not down.** Deliver: the handful of modules that matter, their + responsibilities in one line each, the call/data flow between them, the seams (where it + talks to the outside or to other subsystems), and where the user's intended change + would land. A small diagram (Mermaid) helps when the shape is graph-like. + +5. **Persist the vocabulary.** Add genuinely new, durable domain/architecture terms you + surfaced to `CONTEXT.md` (create it if absent — see the shared doc). Don't dump the + whole map there; record the *terms* future sessions need to share your understanding. + +## Rules + +- **Stay zoomed out.** The deliverable is a map, not a line-by-line tour. If the user + needs depth on one node afterward, that's a follow-up. +- **Trust CodeGraph results** — they're from a full AST parse. Don't re-verify with grep. +- **Don't change code.** This is comprehension only. + +## Composition + +- Run before `/feature`, `/bugfix`, or `/improve-architecture` on code you don't know. +- `/improve-architecture` reads the same `CONTEXT.md` this skill enriches. + +## Out of scope + +- Modifying code, or proposing refactors — that's `/improve-architecture`. +- Deep single-symbol detail — zoom back in with a direct `codegraph_node` after the map. diff --git a/install.sh b/install.sh index 9f05482..3c586a1 100755 --- a/install.sh +++ b/install.sh @@ -4,8 +4,8 @@ # # Targets: # claude (default) — .claude/ with rules, hooks, skills, agents, bin -# codex — .codex/ with AGENTS.md (concatenated rules) -# gemini — .gemini/ with GEMINI.md (concatenated rules) +# codex — .codex/ with AGENTS.md + skill directories +# gemini — .gemini/ with GEMINI.md + skill directories # # Multiple languages are supported for polyglot projects: # ./install.sh typescript python /path/to/project @@ -184,6 +184,77 @@ build_rules_bundle() { done } +# Install codex skills into the Codex target. Core skills come from +# harness/codex/skills/; optional plugins contribute from +# plugins/<name>/skills-codex/. The directory layout is just "<skill>/SKILL.md" +# so a project that points Codex at .codex/ picks them up automatically. +install_codex_skills() { + local dest="$PROJECT/.codex" + [ -d "$SCRIPT_DIR/harness/codex/skills" ] || return 0 + + # Shared reference docs (github-access, context-doc) live beside skills and + # are linked from SKILL.md bodies as ../_shared/<file>. + if [ -d "$SCRIPT_DIR/harness/codex/_shared" ]; then + run_or_preview "cp -r harness/codex/_shared -> .codex/_shared/" \ + "mkdir -p \"$dest/_shared\" && cp -r \"$SCRIPT_DIR/harness/codex/_shared/\"* \"$dest/_shared/\"" + fi + + for s in "$SCRIPT_DIR/harness/codex/skills/"*; do + [ -d "$s" ] || continue + local name + name="$(basename "$s")" + run_or_preview "cp -r harness/codex/skills/$name -> .codex/$name/" \ + "mkdir -p \"$dest/$name\" && cp -r \"$SCRIPT_DIR/harness/codex/skills/$name/\"* \"$dest/$name/\"" + done + + for plugin in "${PLUGINS[@]}"; do + local psrc="$SCRIPT_DIR/plugins/$plugin/skills-codex" + [ -d "$psrc" ] || continue + for s in "$psrc/"*; do + [ -d "$s" ] || continue + local name + name="$(basename "$s")" + run_or_preview "cp -r plugins/$plugin/skills-codex/$name -> .codex/$name/" \ + "mkdir -p \"$dest/$name\" && cp -r \"$psrc/$name/\"* \"$dest/$name/\"" + done + done +} + +# Install codex-format skills into the Gemini target. Skills live under +# .gemini/<name>/SKILL.md and are picked up by the Gemini CLI in the same +# way Codex picks them up from .codex/. +install_gemini_skills() { + local dest="$PROJECT/.gemini" + [ -d "$SCRIPT_DIR/harness/codex/skills" ] || return 0 + + # Shared reference docs (github-access, context-doc) live beside skills and + # are linked from SKILL.md bodies as ../_shared/<file>. + if [ -d "$SCRIPT_DIR/harness/codex/_shared" ]; then + run_or_preview "cp -r harness/codex/_shared -> .gemini/_shared/" \ + "mkdir -p \"$dest/_shared\" && cp -r \"$SCRIPT_DIR/harness/codex/_shared/\"* \"$dest/_shared/\"" + fi + + for s in "$SCRIPT_DIR/harness/codex/skills/"*; do + [ -d "$s" ] || continue + local name + name="$(basename "$s")" + run_or_preview "cp -r harness/codex/skills/$name -> .gemini/$name/" \ + "mkdir -p \"$dest/$name\" && cp -r \"$SCRIPT_DIR/harness/codex/skills/$name/\"* \"$dest/$name/\"" + done + + for plugin in "${PLUGINS[@]}"; do + local psrc="$SCRIPT_DIR/plugins/$plugin/skills-codex" + [ -d "$psrc" ] || continue + for s in "$psrc/"*; do + [ -d "$s" ] || continue + local name + name="$(basename "$s")" + run_or_preview "cp -r plugins/$plugin/skills-codex/$name -> .gemini/$name/" \ + "mkdir -p \"$dest/$name\" && cp -r \"$psrc/$name/\"* \"$dest/$name/\"" + done + done +} + # Install opt-in plugins into the Claude target. Each plugin contributes any of # skills/, rules/, hooks/ and declares external prerequisites in `requires`. install_plugins() { @@ -361,8 +432,10 @@ install_codex() { local dest="$PROJECT/.codex" echo "Installing dat-devkit ($LANG_LABEL) into $dest/" echo "" - echo "Note: Codex supports AGENTS.md for instructions only." - echo " Hooks, skills, agents, and plugins are Claude Code features — skipped." + echo "Note: Codex supports AGENTS.md for instructions and skill directories" + echo " (one folder per skill, each with a SKILL.md). Hooks, agents, and" + echo " Claude-only sub-agent dispatch are not available — skills drive" + echo " multi-phase work directly in-session." echo "" run_or_preview "mkdir -p .codex/" "mkdir -p \"$dest\"" @@ -384,10 +457,22 @@ install_codex() { } > "$dest/AGENTS.md" fi + echo "-> Skills (core + any --with plugins)..." + install_codex_skills + echo "" if [ "$DRY_RUN" = false ]; then - echo "Done! AGENTS.md written to $dest/" - echo " $(wc -l < "$dest/AGENTS.md") lines" + echo "Done! dat-devkit installed in $dest/" + echo " AGENTS.md: $(wc -l < "$dest/AGENTS.md") lines" + if [ -d "$dest" ]; then + local skill_count + skill_count=$(find "$dest" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ') + echo " Skills: $skill_count" + for s in "$dest"/*/; do + [ -d "$s" ] || continue + echo " - $(basename "$s")" + done + fi else echo "[dry-run] No files written." fi @@ -399,8 +484,9 @@ install_gemini() { local dest="$PROJECT/.gemini" echo "Installing dat-devkit ($LANG_LABEL) into $dest/" echo "" - echo "Note: Gemini CLI supports GEMINI.md for instructions only." - echo " Hooks, skills, agents, and plugins are Claude Code features — skipped." + echo "Note: Gemini CLI supports GEMINI.md for instructions and skill" + echo " directories (one folder per skill, each with a SKILL.md). The" + echo " same skill layout Codex uses is reused here." echo "" run_or_preview "mkdir -p .gemini/" "mkdir -p \"$dest\"" @@ -422,10 +508,22 @@ install_gemini() { } > "$dest/GEMINI.md" fi + echo "-> Skills (core + any --with plugins)..." + install_gemini_skills + echo "" if [ "$DRY_RUN" = false ]; then - echo "Done! GEMINI.md written to $dest/" - echo " $(wc -l < "$dest/GEMINI.md") lines" + echo "Done! dat-devkit installed in $dest/" + echo " GEMINI.md: $(wc -l < "$dest/GEMINI.md") lines" + if [ -d "$dest" ]; then + local skill_count + skill_count=$(find "$dest" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ') + echo " Skills: $skill_count" + for s in "$dest"/*/; do + [ -d "$s" ] || continue + echo " - $(basename "$s")" + done + fi else echo "[dry-run] No files written." fi diff --git a/plugins/gitlab/skills-codex/gitlab-pr/SKILL.md b/plugins/gitlab/skills-codex/gitlab-pr/SKILL.md new file mode 100644 index 0000000..58ec3ef --- /dev/null +++ b/plugins/gitlab/skills-codex/gitlab-pr/SKILL.md @@ -0,0 +1,49 @@ +--- +name: gitlab-pr +description: Creates a GitLab merge request from the current branch using the glab CLI (or a GitLab MCP server). Use when the user says "open a GitLab MR", "create a merge request", "raise an MR on GitLab", or works in a GitLab-hosted repo. Optional plugin — requires glab. +--- + +# GitLab MR + +> **Optional plugin.** This skill is only available when the `gitlab` plugin +> is installed (`install.sh --with gitlab`). It requires the **glab CLI** +> (authenticated via `glab auth login`) or a configured GitLab MCP server. The +> default dat-devkit is GitHub-native and uses `gh` instead. + +## Workflow + +1. **Confirm prerequisites.** Check `glab` is available and authenticated: + ```bash + command -v glab && glab auth status + ``` + If missing, tell the user to install and authenticate `glab` (or enable a + GitLab MCP server) — do not fall back to `gh`, which targets GitHub. + +2. **Verify the branch.** Ensure work is committed and the branch is pushed: + ```bash + git push -u origin "$(git branch --show-current)" + ``` + Never push directly to a protected branch — open an MR from a feature + branch. + +3. **Draft the MR description** from the full branch diff against the default + branch (`git diff <default>...HEAD`): summary of changes + a short test + plan. + +4. **Create the MR:** + ```bash + glab mr create \ + --source-branch "$(git branch --show-current)" \ + --title "<summary>" \ + --description "<generated description>" \ + --remove-source-branch=false + ``` + +5. **Report the MR URL** back to the user. + +## Notes + +- Title and description format follow the project's own conventions — read the + repo's contributing guide if present. +- Keep one logical change per MR; squash on merge if the project prefers it. +- This skill does not approve or merge — that stays a human decision. diff --git a/plugins/notion-prd/skills-codex/prd-authoring/SKILL.md b/plugins/notion-prd/skills-codex/prd-authoring/SKILL.md new file mode 100644 index 0000000..3bffe34 --- /dev/null +++ b/plugins/notion-prd/skills-codex/prd-authoring/SKILL.md @@ -0,0 +1,50 @@ +--- +name: prd-authoring +description: Authors and updates product requirement documents (PRDs) as Notion pages via the Notion MCP server. Use when the user says "write a PRD", "draft a product spec in Notion", "create a requirements doc", or "update the PRD page". Optional plugin — requires a Notion MCP server. +--- + +# PRD Authoring (Notion) + +> **Optional plugin.** This skill is only available when the `notion-prd` +> plugin is installed (`install.sh --with notion-prd`). It requires a +> configured **Notion MCP server** with an integration token that has access +> to the target workspace/parent page. Without it, the Notion tools are +> unavailable and this skill is inert. + +## Workflow + +1. **Confirm the Notion MCP is connected.** If the Notion tools aren't + available, tell the user to configure the Notion MCP server and share the + target parent page/database with the integration. + +2. **Gather PRD inputs** by asking the user (or reading from context): + - Problem statement and target users + - Goals and non-goals + - Proposed solution / scope + - Success metrics + - Risks, dependencies, open questions + +3. **Locate the destination** — ask for the parent page or database where the + PRD should live; search Notion by title if the user names an existing + page. + +4. **Create or update the PRD page** via the Notion MCP tools with a standard + structure: + - Title + - Overview / Problem + - Goals & Non-Goals + - Requirements (functional + non-functional) + - Out of Scope + - Metrics + - Risks & Open Questions + +5. **Return the page URL** so the user can review and share it. + +## Notes + +- This skill writes the PRD; it does not run engineering planning. After the + PRD is approved, hand off to your normal planning/feature workflow. +- Keep the document concise and skimmable — headings, bullets, and tables + over long prose. +- Don't invent requirements: flag anything you inferred as an open question + for the author to confirm.