@plainconceptsplatform/workflows 0.28.1 → 0.28.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1657,6 +1657,10 @@ echo "── Visual verify wiring ───────────────
1657
1657
  # The merge-gate's conclude job dispatches agent-visual-verify before merging when the outcome
1658
1658
  # is auto-merge and VISUAL_VERIFY_ENABLED is true. Each of these is one line an edit could drop
1659
1659
  # with nothing going red: a missing dispatch step, a missing env var, or a missing worker file.
1660
+ # The guard against the original bug comes first: the call is a dispatch, never a step doing
1661
+ # `uses:` on a workflow file -- that resolves as a local action, dies with "Can't find
1662
+ # action.yml", and under continue-on-error every auto-merge shipped with zero screenshots
1663
+ # and nothing red.
1660
1664
  if worker_installed merge-gate; then
1661
1665
  VV_OK=1
1662
1666
 
@@ -1665,14 +1669,27 @@ if worker_installed merge-gate; then
1665
1669
  }
1666
1670
 
1667
1671
  # The dispatch step exists and runs only on auto-merge with the feature flag on.
1668
- vv 'name: Run visual verification' "$MERGE_GATE_WORKER_MD" 'merge-gate has no visual-verify dispatch step'
1672
+ vv 'name: Dispatch visual verification' "$MERGE_GATE_WORKER_MD" 'merge-gate has no visual-verify dispatch step'
1669
1673
  vv "outcome == 'auto-merge'.*VISUAL_VERIFY_ENABLED == 'true'" "$MERGE_GATE_WORKER_MD" 'visual-verify dispatch has wrong guard'
1670
- vv 'continue-on-error: true' "$MERGE_GATE_WORKER_MD" 'visual-verify dispatch must not block the merge'
1674
+
1675
+ # The shape that never worked: a step calling a reusable workflow file. Also reject the
1676
+ # swallowed-failure form it shipped with.
1677
+ vv 'operation=visual-verify' "$MERGE_GATE_WORKER_MD" 'the dispatch must target the router operation, not a nested file'
1678
+ if grep -qE '^ - name:.*\n.*uses: \./\.github/workflows/agent-visual-verify' "$MERGE_GATE_WORKER_MD" 2>/dev/null \
1679
+ || grep -A2 '^ - name:' "$MERGE_GATE_WORKER_MD" | grep -q 'uses: \./\.github/workflows/'; then
1680
+ VV_OK=0
1681
+ echo "FAIL: a step still uses: a workflow file; the runner resolves it as a local action and it cannot work" >&2
1682
+ fi
1671
1683
 
1672
1684
  # The env vars the worker needs.
1673
1685
  vv 'VISUAL_VERIFY_ENABLED:' "$MERGE_GATE_WORKER_MD" 'merge-gate missing VISUAL_VERIFY_ENABLED env var'
1674
1686
  vv 'VISUAL_VERIFY_START_COMMAND:' "$MERGE_GATE_WORKER_MD" 'merge-gate missing VISUAL_VERIFY_START_COMMAND env var'
1675
1687
 
1688
+ # The worker gates its agent on its own configuration, so an unconfigured repository
1689
+ # runs no model: the subject job exposes it, the top-level if: reads it.
1690
+ vv 'enabled: ' "${WORKFLOWS_DIR}/agent-visual-verify.md" 'visual-verify subject does not expose the enabled output'
1691
+ vv "outputs.enabled == 'true'" "${WORKFLOWS_DIR}/agent-visual-verify.md" 'visual-verify agent gate does not read the enabled output'
1692
+
1676
1693
  # The worker file exists.
1677
1694
  VV_WORKER_MD="${WORKFLOWS_DIR}/agent-visual-verify.md"
1678
1695
  if [ ! -f "$VV_WORKER_MD" ]; then
@@ -378,6 +378,17 @@ jobs:
378
378
  protected-hit: ${{ needs.protected_changes.outputs.requires_review }}
379
379
  owner-hit: ${{ needs.protected_changes.outputs.owner_hit }}
380
380
  confidence-threshold: ${{ env.CONFIDENCE_THRESHOLD }}
381
+ # The pre-merge screenshot pass is dispatched rather than nested. A nested
382
+ # workflow_call job cannot live downstream of this worker's agent: the compiler hoists
383
+ # prompt-referenced jobs into the agent's needs, and any call job depending on
384
+ # validate_output closes a cycle through agent (measured: the graph refuses to compile).
385
+ # The first version of this wiring was a step doing `uses:` on the worker's lock file,
386
+ # which is not a call at all -- the runner resolved it as a local action and died with
387
+ # "Can't find action.yml" under continue-on-error, so every auto-merge since the feature
388
+ # shipped merged with zero screenshots and nothing red. This dispatches the router's
389
+ # existing visual-verify operation (the dispatch-triage pattern) before the merge below.
390
+ # The merge pins the head SHA with --match-head-commit, and visual-verify re-reads the
391
+ # pull request itself, so the called worker owns its own subject validation.
381
392
  conclude:
382
393
  needs: [activation, subject, protected_changes, agent, safe_outputs, validate_output]
383
394
  # `protected_changes.result == 'success'` is stated rather than relied on. GitHub skips a job
@@ -396,6 +407,8 @@ jobs:
396
407
  contents: write
397
408
  issues: write
398
409
  pull-requests: write
410
+ # dispatching the visual-verify pass through the router's workflow_dispatch
411
+ actions: write
399
412
  steps:
400
413
  - name: Create bot token
401
414
  id: app-token
