Summary
| Task |
Description |
Typecheck |
Key finding |
| 1 |
Multi-step PR readiness checker (reused) |
✅ pass |
p.read + p.bash + s.enum verdict + repair() composed cleanly |
| 2 |
Changelog entry generator (reused) |
✅ pass |
defineTool for semver validation + s.record(s.array(s.string)) for changesByCategory worked well |
| 3 |
TODO/FIXME/HACK comment tracker (reused) |
✅ pass |
p.writeOutput used for report; s.enum("TODO","FIXME","HACK") on nested item was clean |
| 4 |
Service health probe checker (new) |
✅ pass |
steering() + repair() combined via array form; p.inputField not needed since p.bash accepts only static strings — description-based workaround was required |
| 5 |
Git-metadata template renderer (new) |
✅ pass |
p.readInput("templatePath") + defineTool for log parsing + p.writeOutput composed smoothly |
Problems encountered
No typecheck failures this run. However, several friction points were noted during authoring:
Task 4 — Dynamic curl per-URL iteration not expressible
The task called for running curl against each URL in input.endpoints. Since p.bash only accepts static strings, there is no native way to fan out a command per input array element. The workaround was to describe the command template in prose and reference input.endpoints by name, relying on the LLM to iterate at runtime. This is functional but imprecise — a developer might naturally reach for a loop.
Sketch:
// Desired (not currently possible):
instructions: p`${p.bashEach("curl -s -o /dev/null -w '%{http_code}' {} --max-time 5", "endpoints")}`
// Actual workaround:
instructions: p`For each endpoint in the input.endpoints list, the curl command format is:
curl -s -o /dev/null -w "%{http_code}" <url> --max-time 5`
Task 5 — p.writeOutput path binding is opaque
p.writeOutput(field, path) requires the path argument to be a static string, but Task 5 had a dynamic outputPath input field. The output renderedPath field then had to be set to a static placeholder. The relationship between the output schema field and the actual written path is not enforced at the type level.
Task 2 — No p.write with dynamic content from agent output
The changelog generator needed to write the generated content to CHANGELOG.md. p.writeOutput writes an output field, but the task wanted to write a rendered markdown string. The workaround was to set written: s.boolean and instruct the LLM to describe what it would write rather than using a proper p.write with a computed body.
Improvement opportunities
Missing prompt helpers (p.*)
p.bashEach(template, inputArrayField): Run a shell command template once per element in a caller-supplied array field, injecting each element as {}. Eliminates the current pattern of describing iteration in prose when the operation is uniform per-element.
p.writeInput(inputField, contentField): Write LLM-generated content to a path supplied via an input field (dynamic output path). Currently p.writeOutput(field, staticPath) requires a hardcoded path, making it unusable when the destination is caller-supplied.
Missing schema helpers (s.*)
s.path as output type for p.writeOutput: There is no enforcement that an output field bound with p.writeOutput should be typed s.path. A lint warning or type constraint would catch mismatches early.
API ergonomics
p.bash static-string restriction: The constraint is documented, but it surfaces naturally during authoring of input-driven tasks. A companion p.inputField or p.bashTemplate that safely interpolates a single scalar input field would cover ~80% of the dynamic-command use cases without breaking the declarative model.
steering() + repair() order sensitivity: The docs don't specify whether order matters in addons: [steering(), repair()]. A note in SKILL.md or a diagnostic if they are provided in an unusual order would reduce guessing.
Documentation gaps
- SKILL.md doesn't include a worked example of
p.readInput vs p.readAllInput in a program that also uses p.writeOutput. A single task-5-style example would clarify the read-input → process → write-output pattern.
- The
p.writeOutput(field, path) entry in the prompt-intents reference could note that path is always static and link to the p.inputField workaround for dynamic destinations.
Tasks run today
- (reused) Task 1: Multi-step PR readiness checker — reads package.json via
p.read, runs tests via p.bash, reads git status, produces s.object with s.enum verdict and s.array of issues, repair() addon
- (reused) Task 2: Changelog entry generator — reads git log via
p.bash, uses defineTool to validate semver bump type, s.record(s.array(s.string)) changesByCategory, repair() addon
- (reused) Task 3: TODO/FIXME/HACK comment tracker —
p.bash grep scan, p.writeOutput for report, nested s.enum on item kind
- (new) Task 4: Service health probe checker —
s.array(s.string) input URLs, p.bash curl per endpoint (static template), steering() + repair() addons, s.enum per-endpoint status
- (new) Task 5: Git-metadata template renderer —
p.readInput("templatePath"), p.bash git log, defineTool for log parsing, p.writeOutput for rendered file, s.object metadata output
Generated by Daily Rig Task Generator · sonnet46 63 AIC · ⌖ 4.59 AIC · ⊞ 5.6K · ◷
Summary
p.read+p.bash+s.enumverdict +repair()composed cleanlydefineToolfor semver validation +s.record(s.array(s.string))for changesByCategory worked wellp.writeOutputused for report;s.enum("TODO","FIXME","HACK")on nested item was cleansteering()+repair()combined via array form;p.inputFieldnot needed since p.bash accepts only static strings — description-based workaround was requiredp.readInput("templatePath")+defineToolfor log parsing +p.writeOutputcomposed smoothlyProblems encountered
No typecheck failures this run. However, several friction points were noted during authoring:
Task 4 — Dynamic curl per-URL iteration not expressible
The task called for running
curlagainst each URL ininput.endpoints. Sincep.bashonly accepts static strings, there is no native way to fan out a command per input array element. The workaround was to describe the command template in prose and referenceinput.endpointsby name, relying on the LLM to iterate at runtime. This is functional but imprecise — a developer might naturally reach for a loop.Sketch:
Task 5 —
p.writeOutputpath binding is opaquep.writeOutput(field, path)requires thepathargument to be a static string, but Task 5 had a dynamicoutputPathinput field. The outputrenderedPathfield then had to be set to a static placeholder. The relationship between the output schema field and the actual written path is not enforced at the type level.Task 2 — No
p.writewith dynamic content from agent outputThe changelog generator needed to write the generated content to
CHANGELOG.md.p.writeOutputwrites an output field, but the task wanted to write a rendered markdown string. The workaround was to setwritten: s.booleanand instruct the LLM to describe what it would write rather than using a properp.writewith a computed body.Improvement opportunities
Missing prompt helpers (
p.*)p.bashEach(template, inputArrayField): Run a shell command template once per element in a caller-supplied array field, injecting each element as{}. Eliminates the current pattern of describing iteration in prose when the operation is uniform per-element.p.writeInput(inputField, contentField): Write LLM-generated content to a path supplied via an input field (dynamic output path). Currentlyp.writeOutput(field, staticPath)requires a hardcoded path, making it unusable when the destination is caller-supplied.Missing schema helpers (
s.*)s.pathas output type forp.writeOutput: There is no enforcement that an output field bound withp.writeOutputshould be typeds.path. A lint warning or type constraint would catch mismatches early.API ergonomics
p.bashstatic-string restriction: The constraint is documented, but it surfaces naturally during authoring of input-driven tasks. A companionp.inputFieldorp.bashTemplatethat safely interpolates a single scalar input field would cover ~80% of the dynamic-command use cases without breaking the declarative model.steering()+repair()order sensitivity: The docs don't specify whether order matters inaddons: [steering(), repair()]. A note in SKILL.md or a diagnostic if they are provided in an unusual order would reduce guessing.Documentation gaps
p.readInputvsp.readAllInputin a program that also usesp.writeOutput. A single task-5-style example would clarify the read-input → process → write-output pattern.p.writeOutput(field, path)entry in the prompt-intents reference could note thatpathis always static and link to thep.inputFieldworkaround for dynamic destinations.Tasks run today
p.read, runs tests viap.bash, reads git status, producess.objectwiths.enumverdict ands.arrayof issues,repair()addonp.bash, usesdefineToolto validate semver bump type,s.record(s.array(s.string))changesByCategory,repair()addonp.bashgrep scan,p.writeOutputfor report, nesteds.enumon item kinds.array(s.string)input URLs,p.bashcurl per endpoint (static template),steering()+repair()addons,s.enumper-endpoint statusp.readInput("templatePath"),p.bashgit log,defineToolfor log parsing,p.writeOutputfor rendered file,s.objectmetadata output