From 30c3a75c2035a1219dd9cd771430b7bf087f146b Mon Sep 17 00:00:00 2001 From: Paul O'Reilly Date: Thu, 10 Sep 2026 09:35:29 +1200 Subject: [PATCH] feat(workflow): bug-ancestor-auto-advance@1 demo template (M43 Task 2) --- .../workflow/bug-ancestor-auto-advance@1.yaml | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 task-templates/workflow/bug-ancestor-auto-advance@1.yaml diff --git a/task-templates/workflow/bug-ancestor-auto-advance@1.yaml b/task-templates/workflow/bug-ancestor-auto-advance@1.yaml new file mode 100644 index 0000000..4083328 --- /dev/null +++ b/task-templates/workflow/bug-ancestor-auto-advance@1.yaml @@ -0,0 +1,71 @@ +name: bug-ancestor-auto-advance +version: 1 +description: >- + M43 demo — script-only auto-advance for a bug whose parent milestone carries + the opt-in tag. Functionally what R1 (bug-ai-resolve-seed) does today, minus + the per-bug tagging step: the trigger rule matches on the PARENT's tag + (match.ancestor, spec/workflow-triggers.md §3c), this workflow re-checks the + link in-band, tags the bug `ai-resolve` (so the existing R2 verify rule picks + it up), then transitions it to verify-pending. Zero LLM nodes. +runtime: script +input: + # A freshly-created bug has no flow_state yet, so eligibility sees its + # lifecycle state (ItemView.workflow_state = flow_state or state). Accept + # both lifecycle spellings seen across backends. + state: pending + tags_required: [] + tags_forbidden: [blocked, paused, ai-resolve] + required_artifacts: [] +escalation_input_states: [pending, open] +output: + state: verify-pending +scope_budget: + # Schema minimum is 1; no node here touches a repo, so these are nominal. + files_modified_max: 1 + lines_diff_max: 1 + wall_clock_seconds_max: 300 +nodes: + # Gate: re-verify in-band that the parent milestone still carries the + # opt-in tag (the trigger's ancestor read may be up to 60s stale on the + # consumer path, WT-ANC-5). Fails closed — refuse_dispatch on a miss. + - id: parent-link-check + kind: script + cmd: scripts/workflow/parent-link-check + on_fail: refuse_dispatch + runtime_env: + CP_URL: "http://controlplane.agent-runtimes.svc.cluster.local:8100" + WORKFLOW_ITEM_UUID: "${item.uuid}" + PARENT_LINK_TAG: auto-resolve-bugs + PARENT_LINK_RELATION: parent + # Opt the bug into the existing verify pipeline (R2 bug-ai-resolve-verify + # requires tags_required: [ai-resolve]). + - id: tag-ai-resolve + kind: script + cmd: scripts/workflow/tag-set + depends_on: [parent-link-check] + on_fail: escalate + runtime_env: + CP_URL: "http://controlplane.agent-runtimes.svc.cluster.local:8100" + WORKFLOW_ITEM_UUID: "${item.uuid}" + TAG_SET_ADD: ai-resolve + # Advance the bug; R2 then dispatches bug-verify-sonnet@1 at verify-pending. + - id: state-tx + kind: script + cmd: scripts/workflow/state-tx + depends_on: [tag-ai-resolve] + on_fail: escalate + runtime_env: + CP_URL: "http://controlplane.agent-runtimes.svc.cluster.local:8100" + STATE_TX_NEW_STATE: verify-pending +# NOTE (script-node credentials, M43): kind: script nodes are harness-exempt +# (WF-COMP-6) but now carry the AU-51 internal-service bearer token by +# default — see spec/typed-workflows.md WF-COMP-26. The compiler emits +# `secrets_required: [CP_SERVICE_TOKEN]` and +# `runtime_env.CP_SERVICE_TOKEN_FILE=/run/secrets/CP_SERVICE_TOKEN` on +# every script node; the dispatcher's `_run_script_task` legacy-key +# branch mounts the dispatcher-process-env CP_SERVICE_TOKEN value as a +# file. All three nodes above read it via +# `open(os.environ["CP_SERVICE_TOKEN_FILE"]).read().strip()`. Each script +# still resolves its own actor identity (OIDC_IDENTITY_EMAIL or +# CP_Caller-Identity header — see scripts/workflow/tag-set and +# parent-link-check) for the write envelope.