Skip to content

[rig-tasks] Add 10 rig samples — 2026-08-30 - #513

Merged
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-08-30-1336976e138730fc
Sep 1, 2026
Merged

[rig-tasks] Add 10 rig samples — 2026-08-30#513
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-08-30-1336976e138730fc

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Summary

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

# File Description Type Typecheck
1 491-dotenv-process-drift-detector.md Detect drift between .env.example and process.env usages agent ✅ pass
2 492-vitest-snapshot-count-workflow.md Count Vitest snapshots via parallel two-subagent workflow workflow ✅ pass
3 493-git-stale-branch-reporter.md Report git remote branches by age with enum classification agent ✅ pass
4 494-ts-abstract-class-finder.md Find TypeScript abstract classes with export status agent ✅ pass
5 495-dockerfile-env-inspector.md Parse ENV instructions from Dockerfiles agent ✅ pass
6 496-npm-script-prefix-analyzer.md Classify npm scripts by command prefix with s.record output agent ✅ pass
7 497-ts-default-param-extractor.md Extract TypeScript default parameters with repair addon agent ✅ pass
8 498-git-branch-risk-classifier.md Classify git branches by merge risk with steering+repair agent ✅ pass
9 499-test-file-coverage-pipeline.md 3-stage sequential workflow: discover → classify → report workflow ✅ pass
10 500-json-schema-type-distribution.md Analyze type distribution across JSON schema files agent ✅ pass

Typecheck failures

None — all 10 tasks passed typecheck.

Two issues were caught and fixed during development before writing the sample files:

  1. workflow() meta object missing required description field.
  2. Implicit any in .reduce() inside workflow body when operating on call() results typed as T | null.

Tasks run

  • (reused) dotenv vs process.env drift detector
  • (reused) Vitest snapshot count reporter workflow
  • (reused) Git stale branch age reporter
  • (reused) TypeScript abstract class finder
  • (reused) Dockerfile ENV instruction parser
  • (reused) NPM script command prefix analyzer
  • (new) TypeScript default parameter extractor
  • (new) Git branch risk classifier with steering+repair
  • (new) Test file coverage 3-stage pipeline workflow
  • (new) JSON schema type distribution analyzer

Generated by Daily Rig Task Generator · sonnet46 198.2 AIC · ⌖ 8.45 AIC · ⊞ 6.8K ·

- 491: dotenv-process-drift-detector — p.read + p.bash + defineTool + repair addon + s.record
- 492: vitest-snapshot-count-workflow — workflow() + parallel Promise.all + two subagents
- 493: git-stale-branch-reporter — p.bash + defineTool with s.enum return
- 494: ts-abstract-class-finder — p.glob + p.bash + defineTool + s.boolean
- 495: dockerfile-env-inspector — p.bash find + defineTool + s.array of s.object
- 496: npm-script-prefix-analyzer — p.read + defineTool + s.record(s.object) + s.record(s.int)
- 497: ts-default-param-extractor — p.glob + p.bash + defineTool + repair addon
- 498: git-branch-risk-classifier — p.bash + defineTool + steering() + repair() addons
- 499: test-file-coverage-pipeline — workflow() + 3-stage sequential call() pipeline
- 500: json-schema-type-distribution — p.glob + p.bash + defineTool + s.record

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pelikhan
pelikhan marked this pull request as ready for review September 1, 2026 05:12
@pelikhan
pelikhan merged commit 6d46919 into main Sep 1, 2026
1 check passed
@github-actions

github-actions Bot commented Sep 1, 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 /codebase-design — commenting on correctness and naming issues across the new samples.

📋 Key Themes & Highlights

Key Themes

  • s.string used where s.enum is more accurate (491, 493, 498): Several samples define tools with typed union return values but use s.string in the output schema. This is inconsistent — s.enum would keep schemas honest and teach readers the right helper to reach for.
  • Dropped workflow output (492): snapshotParser's exportCount is never returned by the workflow, making the second agent's primary purpose invisible.
  • Contradictory grep in 497: The bash command greps for arrow functions then immediately filters them out, producing variable assignments rather than default parameters.
  • Shell word-splitting in 495: Nested $(find ...) subshell in grep is fragile on paths with spaces — xargs is the conventional fix.

Positive Highlights

  • ✅ All 10 samples pass typecheck — no regressions
  • ✅ Good mix of patterns: repair(), steering(), parallel and sequential workflows, s.record, s.enum, defineTool
  • ✅ Diverse real-world use cases keep the sample set interesting
  • ✅ Null-coalescing with ?? 0 throughout workflow bodies is consistent and safe

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

return {
totalSnapshotFiles: scanResult?.totalFiles ?? 0,
totalLines: (scanResult?.files ?? []).reduce((sum: number, f: { lineCount: number }) => sum + f.lineCount, 0),
snapshotFiles: parseResult?.snapshotFiles ?? [],

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.

[/codebase-design] exportCount from snapshotParser is silently dropped — the workflow never surfaces it in its return value, so the parser agent runs but its key metric goes unused. As a sample this is misleading: readers may conclude exportCount is an optional output rather than the parser's primary purpose.

💡 Include exportCount in the return value
return {
  totalSnapshotFiles: scanResult?.totalFiles ?? 0,
  totalLines: (scanResult?.files ?? []).reduce((sum: number, f: { lineCount: number }) => sum + f.lineCount, 0),
  snapshotFiles: parseResult?.snapshotFiles ?? [],
  exportCount: parseResult?.exportCount ?? 0,  // add this
};

const tsDefaultParamExtractor = agent({
model: "small",
instructions: p`Find TypeScript files with ${p.glob("src/**/*.ts")}. Search for function parameters with defaults using ${p.bash("grep -rn 'function\\|const.*=>' src/ 2>/dev/null | grep '=' | grep -v '=>' | head -50 || true")}. Use extractDefaultParam for each match. Return the full list of default parameters.`,
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 bash grep filter is ambiguous and will produce many false positives. The pattern grep 'function\|const.*=>' | grep '=' | grep -v '=>' is contradictory — it greps for arrow functions (const.*=>) then excludes =>, meaning it only captures const x = ... declarations, not actual default parameters like fn(x = 1). The sample would return mostly variable assignments rather than function defaults.

💡 More precise grep for default parameters
grep -rn '([^)]*\w\+\s*=\s*[^=][^)]*)' src/ --include='*.ts' 2>/dev/null | head -50 || true

Or target function declarations and arrow function signatures specifically and filter for = inside parameter lists.

const dockerfileEnvInspector = agent({
model: "small",
instructions: p`Find Dockerfiles using ${p.bash("find . -name 'Dockerfile*' -not -path '*/node_modules/*' 2>/dev/null | head -20 || true")}. Extract ENV instructions with ${p.bash("grep -rn '^ENV ' $(find . -name 'Dockerfile*' -not -path '*/node_modules/*' 2>/dev/null | head -10 | tr '\\n' ' ') 2>/dev/null || true")}. Use parseEnvInstruction for each ENV line found. Return all env vars.`,
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 nested shell substitution in the grep command — grep -rn '^ENV ' $(find ...) — is shell-injected via p.bash(). If any Dockerfile path contains spaces or special characters this will silently misbehave or error. Since p.bash() is a declarative placeholder (not in-process execution), showing fragile shell composition in a sample teaches an unsafe pattern.

💡 Safer alternative: use xargs
p.bash("find . -name 'Dockerfile*' -not -path '*/node_modules/*' 2>/dev/null | head -10 | xargs -I{} grep -n '^ENV ' {} 2>/dev/null || true")

Using xargs -I{} avoids the subshell word-splitting problem.

instructions: p`Compare declared env keys in ${p.read(".env.example")} with actual usages from ${p.bash("grep -rn 'process\\.env\\.' src/ 2>/dev/null || true")}. Use classifyEnvKey for each key found. Return the full drift report.`,
output: s.object({
keys: s.record(s.object({ inExample: s.boolean, usedInCode: s.boolean, status: s.string })),
totalKeys: s.int,

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 has a status: s.string field but the classifyEnvKey tool returns a typed union ("declared_and_used" | "declared_not_used" | "used_not_declared"). Using s.string instead of s.enum([...]) loses the type constraint and misses a chance to demonstrate s.enum — a schema helper this sample is well-suited to showcase.

💡 Use s.enum to match the tool return type
keys: s.record(s.object({
  inExample: s.boolean,
  usedInCode: s.boolean,
  status: s.enum(["declared_and_used", "declared_not_used", "used_not_declared"]),
})),

const gitBranchRiskClassifier = agent({
model: "small",
instructions: p`List branches with ${p.bash("git branch --format='%(refname:short) %(ahead-behind:HEAD)' 2>/dev/null | head -20 || true")}. Use classifyBranchRisk for each branch with its ahead/behind numbers. Return the risk classification for every branch.`,
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 output schema uses risk: s.string but classifyBranchRisk returns a typed union "safe" | "caution" | "risky" | "critical". Same pattern as 491 — s.enum would make the sample more faithful to the tool's contract and demonstrate the schema helper.

💡 Use s.enum in the branches array
branches: s.array(s.object({ name: s.string, ahead: s.int, behind: s.int, risk: s.enum(["safe", "caution", "risky", "critical"]) })),

const gitStaleBranchReporter = agent({
model: "small",
instructions: p`Analyze git branches from ${p.bash("git branch -r --sort=-committerdate --format='%(refname:short) %(committerdate:relative)' 2>/dev/null | head -30 || true")}. Use classifyBranchAge for each branch to determine its freshness status. Return the full report.`,
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] Same pattern: status: s.string in the output schema but classifyBranchAge returns a typed union. And similarly for 494's branches array. Consider s.enum(["fresh", "aging", "stale", "ancient"]) to keep output schemas honest about the values they represent — this also teaches readers that s.enum is the right schema helper when a tool returns a discriminated string union.

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