Summary
| Task |
Description |
Typecheck |
Key finding |
| 1 (reused) |
Dotfile inventory mapper |
✅ pass |
Clean use of sync defineTool handler with as const enum returns; p.bash for discovery works well |
| 2 (reused) |
Regex pattern tester |
✅ pass |
Input schema with nested arrays typechecked cleanly; new RegExp in handler is a good pattern |
| 3 (reused) |
Commit churn classifier |
✅ pass |
s.record(s.object(...)) as root output (no wrapper object) works correctly with steering() addon |
| 4 (reused) |
NPM package size estimator |
✅ pass |
p.bash("npm pack --dry-run") + defineTool classifySize pattern is straightforward |
| 5 (reused) |
TypeScript branch coverage analyzer |
✅ pass |
Subagent delegation with agents: { branchAnalyzer } + p.readInput typechecked correctly |
| 6 (reused) |
Env variable type inferrer |
✅ pass |
p.readOptional with fallback string works cleanly; s.record(s.object) output well-suited |
| 7 (new) |
Git hook installer |
✅ pass |
Async defineTool with node:fs/promises access check; repair() addon used correctly |
| 8 (new) |
TypeScript type guard generator |
✅ pass |
Async defineTool extractInterfaces with RegExpMatchArray type annotation required |
| 9 (new) |
JSON fixture anonymizer |
✅ pass |
s.unknown parameter in defineTool typechecked without issues |
| 10 (new) |
CSV to Markdown table converter |
✅ pass |
s.boolean for includeStats input field works correctly; repair() addon clean |
Problems encountered
No failures this run. All 10 programs passed typecheck on first attempt.
Improvement opportunities
Missing or undiscoverable schema helpers (s.*)
s.url — Used in pool descriptions (e.g., HTTP health checker) but not in any official SKILL.md example. Developers must guess whether this exists or use s.string.
s.int vs s.number documentation — The decision table in SKILL.md is helpful, but there's no example showing s.int used inside a nested s.object inside s.array. New users tend to use s.number everywhere.
Missing or undiscoverable prompt helpers (p.*)
p.writeInput vs p.writeOutput — the distinction between these two write intents is not obvious from SKILL.md alone; developers must read the full prompt-intents reference. An inline example in the decision table would help.
p.readAll / p.readAllInput — not mentioned in the canonical example; only appears in the decision table. Adding a brief usage snippet would reduce confusion.
Error message quality
No typecheck failures this run, so no new error messages to analyze. Prior runs have shown that missing as const on enum return values in defineTool handlers produces a generic type-widening error rather than pointing to the enum schema.
API ergonomics
defineTool handler return type for enums — Handlers returning string union values need as const casts. A lint rule or a helper like s.enumValue("foo") would reduce this friction.
repair() takes no arguments — This is correctly documented, but the pattern addons: repair() (no array brackets) vs addons: [steering(), repair()] is inconsistently shown in examples. All examples should consistently use the array form.
instructions2 is not a valid field — Task 7 draft briefly used an instructions2 key which would silently be ignored. This is hard to discover without a lint rule.
Candidate lint rules
Rule: no-invalid-agent-fields
- Invalid example:
agent({ instructions2: p\...` })`
- Valid example:
agent({ instructions: p\...` })`
- Why confusing: Extra/misspelled keys on the agent config object are silently dropped at runtime; TypeScript does not always catch them due to excess property checking gaps.
- Autofix: possible (rename to
instructions).
Rule: enum-return-needs-as-const
- Invalid example:
handler() { return "stable"; } (widens to string)
- Valid example:
handler() { return "stable" as const; }
- Why confusing: The widened return type causes a type error on the
output schema comparison, not at the return site.
- Autofix: possible (add
as const).
Documentation gaps
- SKILL.md canonical example only shows
s.enum at top-level output; an example with s.enum inside s.record(s.object(...)) would mirror common real usage.
p.readInput vs p.read distinction (static path vs caller-supplied path) is clear in the decision table but has no worked example in the canonical program. Adding one case to the canonical program would reduce lookup trips to the references.
- Subagent
agents: field — the composition reference explains it, but there is no short reminder in SKILL.md about the named-object form (agents: { name } not agents: [name]).
Tasks run today
- (reused) Dotfile inventory mapper using p.bash find for dotfiles, repair addon, outputs s.object with dotfiles record
- (reused) Regex pattern test runner: input s.object with patterns array, defineTool runRegexTest, repair addon
- (reused) Commit churn classifier: p.bash git log, defineTool classifyRisk, steering addon, s.record output
- (reused) NPM package size estimator: p.bash npm pack --dry-run, defineTool classifySize
- (reused) TypeScript branch coverage analyzer: p.readInput, subagent delegation, s.object summary output
- (reused) Env variable type inferrer: p.readOptional .env.example, defineTool inferType with regex
- (new) Git hook installer: async defineTool checkHooksDir, repair addon, s.object with writtenHooks/skippedHooks
- (new) TypeScript type guard generator: async defineTool extractInterfaces, p.readInput, p.write output
- (new) JSON fixture anonymizer: defineTool anonymizeValue with s.unknown param, p.readInput + p.write
- (new) CSV to Markdown table converter: defineTool parseCSVRow, p.readInput + p.write, s.boolean input field
Generated by Daily Rig Task Generator · sonnet46 104.3 AIC · ⌖ 9.35 AIC · ⊞ 6.7K · ◷
Summary
defineToolhandler withas constenum returns;p.bashfor discovery works wellnew RegExpin handler is a good patterns.record(s.object(...))as root output (no wrapper object) works correctly withsteering()addonp.bash("npm pack --dry-run")+defineTool classifySizepattern is straightforwardagents: { branchAnalyzer }+p.readInputtypechecked correctlyp.readOptionalwith fallback string works cleanly;s.record(s.object)output well-suiteddefineToolwithnode:fs/promisesaccess check;repair()addon used correctlydefineTool extractInterfaceswithRegExpMatchArraytype annotation requireds.unknownparameter indefineTooltypechecked without issuess.booleanforincludeStatsinput field works correctly;repair()addon cleanProblems encountered
No failures this run. All 10 programs passed typecheck on first attempt.
Improvement opportunities
Missing or undiscoverable schema helpers (
s.*)s.url— Used in pool descriptions (e.g., HTTP health checker) but not in any official SKILL.md example. Developers must guess whether this exists or uses.string.s.intvss.numberdocumentation — The decision table in SKILL.md is helpful, but there's no example showings.intused inside a nesteds.objectinsides.array. New users tend to uses.numbereverywhere.Missing or undiscoverable prompt helpers (
p.*)p.writeInputvsp.writeOutput— the distinction between these two write intents is not obvious from SKILL.md alone; developers must read the full prompt-intents reference. An inline example in the decision table would help.p.readAll/p.readAllInput— not mentioned in the canonical example; only appears in the decision table. Adding a brief usage snippet would reduce confusion.Error message quality
No typecheck failures this run, so no new error messages to analyze. Prior runs have shown that missing
as conston enum return values indefineToolhandlers produces a generic type-widening error rather than pointing to the enum schema.API ergonomics
defineToolhandler return type for enums — Handlers returning string union values needas constcasts. A lint rule or a helper likes.enumValue("foo")would reduce this friction.repair()takes no arguments — This is correctly documented, but the patternaddons: repair()(no array brackets) vsaddons: [steering(), repair()]is inconsistently shown in examples. All examples should consistently use the array form.instructions2is not a valid field — Task 7 draft briefly used aninstructions2key which would silently be ignored. This is hard to discover without a lint rule.Candidate lint rules
Rule:
no-invalid-agent-fieldsagent({ instructions2: p\...` })`agent({ instructions: p\...` })`instructions).Rule:
enum-return-needs-as-consthandler() { return "stable"; }(widens tostring)handler() { return "stable" as const; }outputschema comparison, not at thereturnsite.as const).Documentation gaps
s.enumat top-level output; an example withs.enuminsides.record(s.object(...))would mirror common real usage.p.readInputvsp.readdistinction (static path vs caller-supplied path) is clear in the decision table but has no worked example in the canonical program. Adding one case to the canonical program would reduce lookup trips to the references.agents:field — the composition reference explains it, but there is no short reminder in SKILL.md about the named-object form (agents: { name }notagents: [name]).Tasks run today