From e78605ffb3a2fede050add21ad7a312405c6f53d Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Mon, 13 Apr 2026 12:01:51 -0400 Subject: [PATCH 1/3] feat: add harness-audit workflow, expand language rules, add common rules - New harness-audit workflow + skill: audits CLAUDE.md, hooks, MCP configs, agent definitions, and permissions for misconfigurations and injection risks - New common.md rules: cross-platform, language-agnostic (paths, temp dirs, assumption-surfacing, error messages) - New language rules: java, kotlin, swift, csharp - CLAUDE.md: add "state assumptions" convention, update layout table --- CLAUDE.md | 3 +- resources/rules/common.md | 20 ++++++++++ resources/rules/csharp.md | 17 ++++++++ resources/rules/java.md | 17 ++++++++ resources/rules/kotlin.md | 18 +++++++++ resources/rules/swift.md | 17 ++++++++ skills/harness-audit/SKILL.md | 14 +++++++ workflows/harness-audit.yml | 74 +++++++++++++++++++++++++++++++++++ 8 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 resources/rules/common.md create mode 100644 resources/rules/csharp.md create mode 100644 resources/rules/java.md create mode 100644 resources/rules/kotlin.md create mode 100644 resources/rules/swift.md create mode 100644 skills/harness-audit/SKILL.md create mode 100644 workflows/harness-audit.yml diff --git a/CLAUDE.md b/CLAUDE.md index f399772..e5ff2a7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -31,7 +31,7 @@ devkit is a Claude Code plugin: deterministic YAML workflow engine, thin-dispatc | `agents/*.md` | 6 subagent definitions | documenter, improver, researcher, reviewer, security-auditor, test-writer | | `mcpb/` | MCPB bundle (launcher, manifest.json, server) | Packaged distribution artifact | | `bin/devkit` | User-facing CLI wrapper | Shells out to the `devkit-engine` Go binary | -| `resources/rules/` | Language coding rules | Installed via the `setup-rules` skill | +| `resources/rules/` | Language coding rules (common + go/python/rust/typescript/shell/java/kotlin/swift/csharp) | Installed via the `setup-rules` skill | | `.claude-plugin/plugin.json` | Plugin manifest | Name, version, `mcpServers` pointer | | `src/Makefile` | Build + test + version sync | `make build`, `make test`, `make check`, `make sync-version` | | `commands/references/` | 3 reference files pulled in by skills (`debug-checklists.md`, `domain-probes.md`, `stub-patterns.md`) | Shared checklist/probe/stub content; write new work as skills | @@ -46,6 +46,7 @@ devkit is a Claude Code plugin: deterministic YAML workflow engine, thin-dispatc ## Conventions +- State assumptions before implementing. If multiple interpretations exist, present them — don't pick silently. - Never push directly to `main`. Always PR. Direct push bypasses the version-bump and release pipeline. - Never amend commits — create new ones, even after pre-commit hook failures. - Never skip hooks (`--no-verify`, `--no-gpg-sign`) without explicit user consent. diff --git a/resources/rules/common.md b/resources/rules/common.md new file mode 100644 index 0000000..8749b3a --- /dev/null +++ b/resources/rules/common.md @@ -0,0 +1,20 @@ +--- +paths: + - "**/*" +--- + +# Common Rules + +Language-agnostic principles. Applied alongside language-specific rules. + +- State assumptions before implementing. If multiple interpretations exist, present them — don't pick silently. +- One concern per commit. One concern per function. If you say "and", split it. +- Name things for what they do, not where they came from or how they work. +- Delete dead code. Commented-out code is dead code. +- Tests prove behavior, not implementation. If the test breaks on a refactor, it tested the wrong thing. +- Error messages include: what happened, what was expected, what to do next. +- Validate at system boundaries (user input, external APIs, file I/O). Trust internal code. +- Paths: use forward slashes or `path.join`/`filepath.Join` — never hardcode `\`. +- Line endings: let `.gitattributes` or the runtime handle it — never assume `\n`. +- File operations: use `os.MkdirAll`/`makedirs(exist_ok=True)` — never assume dirs exist. +- Temp files: use the OS temp directory (`os.TempDir()`/`tempfile`/`os.tmpdir()`) — never hardcode `/tmp`. diff --git a/resources/rules/csharp.md b/resources/rules/csharp.md new file mode 100644 index 0000000..0a76c09 --- /dev/null +++ b/resources/rules/csharp.md @@ -0,0 +1,17 @@ +--- +paths: + - "**/*.cs" +--- + +# C# Rules + +- `readonly` fields, `init` properties. Immutable where possible. +- Records for immutable data. `record struct` when value semantics + small size. +- `using` declaration (not block) for `IDisposable`. `await using` for `IAsyncDisposable`. +- `??` for null coalescing. `?.` for null conditional. Avoid `!` (null-forgiving) — fix the nullability instead. +- Pattern matching: `is`, `switch` expressions, relational/logical patterns over chains of `if`. +- `async Task` over `async void` (except event handlers). Never `.Result` or `.Wait()` — deadlock risk. +- `IReadOnlyList` / `IReadOnlyDictionary` in public APIs. Mutable types stay internal. +- Dependency injection via constructor. `IOptions` for configuration. +- `string.Equals(a, b, StringComparison.Ordinal)` for case-sensitive. `OrdinalIgnoreCase` for insensitive. +- `Path.Combine()` for file paths. `Environment.GetFolderPath()` for special directories. diff --git a/resources/rules/java.md b/resources/rules/java.md new file mode 100644 index 0000000..76e1fb7 --- /dev/null +++ b/resources/rules/java.md @@ -0,0 +1,17 @@ +--- +paths: + - "**/*.java" +--- + +# Java Rules + +- `Optional` return types, never null. `Optional.empty()` over `Optional.ofNullable(null)`. +- Records for immutable data carriers. Sealed interfaces for closed type hierarchies. +- `try-with-resources` for all `AutoCloseable`. Never manual `close()` in `finally`. +- `List.of()` / `Map.of()` for unmodifiable collections. `new ArrayList<>(List.of(...))` when mutation needed. +- `Objects.requireNonNull()` at public API boundaries with descriptive message. +- Stream pipelines for transforms. `for` loops for side effects or early exit. +- `private final` fields. Constructor injection over field injection. +- `BigDecimal` for money. Never `float`/`double` for currency. +- `@Override` always. Compiler catches signature drift. +- Checked exceptions for recoverable conditions. Runtime exceptions for programming errors. diff --git a/resources/rules/kotlin.md b/resources/rules/kotlin.md new file mode 100644 index 0000000..beae3af --- /dev/null +++ b/resources/rules/kotlin.md @@ -0,0 +1,18 @@ +--- +paths: + - "**/*.kt" + - "**/*.kts" +--- + +# Kotlin Rules + +- `val` over `var`. Immutable by default. +- Data classes for DTOs. Sealed classes/interfaces for closed hierarchies. +- `?.let { }` over null checks. `?:` (Elvis) for defaults. Avoid `!!` — it's a crash waiting to happen. +- `use { }` for `Closeable` resources (Kotlin's try-with-resources). +- Extension functions for utility — but only when they read like natural operations on the type. +- `when` over `if-else` chains. Exhaustive `when` on sealed types (no `else` branch needed). +- `listOf()` / `mapOf()` for read-only. `mutableListOf()` when mutation needed. +- Coroutines: `suspend` functions over callbacks. `withContext(Dispatchers.IO)` for blocking I/O. +- `require()` / `check()` for preconditions — they throw `IllegalArgumentException` / `IllegalStateException`. +- Named arguments when 2+ params of same type: `createUser(name = "x", email = "y")`. diff --git a/resources/rules/swift.md b/resources/rules/swift.md new file mode 100644 index 0000000..1160800 --- /dev/null +++ b/resources/rules/swift.md @@ -0,0 +1,17 @@ +--- +paths: + - "**/*.swift" +--- + +# Swift Rules + +- `let` over `var`. Immutable by default. +- `guard let` for early exit. `if let` for optional binding in the happy path. +- `struct` over `class` unless reference semantics are needed. +- `enum` with associated values over stringly-typed APIs. +- `throws` for recoverable errors. `fatalError()` only for truly impossible states. +- `[weak self]` in escaping closures that outlive the caller. `[unowned self]` only when lifetime is guaranteed. +- `async/await` over completion handlers. `Task { }` at boundaries, `await` inside. +- Access control: `private` by default, widen only as needed. `internal` is implicit — spell it out if intentional. +- `Codable` for serialization. Custom `init(from:)` only when the JSON shape differs from the model. +- Collections: prefer `map`/`filter`/`compactMap` over manual loops. `forEach` only for side effects. diff --git a/skills/harness-audit/SKILL.md b/skills/harness-audit/SKILL.md new file mode 100644 index 0000000..96c2ea0 --- /dev/null +++ b/skills/harness-audit/SKILL.md @@ -0,0 +1,14 @@ +--- +name: harness-audit +description: Audit the agent harness itself — CLAUDE.md, hooks, MCP configs, agent definitions, and permissions — for misconfigurations, injection risks, and security gaps. Use when the user asks to "audit my setup", "check my harness config", "is my agent config secure", "review my hooks", "check my MCP setup", or before trusting a new project's harness with autonomous work. Worth using on first clone of an unfamiliar repo, after adding new hooks or MCP servers, or when onboarding a new team member. Do NOT use for auditing project source code (use audit or tri-security), debugging workflow failures (use tri-debug or bugfix), or reviewing code changes (use tri-review). +--- + +# Harness Audit + +Audit agent harness configuration for security and misconfiguration issues. + +## Invoke + +Use the `devkit_start` tool with workflow: "harness-audit" and input: "{input}". + +Then follow each step the engine returns. Call `devkit_advance` after completing each step. The engine controls step order, gates, and loops. Do NOT skip steps. diff --git a/workflows/harness-audit.yml b/workflows/harness-audit.yml new file mode 100644 index 0000000..5475a76 --- /dev/null +++ b/workflows/harness-audit.yml @@ -0,0 +1,74 @@ +name: Harness Audit +description: Audit the agent harness configuration — CLAUDE.md, hooks, MCP configs, agent definitions, skills — for misconfigurations, injection risks, and permission issues + +steps: + - id: inventory + model: general + enforce: soft + prompt: | + Inventory the agent harness configuration in this project. Find and read: + + 1. CLAUDE.md / AGENTS.md / GEMINI.md (root-level instruction files) + 2. .claude/settings.json and .claude/settings.local.json (permissions, MCP servers) + 3. hooks/ directory (hooks.json + all referenced scripts) + 4. agents/ directory (all .md agent definitions) + 5. skills/ directory (all SKILL.md files — frontmatter only, not full content) + 6. .mcp.json or any MCP config files + 7. .claude-plugin/plugin.json (plugin manifest) + + For each file found, note: path, size, what it configures. + For files NOT found, note their absence — missing configs can be a finding too. + + Output a structured inventory. Do NOT evaluate yet — just collect. + + - id: analyze + model: smart + prompt: | + Review the harness inventory for security and configuration issues. + + Inventory: {{inventory}} + + Check each category: + + **Injection risks in instruction files:** + - CLAUDE.md containing instructions that could be overridden by repo content + - Overly broad tool permissions ("allow all", wildcard patterns) + - Instructions that disable safety checks or skip verification + + **Hook security:** + - Hook scripts that execute unvalidated input + - Missing hooks for dangerous operations (force push, file deletion) + - Hook scripts with hardcoded secrets or tokens + - Shell commands that break on Windows (no cross-platform fallback) + + **MCP configuration:** + - MCP servers with overly broad permissions + - Servers pointing to untrusted or external endpoints + - Missing authentication on sensitive MCP servers + + **Agent definitions:** + - Agents with excessive tool access (Write + Bash + no isolation) + - Missing isolation: worktree for agents that edit files + - Agents without maxTurns limits + + **Permission gaps:** + - Sensitive operations not gated by hooks + - Missing deny patterns for destructive commands + + For each finding: severity (critical/high/medium/low), category, file:line, description, remediation. + + - id: report + model: fast + prompt: | + Compile the harness audit into a final report. + + Analysis: {{analyze}} + + Format: + 1. **Grade** (A-F) based on overall harness security posture + 2. **Critical/High findings** — must fix before trusting this harness with autonomous work + 3. **Medium/Low findings** — hardening opportunities + 4. **What's good** — things configured correctly (acknowledge good practice) + 5. **Recommendations** — prioritized list of changes + + Be direct. A clean harness with no findings gets an A and a short report. From 7c3e2a32af95365710dffac61d07df43daaf64c2 Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Mon, 13 Apr 2026 12:08:57 -0400 Subject: [PATCH 2/3] docs: update README, ROADMAP for harness-audit and expanded rules - README: add common/java/kotlin/swift/csharp to coding rules table, bump skill count to 39 - ROADMAP: bump to 39 skills, 22 workflows, add harness-audit to lists --- README.md | 7 ++++++- ROADMAP.md | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aa20dc4..154d449 100644 --- a/README.md +++ b/README.md @@ -247,11 +247,16 @@ Language-specific rules that auto-activate when Claude reads matching files. Ins | Language | Examples | |---|---| +| Common | Cross-platform paths, assumption-surfacing, error messages, temp dirs | | Go | Error wrapping, context.Context, defer traps, JSON float64 gotcha | | TypeScript | `unknown` not `any`, discriminated unions, catch narrowing | | Python | Exception chains, type hints, dataclasses, pathlib | | Rust | Ownership, `?` propagation, newtypes, clippy-as-errors | | Shell | `set -euo pipefail`, quoting, macOS portability | +| Java | Optional, records, try-with-resources, BigDecimal for money | +| Kotlin | `val` default, sealed classes, coroutines, Elvis operator | +| Swift | `guard let`, struct-first, async/await, weak self | +| C# | Records, pattern matching, async Task, Path.Combine | --- @@ -293,7 +298,7 @@ Terminal usage (devkit workflow ""): ``` devkit/ ├── commands/ # Legacy (references/ only); new entry points go in skills/ -├── skills/ # 38 skills (workflow triggers, principles, tools, utilities) + _principles.yml +├── skills/ # 39 skills (workflow triggers, principles, tools, utilities) + _principles.yml ├── agents/ # 6 agents (reviewer, researcher, improver, ...) ├── hooks/ # 12 hooks (safety, security, quality gates, workflow enforcement) ├── workflows/ # 21 YAML workflow definitions diff --git a/ROADMAP.md b/ROADMAP.md index b50aa3c..22e70bc 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -5,7 +5,7 @@ - **MCP engine** — Go server exposes `devkit_start`, `devkit_advance`, `devkit_status`, `devkit_list` tools inside Claude Code. Step ordering enforced via MCP tool scoping + PreToolUse hook exit 2. Session state in session.json (hot path, <50ms hook reads) + SQLite (cold history). ~65% token reduction vs old monolithic prompts. - **Skills-first architecture** — All entry points are skills in `skills/` (tab-completable slash commands in current Claude Code; bare names like `/tri-review` work, `/devkit:` form also works for disambiguation). Primary user-facing commands: `/tri-review`, `/tri-debug`, `/tri-security`, `/health`, `/setup-rules` (user-only via `disable-model-invocation`). Every workflow also has a dedicated skill for natural-language dispatch. The `commands/` directory is retained for backward compat but empty of new entries — redundant tri-* command files were removed (skills take precedence per Claude Code docs) and the generic `/devkit:workflow ` runner was removed since every workflow now has its own slash command (`/feature`, `/bugfix`, etc.). - **Deterministic workflow conversion** — All command logic moved from LLM-interpreted markdown to Go-engine-driven YAML workflows; ~3,600 lines of inline logic removed -- **38 skills** — 21 workflow trigger skills (feature, bugfix, refactor, audit, research, deep-research, pr-ready, autoloop, test-gen, doc-gen, onboard, tri-review, tri-debug, tri-security, tri-dispatch, self-audit, self-improve, self-lint, self-migrate, self-perf, self-test) + 7 coding principles (executing, clean-code, DRY, YAGNI, dont-reinvent, stuck, scratchpad) + 4 tools (gcli, scrape, screenshot, browser) + 1 meta-orchestration (mega-pr) + 2 content (changelog, adr) + 1 reference (creating-workflows) +- **39 skills** — 22 workflow trigger skills (feature, bugfix, refactor, audit, harness-audit, research, deep-research, pr-ready, autoloop, test-gen, doc-gen, onboard, tri-review, tri-debug, tri-security, tri-dispatch, self-audit, self-improve, self-lint, self-migrate, self-perf, self-test) + 7 coding principles (executing, clean-code, DRY, YAGNI, dont-reinvent, stuck, scratchpad) + 4 tools (gcli, scrape, screenshot, browser) + 1 meta-orchestration (mega-pr) + 2 content (changelog, adr) + 1 reference (creating-workflows) - **Deterministic skill dispatch for every workflow** — Every one of the 21 workflows has a natural-language trigger skill with keyword-rich description. Saying "build a feature", "tri review", "deep research X", etc. deterministically invokes the matching skill, which calls `devkit_start` and the engine enforces every step from there. Closes the entry-gate non-determinism where 11/18 workflows previously had no natural-language path. Skill tool added to the guard allowlist so nested mid-workflow skill dispatch works. - **6 agents** — Scoped tool access, worktree isolation, model assignment - **12 hooks** — Safety (destructive command blocking, edit-time security patterns, PR gate), observability (audit trail, slop detection, post-validation, subagent verification, language-aware code review), optimization (RTK token compression), workflow enforcement (devkit-guard, devkit-stop-guard) @@ -15,7 +15,7 @@ - **Early-exit conditions** — Self-improvement loops stop when goal is met, not just at max iterations - **Token budget guidance** — Per-command budget recommendations with model downgrade patterns - **RTK token optimization** — Optional PreToolUse hook compresses Bash output via RTK (60-90% savings) -- **21 YAML workflows** — Portable workflow definitions (feature, bugfix, refactor, research, deep-research, autoloop, self-*, tri-*, test-gen, doc-gen, onboard) +- **22 YAML workflows** — Portable workflow definitions (feature, bugfix, refactor, research, deep-research, autoloop, harness-audit, self-*, tri-*, test-gen, doc-gen, onboard) - **Separate marketplace** — Multi-plugin marketplace at `5uck1ess/marketplace` - **Companion ecosystem** — Evaluated official marketplace, documented holistic setup with 7 complementary plugins - **Hypothesis-driven perf** — Evidence gathering, ranked hypotheses, one-at-a-time testing replaces blind benchmark loops From d6bb9fb8b5fdcff936feac7191696ee3d1993719 Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Mon, 13 Apr 2026 12:11:33 -0400 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20fix=20remaining=20workflow=20count?= =?UTF-8?q?=20references=20(21=E2=86=9222)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI validate-counts caught two more spots in README.md and one in ROADMAP.md still saying 21 workflows. --- README.md | 4 ++-- ROADMAP.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 154d449..f910dc8 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ Enforcement (runs automatically): ## Workflows -All 21 YAML workflows are invoked via the MCP engine. Every workflow has a trigger skill so natural-language keywords dispatch deterministically — saying "build a feature", "fix this bug", "tri review", or "deep research X" fires the matching skill, which calls `devkit_start` and the engine takes over. +All 22 YAML workflows are invoked via the MCP engine. Every workflow has a trigger skill so natural-language keywords dispatch deterministically — saying "build a feature", "fix this bug", "tri review", or "deep research X" fires the matching skill, which calls `devkit_start` and the engine takes over. Every workflow is also a tab-completable slash command. Bare names work (`/feature`, `/bugfix`, `/tri-review`, `/health`, `/setup-rules`); the fully-qualified `/devkit:` form also works if you want to disambiguate from another plugin or a Claude Code built-in. @@ -301,7 +301,7 @@ devkit/ ├── skills/ # 39 skills (workflow triggers, principles, tools, utilities) + _principles.yml ├── agents/ # 6 agents (reviewer, researcher, improver, ...) ├── hooks/ # 12 hooks (safety, security, quality gates, workflow enforcement) -├── workflows/ # 21 YAML workflow definitions +├── workflows/ # 22 YAML workflow definitions ├── resources/rules/ # Language-specific coding rules ├── src/ # Go engine + MCP server │ ├── mcp/ # MCP server (tools, principles loader, session management) diff --git a/ROADMAP.md b/ROADMAP.md index 22e70bc..2d609c0 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -6,7 +6,7 @@ - **Skills-first architecture** — All entry points are skills in `skills/` (tab-completable slash commands in current Claude Code; bare names like `/tri-review` work, `/devkit:` form also works for disambiguation). Primary user-facing commands: `/tri-review`, `/tri-debug`, `/tri-security`, `/health`, `/setup-rules` (user-only via `disable-model-invocation`). Every workflow also has a dedicated skill for natural-language dispatch. The `commands/` directory is retained for backward compat but empty of new entries — redundant tri-* command files were removed (skills take precedence per Claude Code docs) and the generic `/devkit:workflow ` runner was removed since every workflow now has its own slash command (`/feature`, `/bugfix`, etc.). - **Deterministic workflow conversion** — All command logic moved from LLM-interpreted markdown to Go-engine-driven YAML workflows; ~3,600 lines of inline logic removed - **39 skills** — 22 workflow trigger skills (feature, bugfix, refactor, audit, harness-audit, research, deep-research, pr-ready, autoloop, test-gen, doc-gen, onboard, tri-review, tri-debug, tri-security, tri-dispatch, self-audit, self-improve, self-lint, self-migrate, self-perf, self-test) + 7 coding principles (executing, clean-code, DRY, YAGNI, dont-reinvent, stuck, scratchpad) + 4 tools (gcli, scrape, screenshot, browser) + 1 meta-orchestration (mega-pr) + 2 content (changelog, adr) + 1 reference (creating-workflows) -- **Deterministic skill dispatch for every workflow** — Every one of the 21 workflows has a natural-language trigger skill with keyword-rich description. Saying "build a feature", "tri review", "deep research X", etc. deterministically invokes the matching skill, which calls `devkit_start` and the engine enforces every step from there. Closes the entry-gate non-determinism where 11/18 workflows previously had no natural-language path. Skill tool added to the guard allowlist so nested mid-workflow skill dispatch works. +- **Deterministic skill dispatch for every workflow** — Every one of the 22 workflows has a natural-language trigger skill with keyword-rich description. Saying "build a feature", "tri review", "deep research X", etc. deterministically invokes the matching skill, which calls `devkit_start` and the engine enforces every step from there. Closes the entry-gate non-determinism where 11/18 workflows previously had no natural-language path. Skill tool added to the guard allowlist so nested mid-workflow skill dispatch works. - **6 agents** — Scoped tool access, worktree isolation, model assignment - **12 hooks** — Safety (destructive command blocking, edit-time security patterns, PR gate), observability (audit trail, slop detection, post-validation, subagent verification, language-aware code review), optimization (RTK token compression), workflow enforcement (devkit-guard, devkit-stop-guard) - **Graceful degradation** — tri:* commands work with 1-3 agents depending on installed CLIs