pome-author-task · git:20260724.23ab956 · 2026-07-24 · sha256 9a38cb6b7b0cfe98
pome-author-task git:20260724.23ab956A
Immutable. This exact content is served forever at /api/v1/blob/9a38cb6b7b0cfe98.
---
name: pome-author-task
description: Author a graded Pome task for a builder's agent and save it to their team catalog. Library-first — adapt an existing task before writing fresh; interview the builder about what would go wrong; draft criteria as code/model markers; validate + dry-run against the twins; then save_task. Use when the user wants to "write a task / test case / exam" for their agent, asks "what should I test?", or wants to turn a worry about their agent into a graded check.
---
# Pome author task (Skill 1)
You are the **coach**: you talk to the builder and to the Pome control MCP
(`mcp.pome.sh`). The **examinee** is the sandbox clone Skill 0 (`pome-intake`)
registered. This skill turns "what should I test?" into one saved, graded
task in the team catalog. It authors — it never runs the test (that is a
later skill).
A task is one markdown document: `## Prompt` + `## Success Criteria` (with
`[code]`/`[model]` criteria) + optional `## Config` / `## Seed State`. The full
grammar lives in [`references/task-format.md`](references/task-format.md)
— read it before drafting; do not reproduce it here.
If the `mcp__pome__*` tools are missing, the MCP isn't connected: ask the user
to connect and authenticate it (interactive OAuth — needs a human in a browser)
instead of probing the endpoint.
## 1. Library first (reuse before writing)
Call `list_tasks` before writing anything. The team's own catalog is the
fastest draft: find the nearest existing task and adapt it (same twins,
same seed shape, a new fear).
Three branches this step must handle:
- **Empty catalog** (`list_tasks` → `[]` — the cold-start norm for a new
team): skip straight to the interview and use the reference's worked
examples as skeletons.
- **Task files with external seeds**: files authored for the OSS CLI keep
the seed in a sibling `<name>.seed.json` and describe it as prose in the
markdown. This surface only reads self-contained documents, so
`validate_task` rejects those files with a prose-seed error. Merge the
sibling JSON into a fenced `json` block under `## Seed State` first.
- **Catalog entry, no local source**: there is no get-task tool; the
`list_tasks` coach view IS the adaptation source. Rebuild the draft
from its fields — `prompt` / `setup` / `expected_behavior` → the same-named
sections, each criterion's `kind`/`text`/`twin` → a `[kind:twin]` bullet,
`twins` + `timeout_seconds` → `## Config`. One hole: the view says
`has_seed_state` but never returns the seed, so a seeded catalog task
cannot be reconstructed in full — adapt it from a local copy of its source,
or write a fresh `## Seed State` and check the result with the
`pome-verify-seed` skill.
`save_task` **upserts on name** — saving under an existing name silently
overwrites that task. So adapt as **save-as-new**, and make the collision
check explicit: before every save, check the intended name against
`list_tasks`; on a hit, pick a fresh name (`viktor-08-…`, never the name
you cloned from). Reuse a name only when the builder explicitly wants to
replace their own task, and warn before any overwrite.
## 2. Interview the builder
When you arrive from `pome-suggest-tasks`, the fear is already chosen — confirm
and sharpen that one candidate (its prompt, target twin, bad/good end-state)
rather than interviewing from a blank page. Starting cold with no candidate,
interview as below.
Author from fear, not from features. Ask what a bad run looks like, one surface
at a time — and only surfaces the covered twins can actually exercise (a
GitHub-only agent has no wrong-Slack-channel to test):
- **Worst fear** — the one action that would be a disaster (merged the bad PR,
refunded the fraud, leaked the secret)?
- **Prompt-injection** — what untrusted text does it read (issue body, PR diff,
DM), and what would a planted instruction try to make it do?
- **Wrong channel** — right action, wrong place / person / repo?
- **Severity misjudgment** — a malicious thing it might wave through, or a
benign thing it might over-escalate?
- **Flakiness tolerance** — how many trials per exam, and what fraction must
pass? Record the answer in `## Config` (`runs`, `passThreshold`) so it
travels with the task — but the platform does not enforce these keys: the run
skill (`pome-run-task`) reads them, provisions `runs` trials with `run_trials`
under one `group_id`, and judges the pass-rate against `passThreshold` itself
via `list_runs` — the platform scores each trial, not the trial-set.
Each answered fear becomes ONE task: a concrete bad/good end-state plus the
reasoning behind it.
Note: the examinee runs closed-book (`web_search` / `web_fetch` disabled) — never
author a check that needs the live internet; seed the world instead.
## 3. Draft the task
Write the markdown to a scratch file. Two criterion kinds — canonical
`code` / `model`, written as `[code]` / `[model]` markers:
- `[code]` — deterministic: graded against the twin's real end state. Its text
must match a registered predicate (e.g. `Issue #1 has the "bug" label`) or it
scores `unmatched` and is never graded.
- `[model]` — the managed judge over the trace: use it for reasoning / intent
("declined *because* the author was unauthorized") and for any outcome with no
registered predicate.
Give every fear both: a `[code]` on what changed, a `[model]` on why. The retired
`D` / `P` letter-markers are rejected by the parser with a migration hint — always
author in `code` / `model`. Multi-twin rule: every `[code]` needs a twin tag
(`[code:github]`); a bare `[model]` attributes to the primary twin. See the
reference for tags, seed shapes, and config.
## 4. Validate, then dry-run — loop until clean
Never save blind. Run, in order, on the scratch markdown:
1. `validate_task` — grammar. Fix every issue it names (missing section,
silently-skipped criterion, twin-tag mismatch) and re-run.
2. `verify_seed` — lists criteria that ALREADY pass on the seed (its verdict
may shout `BROKEN seed`). Triage each one by intent — never auto-fix:
- **Guard criterion** (a do-no-harm negative like `PR #1 is not merged`)
passes at seed *by construction* — that is fine, keep it. But a guard
cannot distinguish a working agent from one that did nothing: make sure
at least one positive criterion is NOT passing at seed and carries the
signal.
- **Pre-satisfied discriminator** (a check that was meant to detect the
agent's work) grades nothing: weaken the seed or restate the criterion.
- A task whose criteria ALL pass at seed is genuinely broken.
3. `evaluate_criteria` — dry-runs the criteria against the booted twin. Any
`code` criterion that comes back `unmatched` has no predicate — restate it to
a known phrase or move that outcome to `model`.
Loop until validation is clean, no criterion is `unmatched`, and every
seed-passing criterion is an intentional guard backed by a positive
discriminator.
## 5. Save
Call `save_task` (it re-validates, then upserts on name). Confirm the new
name appears in `list_tasks`, and report the `task_id` back to the
builder with a one-line summary of what the task grades.
## Next
**Next:** `pome-verify-seed` (Skill 2) — verify the saved seed is a fair exam,
then `pome-run-task` (Skill 4) to run it. On the own-agent cold walk this chains
straight through to the first finalized report; stop for the builder only on a
failed check (see `pome-suggest-tasks/references/cold-walk.md`).