@@ -457,13 +470,30 @@ jobs:
457
470
  ```
458
471
 
459
472
  Findings and verification on the linked issue: #${{ needs.subject.outputs.issue }}. [View this workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
460
- - name: Run visual verification
473
+ # Screenshots before the merge. The visual-verify pass is dispatched through the
474
+ # router (see the visual_verify note above conclude) and cannot be awaited from here;
475
+ # the merge below pins the head SHA with --match-head-commit, so a screenshot run on
476
+ # the same head describes exactly what is being merged. GITHUB_TOKEN: a dispatch
477
+ # raises one workflow_run-free event, and the called worker re-owns its subject.
478
+ - name: Dispatch visual verification
461
479
  if: needs.validate_output.outputs.outcome == 'auto-merge' && env.VISUAL_VERIFY_ENABLED == 'true'
462
- uses: ./.github/workflows/agent-visual-verify.lock.yml
463
- with:
464
- pr-number: ${{ needs.subject.outputs.pr }}
465
- linked-issue: ${{ needs.subject.outputs.issue }}
466
- continue-on-error: true
480
+ env:
481
+ GH_TOKEN: ${{ github.token }}
482
+ REPO: ${{ github.repository }}
483
+ REF: ${{ github.event.repository.default_branch }}
484
+ PR: ${{ needs.subject.outputs.pr }}
485
+ ISSUE: ${{ needs.subject.outputs.issue }}
486
+ run: |
487
+ set -euo pipefail
488
+ if gh workflow run work-router.yml --repo "$REPO" --ref "$REF" \
489
+ -f operation=visual-verify -f pr-number="$PR" -f issue-number="$ISSUE"; then
490
+ echo "Visual verification dispatched for PR #$PR."
491
+ else
492
+ echo "::warning::could not dispatch visual verification for PR #$PR; merging without screenshots."
493
+ fi
494
+ # The visual verification pass is the visual_verify dispatch above. It runs as its own
495
+ # worker because a step cannot call a reusable workflow, and the merge below may land
496
+ # while the capture is still running -- the head SHA pin keeps the two honest.
467
497
  - name: Merge approved pull request
468
498
  if: needs.validate_output.outputs.outcome == 'auto-merge'
469
499
  env:
@@ -43,6 +43,10 @@ on:
43
43
  description: Issue number the pull request closes.
44
44
  required: true
45
45
  type: string
46
+ # The gate job the top-level `if:` reads. gh-aw folds that `if:` into the generated
47
+ # activation job but gives activation no dependency on the job, so the reference resolves
48
+ # to '' and the clause is false -- the agent would never run.
49
+ needs: [subject]
46
50
 
47
51
  # Rung 3-4. The agent reads the verification plan and writes waypoints as JSON; a post-agent
48
52
  # shell step runs agent-browser to capture screenshots outside the awf sandbox.
@@ -57,11 +61,28 @@ jobs:
57
61
  found: ${{ steps.subject.outputs.found }}
58
62
  pr: ${{ steps.subject.outputs.pr }}
59
63
  issue: ${{ steps.subject.outputs.issue }}
64
+ enabled: ${{ steps.config.outputs.enabled }}
60
65
  steps:
61
66
  - name: Checkout workflow actions
62
67
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
63
68
  with:
64
69
  persist-credentials: false
70
+ # Rung 4. A step can read the env: context; a job-level if: cannot. The enablement
71
+ # check therefore happens here and the agent gate reads the output -- a runnable
72
+ # snippet on an unconfigured repository burns the model otherwise.
73
+ - name: Read the visual-verify configuration
74
+ id: config
75
+ env:
76
+ ENABLED: ${{ env.VISUAL_VERIFY_ENABLED }}
77
+ START_COMMAND: ${{ env.VISUAL_VERIFY_START_COMMAND }}
78
+ run: |
79
+ set -euo pipefail
80
+ if [ "$ENABLED" = "true" ] && [ -n "$START_COMMAND" ]; then
81
+ echo "enabled=true" >> "$GITHUB_OUTPUT"
82
+ else
83
+ echo "enabled=false" >> "$GITHUB_OUTPUT"
84
+ echo "::notice::visual verification is not configured (VISUAL_VERIFY_ENABLED=$ENABLED, start command ${START_COMMAND:-unset}); the agent will not run."
85
+ fi
65
86
  - name: Identify the pull request and its issue
66
87
  id: subject
67
88
  env:
@@ -80,7 +101,7 @@ jobs:
80
101
  issue="$(jq -r '.closingIssuesReferences[0].number // empty' <<<"$pr")"
81
102
  fi
82
103
  if [ -z "$issue" ]; then
83
- issue="$(jq -r '.body // ""' <<<"$pr" |
104
+ issue="$(jq -r '.body // ""' <<<"$pr")"
84
105
  grep -oiE '(close[sd]?|fixe?[sd]?|resolve[sd]?) +#[0-9]+' |
85
106
  grep -oE '[0-9]+' | head -n 1 || true)"
86
107
  fi
@@ -198,6 +219,11 @@ post-steps:
198
219
  run: |
199
220
  kill "$APP_PID" 2>/dev/null || true
200
221
 
222
+ # `!failure()` because subject skips on an unconfigured repository and a closed pull
223
+ # request: without a status function the implicit success() would let those skips look
224
+ # like failures to every job that needs this one.
225
+ if: needs.subject.outputs.found == 'true' && needs.subject.outputs.enabled == 'true' && !failure()
226
+
201
227
  timeout-minutes: 15
202
228
 
203
229
  engine:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plainconceptsplatform/workflows",
3
- "version": "0.28.1",
3
+ "version": "0.28.2",
4
4
  "description": "Install and update Platform GitHub agentic workflows.",
5
5
  "keywords": [
6
6
  "github-actions",