Skip to content

[rig-tasks] Add 10 rig samples — 2026-07-28 - #232

Merged
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-07-28-6c7e4b0c8648e591
Jul 28, 2026
Merged

[rig-tasks] Add 10 rig samples — 2026-07-28#232
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-07-28-6c7e4b0c8648e591

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Summary

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

# File Description Typecheck
1 240-git-commit-annotator.md Git commit annotator with nano subagent per commit pass
2 241-npm-script-dep-mapper.md NPM script dependency mapper with repair addon pass
3 242-markdown-link-checker.md Markdown link checker with async curl tool pass
4 243-package-version-drift.md Package version drift reporter with npm outdated pass
5 244-git-author-stats.md Git author stats aggregator with s.record output pass
6 245-ts-path-alias-validator.md TypeScript path alias validator with existsSync tool pass
7 246-stale-branch-detector.md Stale branch detector using git for-each-ref pass
8 247-license-header-checker.md License header checker with async readFile tool pass
9 248-yaml-config-diff.md YAML config diff with two chained defineTool calls pass
10 249-monorepo-workspace-lister.md Monorepo workspace lister with steering addon pass

Typecheck failures

No typecheck failures — all 10 samples passed.

Tasks run

  • (reused) Git commit annotator with nano subagent (gitcman8)
  • (reused) NPM script dependency mapper (npmscdp9)
  • (reused) Markdown link checker (mdlnkch0)
  • (reused) Package version drift reporter (pkgverd1)
  • (reused) Git author stats aggregator (gitauth2)
  • (reused) TypeScript path alias validator (tscpath3)
  • (new) Stale branch detector — git for-each-ref, sync classifyBranchAge tool, s.enum(fresh/stale/dead)
  • (new) License header checker — input: s.object, async checkLicenseHeader tool, repair() addon
  • (new) YAML config diff — p.readInput for both files, two chained tools
  • (new) Monorepo workspace lister — p.bash find, async extractPackageInfo tool, steering() addon

Generated by Daily Rig Task Generator · sonnet46 87.6 AIC · ⌖ 9.5 AIC · ⊞ 6.7K ·

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

github-actions Bot commented Jul 28, 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 — requesting changes on 3 correctness issues across 4 samples.

📋 Key Findings

Issues

  • Shell injection (242): url interpolated into execAsync shell string — use execFile instead
  • Phantom output field (243): reportWritten claims a file was written but no write tool or p.write intent exists — field will always be hallucinated
  • Enum/handler mismatch (241): output schema includes "other" but handler never produces it (default is "util")
  • Ergonomic input design (248): input fields hold raw YAML content rather than file paths; p.readInput is the idiomatic pattern

Positive Highlights

  • ✅ Diverse, realistic use cases (git, npm, file I/O, HTTP, YAML) well-matched to rig primitives
  • ✅ Consistent use of s.enum, s.record, s.optional throughout
  • repair() and steering() addons used correctly in 247 and 249
  • ✅ All samples passed typecheck

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

const { stdout } = await execAsync(
`curl -s -o /dev/null -w "%{http_code}" --max-time 5 --location "${url}"`,
);
const code = parseInt(stdout.trim(), 10);

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 injection risk: url is interpolated directly into a shell string passed to execAsync. A URL containing shell metacharacters (e.g. $(...), backticks) will execute arbitrary commands.

💡 Suggested fix

Use execFile to pass the URL as a separate argument, bypassing shell interpretation:

import { execFile } from "node:child_process";
const { stdout } = await promisify(execFile)("curl", ["-s","-o","/dev/null","-w","%{http_code}","--max-time","5","--location",url]);

Samples teach patterns — unsafe shell interpolation here will be replicated by readers.

- "major" if major version differs
3. Write a markdown drift report to drift-report.md summarizing the table.
4. Set reportWritten to true after writing.`,
output: 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] The instructions say "Write a markdown drift report to drift-report.md" but the agent has no write tool and no p.write(...) prompt intent. The reportWritten output field will always be a hallucinated true. Either add a p.write intent or remove the file-writing step and the reportWritten field.

💡 Options

Option A — remove the phantom write:

// Remove "3. Write a markdown drift report to drift-report.md" from instructions
// Remove reportWritten from the output schema
output: s.object({
  packages: s.array(...),
}),

Option B — add a write intent:

instructions: p`...
${p.write("drift-report.md", "<the generated markdown table>")}
`,

command: s.string,
dependsOn: s.array(s.string),
category: s.enum("build", "test", "lint", "dev", "deploy", "util", "hook", "other"),
hasPreHook: 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 includes "other" in the category enum, but the parseScriptDeps tool handler never produces that value — it always falls through to "util". Either remove "other" from the schema or add an explicit else branch that returns it.

💡 Fix
// In parseScriptDeps handler, the fallthrough produces "util", never "other".
// Option A: remove "other" from the output enum:
category: s.enum("build", "test", "lint", "dev", "deploy", "util", "hook"),

// Option B: rename the default to "other" in the handler:
let category = "other";

// Agent role: diff top-level keys between two YAML config files and detect breaking changes.
const yamlConfigDiff = agent({
model: "small",
input: s.object({ baseFile: s.string, targetFile: s.string }),

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] input requires the caller to pass raw YAML content as strings (baseFile: s.string), but the agent description says "diff two YAML config files". Callers will expect to pass file paths. The existing p.read intent is the idiomatic way to handle this in rig — use p.readInput("baseFile") where baseFile is a path.

💡 Suggested pattern
input: s.object({ baseFile: s.string, targetFile: s.string }),  // paths, not content
instructions: p`...
Base file: ${p.readInput("baseFile")}
Target file: ${p.readInput("targetFile")}
`,

This also mirrors how sample 247 (licenseHeaderChecker) uses p.readInput. Passing raw multi-KB YAML content as input strings is ergonomically awkward for callers.

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