Skip to content

[rig-tasks] Add 10 rig samples — 2026-07-27 - #217

Merged
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-07-27-7dc9c5436d12c3ed
Jul 27, 2026
Merged

[rig-tasks] Add 10 rig samples — 2026-07-27#217
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-07-27-7dc9c5436d12c3ed

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Summary

Added 10 new rig sample files to skills/rig/samples/.

# File Description Typecheck
1 210-test-file-naming-enforcer.md Scan test files and classify naming convention violations with defineTool pass
2 211-pkg-dependency-graph-extractor.md Extract and classify npm dependencies using p.read + p.bash + defineTool pass
3 212-ts-export-usage-counter.md Count TypeScript export usages via async defineTool with execSync pass
4 213-git-rename-tracker.md Track git file renames with p.bash + s.array + repair addon pass
5 214-yaml-lint-checker.md Validate YAML files via async defineTool using node:fs/promises pass
6 215-two-phase-complexity-review.md Two-subagent complexity review with coordinator + extractor delegation pass
7 216-dockerfile-layer-analyzer.md Analyze Dockerfile layers for cache efficiency via defineTool + p.readOptional pass
8 217-git-worktree-status.md Report git worktree statuses with defineTool classification + repair pass
9 218-ts-interface-conflict-checker.md Detect duplicate TypeScript interface names with steering+repair addons pass
10 219-npm-audit-simplifier.md Simplify npm audit output with defineTool vuln classification + s.enum action pass

Typecheck failures

None — all 10 samples passed typecheck.

Tasks run

  • (reused) Test file naming convention enforcer
  • (reused) Package dependency graph extractor
  • (reused) TypeScript exported symbol usage counter
  • (reused) Git file rename tracker
  • (reused) YAML file lint checker
  • (reused) Two-phase code complexity reviewer
  • (new) Dockerfile layer analyzer
  • (new) Git worktree status reporter
  • (new) TypeScript interface conflict checker
  • (new) NPM audit simplifier

Generated by Daily Rig Task Generator · sonnet46 143.8 AIC · ⌖ 10.2 AIC · ⊞ 6.7K ·

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pelikhan
pelikhan marked this pull request as ready for review July 27, 2026 06:07
@pelikhan
pelikhan merged commit b5630fb into main Jul 27, 2026
1 check passed
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /grill-with-docs and /tdd — requesting changes on correctness issues in tool handlers and output schemas.

📋 Key Themes & Highlights

Key Themes

  • Broken regex backreference (210): .replace(/.../, '.test.$1') produces a literal $1 — the most impactful bug since it corrupts all missing-spec suggestions.
  • Enum/handler mismatch (210): "wrong-prefix" is in the output schema but never returned by the tool, creating a misleading contract.
  • Unused parameter (211): name is declared in parameters but never used, adding noise for the LLM.
  • Misleading tool signature (217): classifyWorktree accepts path but completely ignores it; the tool description should reflect the actual split of responsibilities.
  • Record loses duplicate keys (218): interfaces keyed by name drops all-but-one entry for conflicting interfaces — the core data the agent is meant to surface.

Positive Highlights

  • ✅ All 10 samples pass typecheck
  • ✅ Good variety of patterns: defineTool, async handlers, p.readOptional, repair(), steering(), subagent delegation
  • ✅ Defensive fallbacks in bash commands (|| echo '{}', 2>/dev/null)
  • ✅ 213 (git-rename-tracker) and 219 (npm-audit-simplifier) are clean, idiomatic, copy-paste-ready examples

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 56.8 AIC · ⌖ 4.62 AIC · ⊞ 6.3K
Comment /matt to run again

}
return { convention: "missing-spec" as const, suggestedName: base.replace(/\.(ts|js|tsx|jsx)$/, ".test.$1") };
},
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] Broken backreference: .test.$1 is a literal string — the regex has no capture group, so every missing-spec suggestion will contain the literal text $1 instead of the actual extension.

💡 Fix

Capture the extension explicitly:

// current (broken):
base.replace(/\.(ts|js|tsx|jsx)$/, '.test.$1')

// fixed:
const ext = base.split('.').pop();
return { convention: 'missing-spec' as const, suggestedName: base.replace(/\.(ts|js|tsx|jsx)$/, ``) + `.test.${ext}` };

Or use a replacement function: .replace(/\.(ts|js|tsx|jsx)$/, (_, e) => .${e})

model: "small",
instructions: p`Find all test files: ${p.bash("find . \\( -name '*.test.ts' -o -name '*.spec.ts' -o -name '*.test.js' -o -name '*.spec.js' -o -name '*Test.ts' -o -name '*Test.js' \\) -not -path '*/node_modules/*' | head -60")}. Use the classifyFile tool for each file path. Build a record keyed by file path with the convention classification and optional suggestedName. Set allConform to true only when every entry is classified as correct.`,
output: s.object({
files: s.record(s.object({

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] Output schema includes "wrong-prefix" as a convention enum value, but the tool handler never returns it — only "correct", "wrong-suffix", and "missing-spec" are possible. This creates a misleading contract and can confuse the LLM into hallucinating that case.

💡 Fix

Remove "wrong-prefix" from the output s.enum to match the tool's actual return values, or add a handler branch that detects wrong-prefix files (e.g. test.foo.ts).

inPeerDependencies: s.boolean,
}),
handler({ inDependencies, inDevDependencies, inPeerDependencies }) {
if (inPeerDependencies) return "peer";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] The name parameter is declared in parameters but never destructured or used in the handler body. This is dead input that inflates the tool's parameter surface without contributing to its output, and may mislead the agent into passing extra data unnecessarily.

const { execSync } = await import("node:child_process");
try {
const escaped = symbolName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const out = execSync(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] Shell-injecting symbolName directly into a grep command string is a command injection risk in a real tool. Even though the input is sanitised with a regex escape, the pattern is embedded in double-quoted shell interpolation, which means symbols containing \" or \ could still break the command. For a sample that readers will copy, consider using grep -F (fixed-string) to remove the need for regex escaping entirely.

💡 Safer alternative
const out = execSync(
  `grep -rln -F "${symbolName}" --include="*.ts" . | grep -v node_modules`,
  { encoding: 'utf8' }
);```

`-F` treats the pattern as a literal string, eliminating the escaping surface.

</details>

isDetached: s.boolean,
}),
handler({ branch, isBare, isDetached }) {
if (isBare) return "bare";

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] classifyWorktree ignores the path parameter entirely and always returns "clean" for non-bare, non-detached worktrees — even if the working tree has modifications. The actual dirty-detection is delegated to the agent via the git status intent, but the tool's description says nothing about this split. This makes the tool's contract misleading: callers see a path input but it has zero effect on the output.

💡 Fix

Either remove path from the parameters (since the handler doesn't use it) and rely on the agent to override status to dirty, or rename the tool to classifyWorktreeShape to make it clear it only classifies structural state (bare/detached/clean), not dirtiness.

interfaces: s.record(s.object({
fields: s.array(s.string),
file: s.path,
hasConflict: s.boolean,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/grill-with-docs] The output schema models interfaces as a flat s.record keyed by interface name, but the agent is asked to detect duplicates across files — meaning the same key can appear in multiple files. A flat record by name loses all but one entry for duplicated names. The conflicts array captures them separately, but the interfaces record will silently drop earlier entries for conflicting names.

💡 Fix

Key interfaces by ${file}::${name} or change it to an array so all occurrences are preserved:

interfaces: s.array(s.object({
  name: s.string,
  file: s.path,
  fields: s.array(s.string),
  hasConflict: s.boolean,
})),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant