Skip to content

[rig-tasks] Add 10 rig samples — 2026-08-01 - #327

Merged
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-08-01-67a7aad036393456
Aug 1, 2026
Merged

[rig-tasks] Add 10 rig samples — 2026-08-01#327
pelikhan merged 1 commit into
mainfrom
rig-tasks/2026-08-01-67a7aad036393456

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

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

# File Description Typecheck
1 341-ci-flake-triager-v2.md CI Flake Triager V2 — p.bash test log, p.readOptional workflow, defineTool classify, repair addon pass
2 342-config-drift-reconciler-v2.md Config Drift Reconciler V2 — p.readInput both configs, defineTool diff, p.writeOutput patch pass
3 343-release-note-enricher-v2.md Release Note Enricher V2 — input s.object rawNotes, defineTool lookupTicketMetadata, steering+repair pass
4 344-docs-refactor-coordinator-v2.md Docs Refactor Coordinator V2 — named subagents apiExtractor+proseCleanup, p.read README, p.writeOutput pass
5 345-dockerfile-layer-analyzer-v2.md Dockerfile Layer Analyzer V2 — p.readOptional Dockerfile, defineTool parseLayer, repair addon pass
6 346-git-worktree-status-v2.md Git Worktree Status V2 — p.bash worktree list, defineTool classify, s.optional branch field pass
7 347-gitignore-pattern-tester.md Gitignore Pattern Tester — p.readOptional .gitignore, two p.bash file lists, defineTool classifyPattern pass
8 348-makefile-phony-extractor.md Makefile Phony Extractor — p.readOptional Makefile, defineTool extractPhonyTargets with regex, steering pass
9 349-ts-generic-constraint-extractor.md TS Generic Constraint Extractor — p.bash find, async defineTool with node:fs/promises, s.record output pass
10 350-readme-badge-analyzer.md Readme Badge Analyzer — p.readOptional README.md, defineTool parseBadge, s.enum type classification pass

Typecheck failures

None — all 10 samples passed typecheck on first attempt.

Tasks run

  • (reused) CI flake triager with p.bash, s.enum classification, repair addon
  • (reused) Config drift reconciler with p.readInput, p.writeOutput, nested s.record
  • (reused) Release note enricher with defineTool and steering+repair addons
  • (reused) Docs refactor coordinator with named subagents and p.writeOutput
  • (reused) Dockerfile layer analyzer with p.readOptional and defineTool
  • (reused) Git worktree status reporter with p.bash and s.optional
  • (new) Gitignore pattern tester with p.readOptional and two p.bash file list commands
  • (new) Makefile phony target extractor with p.readOptional and regex defineTool
  • (new) TypeScript generic constraint extractor with async defineTool and node:fs/promises
  • (new) README badge status analyzer with p.readOptional and s.enum classification

Generated by Daily Rig Task Generator · sonnet46 119.7 AIC · ⌖ 9.24 AIC · ⊞ 6.8K ·

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pelikhan
pelikhan marked this pull request as ready for review August 1, 2026 20:07
@pelikhan
pelikhan merged commit 8914d61 into main Aug 1, 2026
1 check passed
@github-actions

github-actions Bot commented Aug 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 /codebase-design — requesting changes on correctness and API misuse issues found in 3 of the 10 samples.

📋 Key Themes

Correctness issues

  • 346: classifyWorktree handler can never return "dirty" — the enum value is declared in the output schema and the agent description promises it, but the tool always falls through to "clean". This makes the sample demonstrably wrong.
  • 342: p.writeOutput("outputPatch", "outputPatch") treats an input field name as a literal file path, so the patch is always written to a file called outputPatch rather than the caller-supplied path.
  • 344: Same p.writeOutput / fixed-path mismatch, and the output schema redundantly echoes back the hard-coded path as if it were a variable.

API confusion

  • 345: The .some((p) => ...) arrow parameter shadows the imported p template tag — confusing for readers learning from this sample.

Design observation

  • 341: p.bash("npm test ...") reruns the test suite on every invocation. A triage agent reading an existing log file would be a better-fit pattern.

Positive highlights

  • ✅ Consistent use of s.enum with as const in handler return values
  • ✅ Good use of repair() addon on agents whose output needs to be well-formed
  • 349 async defineTool with node:fs/promises is a clean pattern worth preserving
  • 347 two-p.bash pattern (ignored + tracked) nicely demonstrates multiple prompt intents

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

handler: (args) => {
const status = args.isBare ? "bare" as const
: args.isDetached ? "detached" as const
: "clean" as const;

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] The classifyWorktree handler never returns "dirty", yet the output schema declares s.enum("clean", "dirty", "bare", "detached") and the file title promises "clean, dirty, bare, or detached". When a worktree is neither bare nor detached the handler always returns "clean", silently misclassifying dirty worktrees.

💡 Suggested fix

Add isDirty: s.boolean to the tool parameters so callers can pass git-status info:

parameters: s.object({
  path: s.string,
  branch: s.optional(s.string),
  isDetached: s.boolean,
  isBare: s.boolean,
  isDirty: s.boolean,  // ← add
}),
handler: (args) => {
  const status = args.isBare ? "bare" as const
    : args.isDetached ? "detached" as const
    : args.isDirty ? "dirty" as const
    : "clean" as const;
  return { status };
},

}),
}),
});

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] p.writeOutput("outputPatch", "outputPatch") passes the literal string "outputPatch" as the file path, but the intent is to write to a caller-supplied path. This means the file will always be written to a file literally named outputPatch in the working directory, ignoring the outputPatch input field.

💡 Suggested fix

Use p.writeInput("outputPatch", ...) to write to the path from the input field, or use a concrete path like "config.patch" if the output path is always fixed:

// option A: caller-supplied output path
${p.writeInput("outputPatch", "patchContent")}

// option B: fixed path
${p.write("config.patch", "...")}

See p.writeInput(pathField, contentField) for the pattern where both path and content come from input fields.


Return the list of extracted APIs, count of changes applied, and the output path.`,
agents: { apiExtractor, proseCleanup },
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.

[/codebase-design] p.writeOutput("outputPath", "refactored.md") writes to the hard-coded path "refactored.md", but then the output schema returns outputPath: s.string as if it is a variable value. The output field will always be the literal string "refactored.md" — the field in output is redundant and misleading.

💡 Note

Either remove outputPath from the output schema (since the path is fixed), or make it a real input field and use p.writeInput("outputPath", ...) so callers can control the destination. Returning a constant value in a structured output field is noise that could confuse consumers of this sample.

(p) => args.args.includes(p)
);
const cacheable = args.instruction !== "RUN" || !isHeavy;
const tip = isHeavy

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] The local variable p in the isHeavy predicate shadows the imported p (prompt template tag) from "rig". While it works at runtime, it is confusing and fragile — readers scanning the sample will see p used as both a string and a prompt helper.

💡 Suggested fix

Rename the predicate parameter to avoid the collision:

const isHeavy = ["npm install", "apt-get", "pip install", "COPY . ."].some(
  (pattern) => args.args.includes(pattern)
);

const ciFlakeTriager = agent({
model: "small",
instructions: p`You are a CI flake triager. Analyze the following test output and workflow config to classify the failure.

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] p.bash("npm test 2>&1 | tail -100") will actively run the test suite when this agent is invoked, not just read a log. For a triage-only agent this is likely undesirable — it triggers side effects and could take a long time. The sample would be more accurate if it reads an existing log file (e.g. p.readOptional("test-output.log") or a path from input).

💡 Alternative
input: s.object({ logFile: s.string }),
instructions: p`...
Test output:
${p.readInput("logFile")}
...`

This makes the agent a pure analyzer rather than a test runner, which is the correct pattern for a triage tool.

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