@plainconceptsplatform/workflows 0.19.2 → 0.20.1
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.
- package/dist/catalog-installation.js +12 -1
- package/dist/index.js +0 -0
- package/dist/stack-defaults.js +16 -16
- package/dist/worker-env.js +14 -0
- package/loops/actions/add-issue-labels/action.yml +50 -50
- package/loops/actions/agent-output.cjs +17 -17
- package/loops/actions/apply-agent-bundle/action.yml +24 -24
- package/loops/actions/apply-agent-comments/action.yml +42 -42
- package/loops/actions/apply-agent-labels/action.yml +55 -55
- package/loops/actions/apply-agent-output/action.yml +108 -108
- package/loops/actions/assess-blast-radius/action.yml +148 -0
- package/loops/actions/assess-blast-radius/assess-blast-radius.sh +138 -0
- package/loops/actions/classify-route/action.yml +100 -100
- package/loops/actions/cleanup-artifacts/action.yml +91 -91
- package/loops/actions/close-agent-issues/action.yml +43 -43
- package/loops/actions/create-agent-issues/action.yml +52 -52
- package/loops/actions/create-issue-comment/action.yml +29 -29
- package/loops/actions/download-agent-output/action.yml +53 -53
- package/loops/actions/housekeeping/action.yml +55 -2
- package/loops/actions/link-pr-to-issue/action.yml +40 -40
- package/loops/actions/list-open-issues/action.yml +33 -33
- package/loops/actions/load-issue-context/action.yml +45 -45
- package/loops/actions/merge-agent-pr/action.yml +49 -49
- package/loops/actions/push-agent-branch/action.yml +45 -45
- package/loops/actions/remove-issue-labels/action.yml +37 -37
- package/loops/actions/update-agent-issues/action.yml +58 -58
- package/loops/actions/validate-merge-gate-output/action.yml +62 -40
- package/loops/actions/validate-merge-gate-output/validate-merge-gate-output.sh +147 -31
- package/loops/actions/validate-refine-output/action.yml +48 -44
- package/loops/actions/validate-refine-output/validate-refine-output.sh +15 -4
- package/loops/actions/validate-review-output/action.yml +35 -35
- package/loops/actions/validate-triage-output/action.yml +36 -36
- package/loops/actions/verify-composite-actions/action.yml +9 -9
- package/loops/actions/verify-refine-output/action.yml +9 -9
- package/loops/actions/verify-refine-output/verify-refine-output.sh +6 -1
- package/loops/actions/verify-route-matrix/action.yml +9 -9
- package/loops/actions/verify-route-matrix/verify-gate-metrics.mjs +51 -0
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +329 -29
- package/loops/scripts/compile-agent-workflows.mjs +331 -331
- package/loops/templates/agentics/agentics-maintenance.yml +121 -121
- package/loops/templates/ci/app-ci-dotnet-next.yml +330 -330
- package/loops/templates/ci/app-ci-node-monorepo.yml +260 -260
- package/loops/templates/issues/bug_report.yml +109 -109
- package/loops/templates/issues/feature_request.yml +75 -75
- package/loops/templates/opencode/opencode.ci.json +55 -49
- package/loops/templates/opencode/opencode.ci.json.md +59 -49
- package/loops/templates/release/github-release.yml +30 -30
- package/loops/workflows/agent-merge-gate.md +367 -148
- package/loops/workflows/agent-refine.md +60 -16
- package/loops/workflows/authorize-bot-work.yml +105 -105
- package/loops/workflows/shared/opencode-ci.md +206 -206
- package/loops/workflows/shared/platform-defaults.md +19 -19
- package/package.json +12 -11
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/validate-review-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Validate review output
|
|
3
|
-
description: Verify an apply-review outcome accounts for every unresolved review thread.
|
|
4
|
-
inputs:
|
|
5
|
-
output-file:
|
|
6
|
-
description: Path to agent_output.json.
|
|
7
|
-
required: true
|
|
8
|
-
pr-number:
|
|
9
|
-
description: Pull request receiving the review feedback.
|
|
10
|
-
required: true
|
|
11
|
-
review-threads-file:
|
|
12
|
-
description: JSON file containing unresolved review threads.
|
|
13
|
-
required: true
|
|
14
|
-
outputs:
|
|
15
|
-
valid:
|
|
16
|
-
description: Whether the agent output is a valid review outcome.
|
|
17
|
-
value: ${{ steps.validate.outputs.valid }}
|
|
18
|
-
outcome:
|
|
19
|
-
description: "Deterministic review outcome: implemented, already-satisfied, needs-human, or invalid."
|
|
20
|
-
value: ${{ steps.validate.outputs.outcome }}
|
|
21
|
-
runs:
|
|
22
|
-
using: composite
|
|
23
|
-
steps:
|
|
24
|
-
- name: Validate review outcome
|
|
25
|
-
id: validate
|
|
26
|
-
shell: bash
|
|
27
|
-
env:
|
|
28
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
29
|
-
PR_NUMBER: ${{ inputs.pr-number }}
|
|
30
|
-
REVIEW_THREADS_FILE: ${{ inputs.review-threads-file }}
|
|
31
|
-
run: |
|
|
32
|
-
set -euo pipefail
|
|
33
|
-
outcome="$(bash "${{ github.action_path }}/validate-review-output.sh" "$OUTPUT_FILE" "$PR_NUMBER" "$REVIEW_THREADS_FILE")"
|
|
34
|
-
echo "outcome=$outcome" >> "$GITHUB_OUTPUT"
|
|
35
|
-
echo "valid=$([ "$outcome" != 'invalid' ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/validate-review-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Validate review output
|
|
3
|
+
description: Verify an apply-review outcome accounts for every unresolved review thread.
|
|
4
|
+
inputs:
|
|
5
|
+
output-file:
|
|
6
|
+
description: Path to agent_output.json.
|
|
7
|
+
required: true
|
|
8
|
+
pr-number:
|
|
9
|
+
description: Pull request receiving the review feedback.
|
|
10
|
+
required: true
|
|
11
|
+
review-threads-file:
|
|
12
|
+
description: JSON file containing unresolved review threads.
|
|
13
|
+
required: true
|
|
14
|
+
outputs:
|
|
15
|
+
valid:
|
|
16
|
+
description: Whether the agent output is a valid review outcome.
|
|
17
|
+
value: ${{ steps.validate.outputs.valid }}
|
|
18
|
+
outcome:
|
|
19
|
+
description: "Deterministic review outcome: implemented, already-satisfied, needs-human, or invalid."
|
|
20
|
+
value: ${{ steps.validate.outputs.outcome }}
|
|
21
|
+
runs:
|
|
22
|
+
using: composite
|
|
23
|
+
steps:
|
|
24
|
+
- name: Validate review outcome
|
|
25
|
+
id: validate
|
|
26
|
+
shell: bash
|
|
27
|
+
env:
|
|
28
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
29
|
+
PR_NUMBER: ${{ inputs.pr-number }}
|
|
30
|
+
REVIEW_THREADS_FILE: ${{ inputs.review-threads-file }}
|
|
31
|
+
run: |
|
|
32
|
+
set -euo pipefail
|
|
33
|
+
outcome="$(bash "${{ github.action_path }}/validate-review-output.sh" "$OUTPUT_FILE" "$PR_NUMBER" "$REVIEW_THREADS_FILE")"
|
|
34
|
+
echo "outcome=$outcome" >> "$GITHUB_OUTPUT"
|
|
35
|
+
echo "valid=$([ "$outcome" != 'invalid' ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/validate-triage-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Validate triage output
|
|
3
|
-
description: Verify agent_output.json contains a usable triage verdict before any GitHub writes.
|
|
4
|
-
inputs:
|
|
5
|
-
output-file:
|
|
6
|
-
description: Path to agent_output.json.
|
|
7
|
-
required: true
|
|
8
|
-
issue-number:
|
|
9
|
-
description: Issue number that every triage outcome must target.
|
|
10
|
-
required: true
|
|
11
|
-
outputs:
|
|
12
|
-
valid:
|
|
13
|
-
description: Whether the output contains a usable triage comment with a verdict.
|
|
14
|
-
value: ${{ steps.validate.outputs.valid }}
|
|
15
|
-
outcome:
|
|
16
|
-
description: "Deterministic triage outcome: pass, needs-info, needs-maintainer, block, or invalid."
|
|
17
|
-
value: ${{ steps.validate.outputs.outcome }}
|
|
18
|
-
runs:
|
|
19
|
-
using: composite
|
|
20
|
-
steps:
|
|
21
|
-
- name: Validate triage outcome
|
|
22
|
-
id: validate
|
|
23
|
-
shell: bash
|
|
24
|
-
env:
|
|
25
|
-
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
26
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
27
|
-
run: |
|
|
28
|
-
set -euo pipefail
|
|
29
|
-
|
|
30
|
-
outcome="$(bash "${{ github.action_path }}/validate-triage-output.sh" "$OUTPUT_FILE" "$ISSUE_NUMBER")"
|
|
31
|
-
echo "outcome=$outcome" >> "$GITHUB_OUTPUT"
|
|
32
|
-
echo "valid=$([ "$outcome" != 'invalid' ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
|
33
|
-
|
|
34
|
-
if [ "$outcome" = 'invalid' ]; then
|
|
35
|
-
echo "::warning::Agent output has no usable triage outcome. It will not be applied."
|
|
36
|
-
fi
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/validate-triage-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Validate triage output
|
|
3
|
+
description: Verify agent_output.json contains a usable triage verdict before any GitHub writes.
|
|
4
|
+
inputs:
|
|
5
|
+
output-file:
|
|
6
|
+
description: Path to agent_output.json.
|
|
7
|
+
required: true
|
|
8
|
+
issue-number:
|
|
9
|
+
description: Issue number that every triage outcome must target.
|
|
10
|
+
required: true
|
|
11
|
+
outputs:
|
|
12
|
+
valid:
|
|
13
|
+
description: Whether the output contains a usable triage comment with a verdict.
|
|
14
|
+
value: ${{ steps.validate.outputs.valid }}
|
|
15
|
+
outcome:
|
|
16
|
+
description: "Deterministic triage outcome: pass, needs-info, needs-maintainer, block, or invalid."
|
|
17
|
+
value: ${{ steps.validate.outputs.outcome }}
|
|
18
|
+
runs:
|
|
19
|
+
using: composite
|
|
20
|
+
steps:
|
|
21
|
+
- name: Validate triage outcome
|
|
22
|
+
id: validate
|
|
23
|
+
shell: bash
|
|
24
|
+
env:
|
|
25
|
+
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
26
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
27
|
+
run: |
|
|
28
|
+
set -euo pipefail
|
|
29
|
+
|
|
30
|
+
outcome="$(bash "${{ github.action_path }}/validate-triage-output.sh" "$OUTPUT_FILE" "$ISSUE_NUMBER")"
|
|
31
|
+
echo "outcome=$outcome" >> "$GITHUB_OUTPUT"
|
|
32
|
+
echo "valid=$([ "$outcome" != 'invalid' ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
|
33
|
+
|
|
34
|
+
if [ "$outcome" = 'invalid' ]; then
|
|
35
|
+
echo "::warning::Agent output has no usable triage outcome. It will not be applied."
|
|
36
|
+
fi
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/verify-composite-actions/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Verify composite actions
|
|
3
|
-
description: Check every local composite action manifest parses and uses only contexts a composite action actually has.
|
|
4
|
-
runs:
|
|
5
|
-
using: composite
|
|
6
|
-
steps:
|
|
7
|
-
- name: Validate composite action manifests
|
|
8
|
-
shell: bash
|
|
9
|
-
run: bash "${GITHUB_ACTION_PATH}/verify-composite-actions.sh"
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/verify-composite-actions/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Verify composite actions
|
|
3
|
+
description: Check every local composite action manifest parses and uses only contexts a composite action actually has.
|
|
4
|
+
runs:
|
|
5
|
+
using: composite
|
|
6
|
+
steps:
|
|
7
|
+
- name: Validate composite action manifests
|
|
8
|
+
shell: bash
|
|
9
|
+
run: bash "${GITHUB_ACTION_PATH}/verify-composite-actions.sh"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/verify-refine-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Verify refine output validation
|
|
3
|
-
description: Exercise deterministic Refine output validation regressions.
|
|
4
|
-
runs:
|
|
5
|
-
using: composite
|
|
6
|
-
steps:
|
|
7
|
-
- name: Verify refinement outcomes
|
|
8
|
-
shell: bash
|
|
9
|
-
run: bash "${{ github.action_path }}/verify-refine-output.sh"
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/verify-refine-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Verify refine output validation
|
|
3
|
+
description: Exercise deterministic Refine output validation regressions.
|
|
4
|
+
runs:
|
|
5
|
+
using: composite
|
|
6
|
+
steps:
|
|
7
|
+
- name: Verify refinement outcomes
|
|
8
|
+
shell: bash
|
|
9
|
+
run: bash "${{ github.action_path }}/verify-refine-output.sh"
|
|
@@ -7,6 +7,7 @@ set -euo pipefail
|
|
|
7
7
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
8
|
VALIDATOR="${HERE}/../validate-refine-output/validate-refine-output.sh"
|
|
9
9
|
MARKER='<!-- agent-refine -->'
|
|
10
|
+
DRAFT_MARK='<!-- agent-refine-draft -->'
|
|
10
11
|
PREFIX='Refinement update'
|
|
11
12
|
TEMP_DIR="$(mktemp -d)"
|
|
12
13
|
|
|
@@ -23,7 +24,7 @@ assert_output() {
|
|
|
23
24
|
local actual
|
|
24
25
|
|
|
25
26
|
printf '%s' "$payload" > "$output_file"
|
|
26
|
-
actual="$(bash "$VALIDATOR" "$output_file" "$MARKER" "$PREFIX" 42)"
|
|
27
|
+
actual="$(bash "$VALIDATOR" "$output_file" "$MARKER" "$PREFIX" 42 "$DRAFT_MARK")"
|
|
27
28
|
|
|
28
29
|
if [ "$actual" = "$expected" ]; then
|
|
29
30
|
PASS=$((PASS + 1))
|
|
@@ -55,6 +56,10 @@ assert_output 'wrong issue output is invalid' invalid \
|
|
|
55
56
|
'{"items":[{"type":"add_comment","item_number":7,"body":"Which users need this feature?"}]}'
|
|
56
57
|
assert_output 'complete output cannot update another issue' invalid \
|
|
57
58
|
'{"items":[{"type":"update_issue","item_number":42,"body":"# User story"},{"type":"update_issue","item_number":7,"body":"# Other story"}]}'
|
|
59
|
+
assert_output 'draft update with questions comment is questions' questions \
|
|
60
|
+
'{"items":[{"type":"update_issue","item_number":42,"body":"<!-- agent-refine-draft -->\n### Proposal\n_pending — see questions below_"},{"type":"add_comment","item_number":42,"body":"<!-- agent-refine -->\nRefinement update\nI have some questions about this issue. Please reply in one comment and I''ll process your answers.\nWhich area owns this behavior?"}]}'
|
|
61
|
+
assert_output 'draft update alone is invalid' invalid \
|
|
62
|
+
'{"items":[{"type":"update_issue","item_number":42,"body":"<!-- agent-refine-draft -->\n### Proposal\n_pending — see questions below_"}]}'
|
|
58
63
|
|
|
59
64
|
# From a real run. The agent's first update_issue went out malformed, the bridge counted it
|
|
60
65
|
# as spent, the retry carrying the body was refused, and the "Refinement complete" comment
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/verify-route-matrix/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Verify route matrix
|
|
3
|
-
description: Exercise the router's classifier against every supported event, and check that each route and dispatch operation has a job in work-router.yml.
|
|
4
|
-
runs:
|
|
5
|
-
using: composite
|
|
6
|
-
steps:
|
|
7
|
-
- name: Run route matrix verification
|
|
8
|
-
shell: bash
|
|
9
|
-
run: bash "${GITHUB_ACTION_PATH}/verify-route-matrix.sh"
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/verify-route-matrix/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Verify route matrix
|
|
3
|
+
description: Exercise the router's classifier against every supported event, and check that each route and dispatch operation has a job in work-router.yml.
|
|
4
|
+
runs:
|
|
5
|
+
using: composite
|
|
6
|
+
steps:
|
|
7
|
+
- name: Run route matrix verification
|
|
8
|
+
shell: bash
|
|
9
|
+
run: bash "${GITHUB_ACTION_PATH}/verify-route-matrix.sh"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Managed by @plainconceptsplatform/workflows. Source: loops/actions/verify-route-matrix/verify-gate-metrics.mjs. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
+
// Runs the housekeeping digest's gate-metrics renderer against fixtures. The auto-merge rate
|
|
3
|
+
// is the number the merge gate asks to be judged on, and the one Phase 7 would widen trust
|
|
4
|
+
// from, so "it cannot merge anything wrong" is not a reason to leave its arithmetic untested.
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
const yml = readFileSync(process.argv[2], "utf8").replace(/\r\n/g, "\n");
|
|
7
|
+
|
|
8
|
+
// Pull the gate metrics renderer out of the inline github-script block and run it. The counting
|
|
9
|
+
// loops above it need a GitHub API to exercise, but the arithmetic does not, and the arithmetic
|
|
10
|
+
// is the part that reports a number somebody will act on.
|
|
11
|
+
const start = yml.indexOf("const gateSection = () => {");
|
|
12
|
+
if (start === -1) { console.error("FAIL: housekeeping has no gateSection renderer"); process.exit(1); }
|
|
13
|
+
let depth = 0, end = start;
|
|
14
|
+
for (let i = yml.indexOf("{", start); i < yml.length; i++) {
|
|
15
|
+
if (yml[i] === "{") depth++;
|
|
16
|
+
else if (yml[i] === "}") { depth--; if (depth === 0) { end = i + 1; break; } }
|
|
17
|
+
}
|
|
18
|
+
const src = yml.slice(start, end).replace(/^\s+/gm, " ");
|
|
19
|
+
|
|
20
|
+
const run = (dispositions, autoMerged, reverts) =>
|
|
21
|
+
new Function("dispositions", "autoMerged", "reverts", "metricsWindowMs",
|
|
22
|
+
`${src}; return gateSection();`)(dispositions, autoMerged, reverts, 14 * 24 * 3600000);
|
|
23
|
+
|
|
24
|
+
let failed = 0;
|
|
25
|
+
const check = (name, got, want) => {
|
|
26
|
+
const ok = typeof want === "function" ? want(got) : got === want;
|
|
27
|
+
if (!ok) { failed = 1; console.error(`FAIL: gate metrics ${name}: got ${JSON.stringify(got)}`); }
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
check("is empty when the gate has posted nothing",
|
|
31
|
+
run({}, [], []), "");
|
|
32
|
+
check("reports the auto-merge share",
|
|
33
|
+
run({ "auto-merge": 12, "human-review": 2, "owner-review": 1 }, [], []),
|
|
34
|
+
(s) => s.includes("**80% auto-merged** (12 of 15 dispositions)"));
|
|
35
|
+
check("rounds rather than truncates",
|
|
36
|
+
run({ "auto-merge": 2, "human-review": 1 }, [], []),
|
|
37
|
+
(s) => s.includes("**67% auto-merged**"));
|
|
38
|
+
check("counts a revert only against the pull request it names",
|
|
39
|
+
run({ "auto-merge": 2 }, [11, 12], [12, 99]),
|
|
40
|
+
(s) => s.includes("later reverted: 1"));
|
|
41
|
+
check("counts no reverts when none match",
|
|
42
|
+
run({ "auto-merge": 2 }, [11, 12], [77]),
|
|
43
|
+
(s) => s.includes("later reverted: 0"));
|
|
44
|
+
check("a repository with only parked pull requests reads as zero, not as an error",
|
|
45
|
+
run({ "human-review": 3 }, [], []),
|
|
46
|
+
(s) => s.includes("**0% auto-merged** (0 of 3 dispositions)"));
|
|
47
|
+
check("lists every disposition it saw",
|
|
48
|
+
run({ "auto-merge": 1, blocked: 2 }, [], []),
|
|
49
|
+
(s) => s.includes("`blocked` · 2") && s.includes("`auto-merge` · 1"));
|
|
50
|
+
|
|
51
|
+
process.exit(failed);
|