Summary
| Task |
Description |
Typecheck |
Key finding |
| 1 (reused) |
OS env variable scanner |
✅ pass |
Clean use of defineTool with s.enum literal return types; as const casts needed for union narrowing |
| 2 (reused) |
Sequential commit pipeline workflow |
✅ pass |
Good 3-agent sequential workflow with call() chaining; null guard after each call is idiomatic |
| 3 (reused) |
TOML config key extractor |
✅ pass |
s.record(s.record(s.string)) nested correctly; p.readInput correctly wired to input schema |
| 4 (reused) |
CSV column stats reporter |
✅ pass |
s.optional(s.number) used correctly for min/max/mean; handler return types well-typed with union |
| 5 (reused) |
Git worktree analyzer |
✅ pass |
addons: [steering(), repair()] ordering correct; s.enum on both type and status fields |
| 6 (reused) |
TypeScript narrowing pattern detector |
✅ pass |
Async defineTool handler with node:fs/promises works; p.glob for discovery pattern correct |
| 7 (new) |
Git reflog summarizer |
✅ pass |
p.bash with custom --format flag; s.enum with 6 action types; repair addon adds robustness |
| 8 (new) |
TypeScript export reporter with p.writeOutput |
✅ pass |
p.writeOutput used in instructions; s.path output field correctly declared |
| 9 (new) |
Parallel project health workflow |
✅ pass |
Promise.all with call.json steps; inlined p\...`in second call.json;s.int` for healthScore |
| 10 (new) |
Markdown frontmatter extractor |
✅ pass |
steering() + repair() both attached; extractFrontmatter tool returns hasFrontmatter boolean guard |
Problems encountered
No failures this run. All 10 programs typechecked successfully on the first attempt.
Improvement opportunities
Missing or undiscoverable schema helpers (s.*)
s.int vs s.number: The distinction is easy to miss — generated code sometimes reached for s.number for counts. Documenting this in a rule ("use s.int for all integer counts and line numbers") in a visible place would reduce drift.
- Nested
s.record: s.record(s.record(s.string)) for TOML sections works but there's no example of nested records in SKILL.md. A short example of two-level records would help.
Missing or undiscoverable prompt helpers (p.*)
p.writeOutput: Only appears in SKILL.md's table, not in any sample before this run. An example showing p.writeOutput in context (in instructions, and how the output schema maps to it) would make this more discoverable.
p.readInput vs p.readAllInput: Programs that need to read a single file from input reliably reach for p.readInput, but the distinction from p.readAllInput (for an array) is not obvious without reading the references.
Error message quality
No typecheck failures observed. All errors seen in prior runs for similar patterns (e.g., wrong s.* for optional fields) were avoided by using the SKILL.md table.
API ergonomics
defineTool handler return types with as const: When a handler returns a union ("path" | "locale" | ...), TypeScript widens the return to string unless as const is used. This is a recurring pattern in tool handlers returning s.enum values. A note in the defineTool reference about as const return casts would help.
Promise.all vs parallel(): In workflows, Promise.all([call(...), call(...)]) works but SKILL.md also mentions parallel(). Both worked here — clarifying the preferred idiom (or confirming both are valid) would reduce ambiguity.
- Null guards after
call(): Every sequential workflow step requires a if (!result) return null guard. This boilerplate is easy to forget. A lint rule or a helper would reduce noise.
Candidate lint rules
Rule: defineTool-enum-return-needs-as-const
- Invalid:
return "path"; (inside a handler returning a union type)
- Valid:
return "path" as const;
- Why model-confusing: TypeScript widens untagged string literals to
string, causing runtime type mismatches vs declared s.enum output.
- Autofix possible: Yes — add
as const to bare string literal returns in defineTool handlers.
Documentation gaps
p.writeOutput needs at least one sample (now added: 438). The reference file prompt-intents.md should show the typical pattern: declare in instructions, map to an s.path output field.
workflow body null guard pattern should be documented with a note explaining why it's needed (call() returns null on failure).
Tasks run today
- (reused) OS environment variable scanner with defineTool + s.enum categories
- (reused) Sequential workflow subagent pipeline (collect→classify→aggregate)
- (reused) TOML config file key extractor with defineTool + repair
- (reused) CSV column statistics reporter with defineTool + s.optional
- (reused) Git worktree listing analyzer with steering + repair addons
- (reused) TypeScript type narrowing pattern detector with async defineTool
- (new) Git reflog entry summarizer with s.enum action classification
- (new) TypeScript export reporter with p.writeOutput
- (new) Parallel project health workflow with call.json + Promise.all
- (new) Markdown frontmatter multi-field extractor with steering + repair
Generated by Daily Rig Task Generator · sonnet46 127.2 AIC · ⌖ 9.24 AIC · ⊞ 6.8K · ◷
Summary
defineToolwiths.enumliteral return types;as constcasts needed for union narrowingworkflowwithcall()chaining;nullguard after eachcallis idiomatics.record(s.record(s.string))nested correctly;p.readInputcorrectly wired toinputschemas.optional(s.number)used correctly for min/max/mean; handler return types well-typed with unionaddons: [steering(), repair()]ordering correct;s.enumon both type and status fieldsdefineToolhandler withnode:fs/promisesworks;p.globfor discovery pattern correctp.bashwith custom--formatflag;s.enumwith 6 action types; repair addon adds robustnessp.writeOutputused in instructions;s.pathoutput field correctly declaredPromise.allwithcall.jsonsteps; inlinedp\...`in second call.json;s.int` for healthScoresteering()+repair()both attached;extractFrontmattertool returns hasFrontmatter boolean guardProblems encountered
No failures this run. All 10 programs typechecked successfully on the first attempt.
Improvement opportunities
Missing or undiscoverable schema helpers (
s.*)s.intvss.number: The distinction is easy to miss — generated code sometimes reached fors.numberfor counts. Documenting this in a rule ("uses.intfor all integer counts and line numbers") in a visible place would reduce drift.s.record:s.record(s.record(s.string))for TOML sections works but there's no example of nested records in SKILL.md. A short example of two-level records would help.Missing or undiscoverable prompt helpers (
p.*)p.writeOutput: Only appears in SKILL.md's table, not in any sample before this run. An example showingp.writeOutputin context (in instructions, and how the output schema maps to it) would make this more discoverable.p.readInputvsp.readAllInput: Programs that need to read a single file from input reliably reach forp.readInput, but the distinction fromp.readAllInput(for an array) is not obvious without reading the references.Error message quality
No typecheck failures observed. All errors seen in prior runs for similar patterns (e.g., wrong
s.*for optional fields) were avoided by using the SKILL.md table.API ergonomics
defineToolhandler return types withas const: When a handler returns a union ("path" | "locale" | ...), TypeScript widens the return tostringunlessas constis used. This is a recurring pattern in tool handlers returnings.enumvalues. A note in thedefineToolreference aboutas constreturn casts would help.Promise.allvsparallel(): In workflows,Promise.all([call(...), call(...)])works but SKILL.md also mentionsparallel(). Both worked here — clarifying the preferred idiom (or confirming both are valid) would reduce ambiguity.call(): Every sequential workflow step requires aif (!result) return nullguard. This boilerplate is easy to forget. A lint rule or a helper would reduce noise.Candidate lint rules
Rule:
defineTool-enum-return-needs-as-constreturn "path";(inside a handler returning a union type)return "path" as const;string, causing runtime type mismatches vs declareds.enumoutput.as constto bare string literal returns indefineToolhandlers.Documentation gaps
p.writeOutputneeds at least one sample (now added: 438). The reference fileprompt-intents.mdshould show the typical pattern: declare in instructions, map to ans.pathoutput field.workflowbodynullguard pattern should be documented with a note explaining why it's needed (call() returns null on failure).Tasks run today