feat: AR-39b — scope-decompose-sonnet@2 + bug-verify-sonnet@2 (WV-36 file-write plan, WF-COMP-25a self-transition) (31553852-e6c7-40e3-8020-b3b65094c1cc)
This commit is contained in:
105
task-templates/workflow/bug-verify-sonnet@2.yaml
Normal file
105
task-templates/workflow/bug-verify-sonnet@2.yaml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
name: bug-verify-sonnet
|
||||||
|
version: 2
|
||||||
|
description: Read-only verification of an ai-resolve-tagged bug using Sonnet planning (CP-side apply-verified self-transition; WF-COMP-25)
|
||||||
|
runtime: planning-sonnet-repo
|
||||||
|
input:
|
||||||
|
state: verify-pending
|
||||||
|
tags_required: [ai-resolve]
|
||||||
|
tags_forbidden: []
|
||||||
|
required_artifacts: []
|
||||||
|
output:
|
||||||
|
# WF-COMP-25 / WF-COMP-33 — the CP resolves this pipe-separated string as
|
||||||
|
# the closed verdict set; the literal value is NEVER PATCHed. The agent's
|
||||||
|
# packed `verdict` value (see `outputs: [verdict]` on node `agent`) is
|
||||||
|
# what gets PATCHed onto the run's item `flow_state`.
|
||||||
|
state: 'verified|rejected'
|
||||||
|
scope_budget:
|
||||||
|
files_modified_max: 1
|
||||||
|
lines_diff_max: 400
|
||||||
|
wall_clock_seconds_max: 1800
|
||||||
|
nodes:
|
||||||
|
# WF-COMP-25 / WF-COMP-25a — the agent's only side effect is its
|
||||||
|
# declared output `verdict` (one of the two closed values); the CP
|
||||||
|
# applies the flow_state change. The agent does NOT call the CP and
|
||||||
|
# does NOT read any internal-service CP credential file.
|
||||||
|
- id: agent
|
||||||
|
kind: agent
|
||||||
|
outputs: [verdict]
|
||||||
|
template: planning-sonnet-repo
|
||||||
|
model: sonnet
|
||||||
|
runtime_env:
|
||||||
|
AGENT_REPO_URL: "git@gitea.oreillyit.nz-ai-enablement:skynet/agent-runtimes-agents.git"
|
||||||
|
AGENT_BRANCH: "bug-verify/${item.uuid}"
|
||||||
|
CP_URL: "http://controlplane.agent-runtimes.svc.cluster.local:8100"
|
||||||
|
prompt: |
|
||||||
|
The agent-runtimes project repo is cloned at /workspace/project.
|
||||||
|
Change to that directory before doing any work.
|
||||||
|
|
||||||
|
Verify the following bug report. This is a READ-ONLY investigation —
|
||||||
|
do NOT modify any source code. Your only file changes are the
|
||||||
|
verification artifact described below.
|
||||||
|
|
||||||
|
**Title**: ${item.title}
|
||||||
|
|
||||||
|
**Bug report**:
|
||||||
|
${item.body}
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
1. cd /workspace/project
|
||||||
|
2. Investigate the codebase to determine whether the reported bug
|
||||||
|
is real, reproducible, and correctly diagnosed. Do not make
|
||||||
|
code changes — this is verification, not a fix.
|
||||||
|
3. Write your findings to
|
||||||
|
spec/bugs/<slug>-verification.md (derive <slug> from this
|
||||||
|
item's own slug) with exactly these sections, in order:
|
||||||
|
- `## Reproduction` — concrete steps or evidence confirming
|
||||||
|
(or failing to confirm) the reported symptom
|
||||||
|
- `## Root-Cause Hypothesis` — the mechanism you believe
|
||||||
|
causes it, with file/line references
|
||||||
|
- `## Verdict` — exactly one of `verified` or `rejected`
|
||||||
|
- `## Rationale` — why you reached that verdict
|
||||||
|
4. Commit and push the verification artifact on this branch.
|
||||||
|
|
||||||
|
DELIVERING THE VERDICT — read carefully.
|
||||||
|
|
||||||
|
This node's declared output is the literal key `verdict`. The CP
|
||||||
|
reads your packed `verdict` value and PATCHes this work item's own
|
||||||
|
`flow_state` with it (`spec/typed-workflows.md` WF-COMP-25 / 25a,
|
||||||
|
`spec/workflow-variables.md` WV-36). You do NOT call the CP, you
|
||||||
|
do NOT run `cp-cli planner items update`, and you do NOT read any
|
||||||
|
internal-service CP credential file (the path that the legacy
|
||||||
|
`@1` flow used for its CP write is no longer mounted into your
|
||||||
|
container). The CP applies your verdict when `finalize_run` runs.
|
||||||
|
|
||||||
|
The closed verdict vocabulary is exactly two strings:
|
||||||
|
verified
|
||||||
|
rejected
|
||||||
|
|
||||||
|
Any other value — including an empty string, `VERIFIED`, `verified `,
|
||||||
|
`Verified`, `verify`, or a sentence — is rejected by WF-COMP-25a as
|
||||||
|
`self_transition_verdict_outside_set` and the run surfaces to a
|
||||||
|
human via `request_decision`. Do not invent a third outcome.
|
||||||
|
|
||||||
|
Write the verdict to your step folder with a quoted heredoc whose
|
||||||
|
terminator cannot occur in the body — example for verdict
|
||||||
|
`verified`:
|
||||||
|
|
||||||
|
cat > /variables/agent/verdict <<'__VERDICT_END__'
|
||||||
|
verified
|
||||||
|
__VERDICT_END__
|
||||||
|
|
||||||
|
The file MUST be strict UTF-8 with LF line endings; no trailing
|
||||||
|
whitespace; no header line; no body. A file that is not exactly the
|
||||||
|
one-line verdict (with optional final LF) is rejected as
|
||||||
|
`self_transition_verdict_outside_set` and surfaces to a human.
|
||||||
|
|
||||||
|
Do NOT use `wfvar set verdict <body>` — it passes the body as argv
|
||||||
|
and breaks on shell quoting.
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
1. Investigate.
|
||||||
|
2. Decide `verified` or `rejected`. Record it in
|
||||||
|
`## Verdict` of the verification artifact AND in
|
||||||
|
`/variables/agent/verdict` — the two MUST agree.
|
||||||
|
3. Commit and push the verification artifact.
|
||||||
|
4. Call task_complete. Do NOT PATCH the CP yourself.
|
||||||
141
task-templates/workflow/scope-decompose-sonnet@2.yaml
Normal file
141
task-templates/workflow/scope-decompose-sonnet@2.yaml
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
name: scope-decompose-sonnet
|
||||||
|
version: 2
|
||||||
|
description: Scope and decompose a spec into tagged tasks using Sonnet planning (CP-side apply-verified; WF-COMP-33 / WIA-47)
|
||||||
|
runtime: spec-writing-sonnet-repo
|
||||||
|
input:
|
||||||
|
state: spec-reviewed-arch
|
||||||
|
tags_forbidden: []
|
||||||
|
required_artifacts: []
|
||||||
|
output:
|
||||||
|
state: scoped-tagged
|
||||||
|
scope_budget:
|
||||||
|
files_modified_max: 10
|
||||||
|
lines_diff_max: 500
|
||||||
|
wall_clock_seconds_max: 2400
|
||||||
|
nodes:
|
||||||
|
# WF-COMP-33 / WIA-47 / WV-36..37 — the agent's only side effect is the
|
||||||
|
# declared output `plan_manifest` plus the per-child item files under
|
||||||
|
# `items/<local_id>`; `finalize_run` reads, validates and applies them.
|
||||||
|
# The agent does NOT call the CP and does NOT read any internal-service
|
||||||
|
# CP credential file.
|
||||||
|
- id: agent
|
||||||
|
kind: agent
|
||||||
|
outputs: [plan_manifest]
|
||||||
|
template: spec-writing-sonnet-repo
|
||||||
|
model: sonnet
|
||||||
|
runtime_env:
|
||||||
|
AGENT_REPO_URL: "git@gitea.oreillyit.nz-ai-enablement:skynet/agent-runtimes-agents.git"
|
||||||
|
AGENT_BRANCH: "spec/${item.uuid}"
|
||||||
|
CP_URL: "http://controlplane.agent-runtimes.svc.cluster.local:8100"
|
||||||
|
# The deliverable is a directory of plan files on disk — NOT a git diff.
|
||||||
|
AGENT_EMPTY_DELIVERABLE_CHECK: "false"
|
||||||
|
prompt: |
|
||||||
|
The agent-runtimes project repo is cloned at /workspace/project.
|
||||||
|
Change to that directory before doing any work.
|
||||||
|
|
||||||
|
Find the spec file in /workspace/project/spec/ (the spec was
|
||||||
|
written in an earlier pipeline stage — look for a file whose name matches
|
||||||
|
the concept title '${item.title}' as a slug, e.g. spec/<slug>.md).
|
||||||
|
Read that spec carefully.
|
||||||
|
|
||||||
|
YOUR ONLY DELIVERABLE FOR THIS STAGE IS THE DECOMPOSE PLAN. You do
|
||||||
|
NOT call the CP, you do NOT run `cp-cli planner items decompose`,
|
||||||
|
and you do NOT read any internal-service CP credential file (the
|
||||||
|
path that the legacy `@1` flow used for its CP write is no longer
|
||||||
|
mounted into your container). The CP applies your plan from disk
|
||||||
|
at finalize time (spec/work-items-api.md WIA-47..47g). This node's
|
||||||
|
declared output is the literal key `plan_manifest`; the CP packs
|
||||||
|
the manifest plus every per-child item file in the same step folder.
|
||||||
|
|
||||||
|
On-disk layout (every path is relative to your step folder):
|
||||||
|
/variables/agent/plan_manifest # the manifest (plain text)
|
||||||
|
/variables/agent/items/<local_id> # one item file per child
|
||||||
|
|
||||||
|
`<local_id>` matches `^[a-z0-9][a-z0-9-]{0,31}$` — lowercase letters,
|
||||||
|
digits, and hyphen; 1–32 characters; no underscore. Use the literal
|
||||||
|
`$root` as the parent header on every item; the CP substitutes the
|
||||||
|
real item UUID server-side (WV-36 / WIA-47e).
|
||||||
|
|
||||||
|
Write each item file with a quoted heredoc whose terminator cannot
|
||||||
|
occur in the body — example for a child `c1`:
|
||||||
|
|
||||||
|
cat > /variables/agent/items/c1 <<'__DECOMPOSE_ITEM_END__'
|
||||||
|
parent: $root
|
||||||
|
title: Implement payment service FP-1..3
|
||||||
|
spec_ids: FP-1,FP-2,FP-3
|
||||||
|
test_files: tests/payments/test_fp.py
|
||||||
|
tags: airouter-eligible
|
||||||
|
---
|
||||||
|
Write the payment service implementation covering FP-1, FP-2, FP-3.
|
||||||
|
|
||||||
|
Acceptance criteria:
|
||||||
|
- FP-1: idempotent payment capture
|
||||||
|
- FP-2: refund flow
|
||||||
|
__DECOMPOSE_ITEM_END__
|
||||||
|
|
||||||
|
Do NOT use `wfvar set <key> <body>` for plan files — it passes the
|
||||||
|
body as argv and breaks on backticks, quotes and `$(...)` and
|
||||||
|
truncates at ARG_MAX. The file-write / heredoc path is byte-faithful.
|
||||||
|
|
||||||
|
Manifest format — first line exactly `decompose/v1`, then one
|
||||||
|
`local_id` per line, no blank lines, no header, no body. Example for
|
||||||
|
the three-item plan above:
|
||||||
|
|
||||||
|
decompose/v1
|
||||||
|
c1
|
||||||
|
c2
|
||||||
|
c3
|
||||||
|
|
||||||
|
Item header grammar (every line is `key: value`):
|
||||||
|
- closed header set: {parent, title, spec_ids, test_files, tags}
|
||||||
|
- `parent` and `title` are REQUIRED on every item
|
||||||
|
- `parent` MUST be the literal `$root` (a work-item UUID is rejected
|
||||||
|
as `parent_must_be_root` — privilege-escalation guard)
|
||||||
|
- `title` is 1–200 bytes UTF-8, unique within one plan compared
|
||||||
|
case- and whitespace-insensitively
|
||||||
|
- `spec_ids` and `test_files` are comma-separated, at most 50
|
||||||
|
entries each; `spec_ids` entries match `^[A-Z][A-Z0-9-]{0,31}$`
|
||||||
|
(e.g. `FP-1`, `WV-36`)
|
||||||
|
- `test_files` entries have no leading `/`, no `..` segment, no SP
|
||||||
|
or `,`, at most 250 bytes each (e.g.
|
||||||
|
`tests/payments/test_fp.py`)
|
||||||
|
- `tags` is optional; every tag MUST be exactly `airouter-eligible`
|
||||||
|
(the only tag in DECOMPOSE_AGENT_TAG_ALLOWLIST — anything else
|
||||||
|
is `tag_not_allowed`). Omit the `tags:` line for tasks Qwen3.6
|
||||||
|
cannot handle alone.
|
||||||
|
- `---` ends the header block; every byte after it to EOF is the
|
||||||
|
body, verbatim (printable ASCII + UTF-8 bytes 0x80–0xFF, plus
|
||||||
|
LF and TAB as the only permitted control bytes; CR is rejected).
|
||||||
|
The body must be ≤ 16,384 bytes UTF-8.
|
||||||
|
- one header per item, no duplicates (`duplicate_header`)
|
||||||
|
- unknown keys are rejected (`unknown_header`)
|
||||||
|
- the file MUST be strict UTF-8, LF line endings (CRLF is rejected)
|
||||||
|
|
||||||
|
Plan fan-out: 1–20 `local_id` lines in the manifest, exactly one
|
||||||
|
`items/<local_id>` file per manifest line (an orphan file or a
|
||||||
|
missing file fails the apply as `orphan_item_file` /
|
||||||
|
`manifest_entry_without_file`).
|
||||||
|
|
||||||
|
Title / slug uniqueness: every planned title must be unique within
|
||||||
|
the plan (`duplicate_title`); every planned slug
|
||||||
|
(`decompose_validation.slugify(title)`, lowercase, non-alphanum
|
||||||
|
runs collapsed to `-`, truncated to 80 chars) must also be unique
|
||||||
|
(`duplicate_slug`). Two titles that differ only in case / whitespace
|
||||||
|
are NOT distinct.
|
||||||
|
|
||||||
|
"airouter-eligible" is the only tag you may use. Do NOT emit
|
||||||
|
`auto-dispatch`, `integrated`, `ai-resolve` or `airouter-skip` —
|
||||||
|
the validator rejects those at apply time.
|
||||||
|
|
||||||
|
Workflow:
|
||||||
|
1. Read the spec carefully.
|
||||||
|
2. Decide the children (1–20). Draft a title, a one-paragraph
|
||||||
|
body, and the `spec_ids` / `test_files` for each.
|
||||||
|
3. Write `/variables/agent/plan_manifest` with a heredoc
|
||||||
|
(the heredoc terminator MUST be unique to that file — do not
|
||||||
|
reuse `__DECOMPOSE_ITEM_END__` across files).
|
||||||
|
4. Write each `/variables/agent/items/<local_id>` with a heredoc.
|
||||||
|
5. Confirm the manifest names exactly the files you wrote, and
|
||||||
|
that no extra `items/*` files exist (an orphan file fails the
|
||||||
|
apply).
|
||||||
|
6. Call task_complete. Do NOT PATCH the CP yourself.
|
||||||
Reference in New Issue
Block a user