@plainconceptsplatform/workflows 1.14.1 → 1.15.0
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/workflow-catalog.d.ts +1 -1
- package/dist/workflow-catalog.js +0 -2
- 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/cleanup-artifacts/action.yml +91 -91
- package/loops/actions/close-agent-issues/action.yml +43 -43
- package/loops/actions/create-issue-comment/action.yml +29 -29
- package/loops/actions/download-agent-output/action.yml +53 -53
- 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/remove-issue-labels/action.yml +37 -37
- package/loops/actions/update-agent-issues/action.yml +58 -58
- package/loops/actions/validate-refine-output/validate-refine-output.sh +13 -1
- 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 +4 -0
- package/loops/actions/verify-route-matrix/action.yml +9 -9
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +32 -46
- package/loops/templates/agentics/agentics-maintenance.yml +121 -121
- package/loops/templates/issues/bug_report.yml +109 -109
- package/loops/templates/issues/feature_request.yml +75 -75
- package/loops/workflows/agent-refine.md +29 -118
- package/loops/workflows/shared/platform-defaults.md +53 -53
- package/package.json +1 -1
- package/loops/actions/report-workflow-errors/action.yml +0 -538
- package/loops/actions/report-workflow-errors/report-policy.cjs +0 -194
- package/loops/templates/agentics/agentics-error-report.yml +0 -101
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/remove-issue-labels/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Remove issue labels
|
|
3
|
-
description: Remove one or more labels from an issue or pull request.
|
|
4
|
-
inputs:
|
|
5
|
-
token:
|
|
6
|
-
description: GitHub token used by github-script.
|
|
7
|
-
required: true
|
|
8
|
-
issue-number:
|
|
9
|
-
description: Issue or pull request number.
|
|
10
|
-
required: true
|
|
11
|
-
labels:
|
|
12
|
-
description: Labels to remove, one per line. A comma-separated list is accepted as well.
|
|
13
|
-
required: true
|
|
14
|
-
runs:
|
|
15
|
-
using: composite
|
|
16
|
-
steps:
|
|
17
|
-
- name: Remove labels
|
|
18
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
-
env:
|
|
20
|
-
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
-
LABELS: ${{ inputs.labels }}
|
|
22
|
-
with:
|
|
23
|
-
github-token: ${{ inputs.token }}
|
|
24
|
-
script: |
|
|
25
|
-
// Callers wrote `labels: a,b` while this split on newlines, so one label named "a,b"
|
|
26
|
-
// was removed: a 404, swallowed below, and neither label ever came off.
|
|
27
|
-
for (const label of process.env.LABELS.split(/\r?\n|,/).map((label) => label.trim()).filter(Boolean)) {
|
|
28
|
-
try {
|
|
29
|
-
await github.rest.issues.removeLabel({
|
|
30
|
-
...context.repo,
|
|
31
|
-
issue_number: Number(process.env.ISSUE_NUMBER),
|
|
32
|
-
name: label,
|
|
33
|
-
});
|
|
34
|
-
} catch (error) {
|
|
35
|
-
if (error.status !== 404) throw error;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/remove-issue-labels/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Remove issue labels
|
|
3
|
+
description: Remove one or more labels from an issue or pull request.
|
|
4
|
+
inputs:
|
|
5
|
+
token:
|
|
6
|
+
description: GitHub token used by github-script.
|
|
7
|
+
required: true
|
|
8
|
+
issue-number:
|
|
9
|
+
description: Issue or pull request number.
|
|
10
|
+
required: true
|
|
11
|
+
labels:
|
|
12
|
+
description: Labels to remove, one per line. A comma-separated list is accepted as well.
|
|
13
|
+
required: true
|
|
14
|
+
runs:
|
|
15
|
+
using: composite
|
|
16
|
+
steps:
|
|
17
|
+
- name: Remove labels
|
|
18
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
+
env:
|
|
20
|
+
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
+
LABELS: ${{ inputs.labels }}
|
|
22
|
+
with:
|
|
23
|
+
github-token: ${{ inputs.token }}
|
|
24
|
+
script: |
|
|
25
|
+
// Callers wrote `labels: a,b` while this split on newlines, so one label named "a,b"
|
|
26
|
+
// was removed: a 404, swallowed below, and neither label ever came off.
|
|
27
|
+
for (const label of process.env.LABELS.split(/\r?\n|,/).map((label) => label.trim()).filter(Boolean)) {
|
|
28
|
+
try {
|
|
29
|
+
await github.rest.issues.removeLabel({
|
|
30
|
+
...context.repo,
|
|
31
|
+
issue_number: Number(process.env.ISSUE_NUMBER),
|
|
32
|
+
name: label,
|
|
33
|
+
});
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error.status !== 404) throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/update-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Update agent issues
|
|
3
|
-
description: Apply every update_issue item from agent_output.json.
|
|
4
|
-
inputs:
|
|
5
|
-
output-file:
|
|
6
|
-
description: Path to agent_output.json.
|
|
7
|
-
required: true
|
|
8
|
-
token:
|
|
9
|
-
description: GitHub token with issues:write.
|
|
10
|
-
required: true
|
|
11
|
-
fallback-issue-number:
|
|
12
|
-
description: Issue an item targets when it names none.
|
|
13
|
-
required: false
|
|
14
|
-
default: ''
|
|
15
|
-
runs:
|
|
16
|
-
using: composite
|
|
17
|
-
steps:
|
|
18
|
-
- name: Update issues
|
|
19
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
20
|
-
env:
|
|
21
|
-
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
22
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
23
|
-
FALLBACK_ISSUE_NUMBER: ${{ inputs.fallback-issue-number }}
|
|
24
|
-
with:
|
|
25
|
-
github-token: ${{ inputs.token }}
|
|
26
|
-
script: |
|
|
27
|
-
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
28
|
-
const items = readAgentItems(process.env.OUTPUT_FILE, 'update_issue');
|
|
29
|
-
|
|
30
|
-
let updated = 0;
|
|
31
|
-
|
|
32
|
-
for (const item of items) {
|
|
33
|
-
const target = item.item_number ?? process.env.FALLBACK_ISSUE_NUMBER;
|
|
34
|
-
|
|
35
|
-
if (!target) {
|
|
36
|
-
core.warning(`update_issue item has no item_number and no fallback, skipping: ${JSON.stringify(item)}`);
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const changes = {};
|
|
41
|
-
if (item.title) changes.title = item.title;
|
|
42
|
-
if (item.body) changes.body = item.body;
|
|
43
|
-
|
|
44
|
-
if (Object.keys(changes).length === 0) {
|
|
45
|
-
core.warning(`update_issue item changes nothing, skipping: ${JSON.stringify(item)}`);
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
await github.rest.issues.update({
|
|
50
|
-
...context.repo,
|
|
51
|
-
issue_number: Number(target),
|
|
52
|
-
...changes,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
updated += 1;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
core.info(`Updated ${updated} issue(s).`);
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/update-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Update agent issues
|
|
3
|
+
description: Apply every update_issue item from agent_output.json.
|
|
4
|
+
inputs:
|
|
5
|
+
output-file:
|
|
6
|
+
description: Path to agent_output.json.
|
|
7
|
+
required: true
|
|
8
|
+
token:
|
|
9
|
+
description: GitHub token with issues:write.
|
|
10
|
+
required: true
|
|
11
|
+
fallback-issue-number:
|
|
12
|
+
description: Issue an item targets when it names none.
|
|
13
|
+
required: false
|
|
14
|
+
default: ''
|
|
15
|
+
runs:
|
|
16
|
+
using: composite
|
|
17
|
+
steps:
|
|
18
|
+
- name: Update issues
|
|
19
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
20
|
+
env:
|
|
21
|
+
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
22
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
23
|
+
FALLBACK_ISSUE_NUMBER: ${{ inputs.fallback-issue-number }}
|
|
24
|
+
with:
|
|
25
|
+
github-token: ${{ inputs.token }}
|
|
26
|
+
script: |
|
|
27
|
+
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
28
|
+
const items = readAgentItems(process.env.OUTPUT_FILE, 'update_issue');
|
|
29
|
+
|
|
30
|
+
let updated = 0;
|
|
31
|
+
|
|
32
|
+
for (const item of items) {
|
|
33
|
+
const target = item.item_number ?? process.env.FALLBACK_ISSUE_NUMBER;
|
|
34
|
+
|
|
35
|
+
if (!target) {
|
|
36
|
+
core.warning(`update_issue item has no item_number and no fallback, skipping: ${JSON.stringify(item)}`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const changes = {};
|
|
41
|
+
if (item.title) changes.title = item.title;
|
|
42
|
+
if (item.body) changes.body = item.body;
|
|
43
|
+
|
|
44
|
+
if (Object.keys(changes).length === 0) {
|
|
45
|
+
core.warning(`update_issue item changes nothing, skipping: ${JSON.stringify(item)}`);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await github.rest.issues.update({
|
|
50
|
+
...context.repo,
|
|
51
|
+
issue_number: Number(target),
|
|
52
|
+
...changes,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
updated += 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
core.info(`Updated ${updated} issue(s).`);
|
|
@@ -121,6 +121,18 @@ jq -r --arg marker "$marker" --arg prefix "$comment_prefix" --arg issue "$issue_
|
|
|
121
121
|
(.body | split($marker) | join("") | split($prefix) | join("") |
|
|
122
122
|
gsub("<[^>]*>"; "") | test("[[:alnum:]]")));
|
|
123
123
|
|
|
124
|
+
# A completion announcement. Branch 5 (has_clarification -> questions) treats any comment
|
|
125
|
+
# with content as a question the agent asked, but a "Refinement complete" comment is not a
|
|
126
|
+
# question: paired with a draft body (which is how branch 5 is reached, via has_draft_body)
|
|
127
|
+
# it is a self-contradiction -- the agent said complete over a body still pending -- and the
|
|
128
|
+
# right outcome is invalid, not questions. Seen as a regression after has_draft_body started
|
|
129
|
+
# matching the pending mark when the HTML draft marker was stripped (1.15.0): the test "a body
|
|
130
|
+
# still pending with no questions asked is not complete" flipped from invalid to questions.
|
|
131
|
+
def has_completion_comment:
|
|
132
|
+
any(.items[]; .type == "add_comment" and (.item_number | tostring) == $issue and
|
|
133
|
+
(.body | type == "string") and
|
|
134
|
+
(.body | test("Refinement complete"; "i")));
|
|
135
|
+
|
|
124
136
|
# Order matters: a run that wrote children is a split even though it also replaced the
|
|
125
137
|
# parent body, and a lone child with no parent update is an incomplete split, not a
|
|
126
138
|
# complete refinement. A body carrying the draft marker is a temporal draft, not a
|
|
@@ -140,7 +152,7 @@ jq -r --arg marker "$marker" --arg prefix "$comment_prefix" --arg issue "$issue_
|
|
|
140
152
|
and (reported_incomplete | not) then "questions"
|
|
141
153
|
elif has_replacement_body and (has_draft_body | not) and (has_pending_marks | not) and has_only_source_items then "complete"
|
|
142
154
|
elif has_clarification and ((has_update | not) or has_draft_body) and has_only_source_items
|
|
143
|
-
and (reported_incomplete | not) then "questions"
|
|
155
|
+
and (reported_incomplete | not) and (has_completion_comment | not) then "questions"
|
|
144
156
|
else "invalid"
|
|
145
157
|
end
|
|
146
158
|
' "$output_file"
|
|
@@ -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"
|
|
@@ -82,6 +82,10 @@ assert_output 'draft update with questions comment is questions' questions \
|
|
|
82
82
|
# cannot settle on its own" instead of the exact sentence. The pending mark
|
|
83
83
|
# (_pending see questions below_) survives in the body and the comment is still on
|
|
84
84
|
# the source issue, so the outcome is questions, not invalid.
|
|
85
|
+
# The JSON fixture below carries literal markdown backticks from the real Bots #1336 output.
|
|
86
|
+
# The checker reads them as command substitution inside single quotes (SC2016), a false
|
|
87
|
+
# positive because the whole argument is data, not shell.
|
|
88
|
+
# shellcheck disable=SC2016
|
|
85
89
|
assert_output 'stripped draft marker with paraphrased questions is questions' questions \
|
|
86
90
|
'{"items":[{"type":"update_issue","item_number":42,"body":"**Complexity:** standard path\n\n> Refinement draft. Three open questions are in a separate comment. The parts they leave open are marked `_pending see questions below_`."},{"type":"add_comment","item_number":42,"body":"## Refinement update\n\nI have some questions that the code cannot settle on its own. Reply in one comment to change any of them.\n1. Does the conductor bot stay local only too?"}]}'
|
|
87
91
|
|
|
@@ -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"
|
|
@@ -2645,17 +2645,11 @@ if worker_installed audit; then
|
|
|
2645
2645
|
printf '%s\n' "$story_labels" | grep -qx refine || af "stories are not labelled refine, so nothing refines them"
|
|
2646
2646
|
printf '%s\n' "$story_labels" | grep -qx audit && af "stories are labelled audit; three of them fill the backpressure and audit-close treats each as a report"
|
|
2647
2647
|
grep -qE '^ staged: true' "$AUDIT_WORKER_MD" || af "is not staged, so gh-aw files the issues before they are measured"
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
af "AUDIT_MAX_BODY_CHARS is not below refine's REFINE_MAX_BODY_CHARS (${refine_chars:-unset})"
|
|
2654
|
-
[ "$(audit_env AUDIT_MAX_WORK_UNITS)" -lt "${refine_units:-0}" ] 2>/dev/null ||
|
|
2655
|
-
af "AUDIT_MAX_WORK_UNITS is not below refine's REFINE_MAX_WORK_UNITS (${refine_units:-unset})"
|
|
2656
|
-
grep -qF 'uses: ./.github/actions/measure-issue-size' "$REFINE_WORKER_MD" ||
|
|
2657
|
-
af "and refine measure with different rules; refine's size_guard must use measure-issue-size"
|
|
2658
|
-
fi
|
|
2648
|
+
# Refine no longer carries a size gate (1.15.0 removed it -- the split mechanism bounds
|
|
2649
|
+
# the output, and gating refine on input size while implement accepts any size just
|
|
2650
|
+
# mis-routed real specs). So there is no REFINE_MAX_* to keep AUDIT_MAX_* below: the
|
|
2651
|
+
# audit's own limits are about keeping its filed stories small and digestible, not about
|
|
2652
|
+
# staying under a gate refine will refuse.
|
|
2659
2653
|
if [ "$AUDIT_FILE_OK" -eq 1 ]; then PASS=$((PASS + 1)); else FAIL=$((FAIL + 1)); fi
|
|
2660
2654
|
fi
|
|
2661
2655
|
|
|
@@ -2676,12 +2670,9 @@ if worker_installed docs-audit; then
|
|
|
2676
2670
|
printf '%s\n' "$docs_story_labels" | grep -qx docs-audit && dfa "stories are labelled docs-audit; one of them fills the backpressure"
|
|
2677
2671
|
grep -qE '^ staged: true' "$DOCS_WORKER_MD" || dfa "is not staged, so gh-aw files the issues before they are measured"
|
|
2678
2672
|
grep -q 'add-issue-labels' "$DOCS_WORKER_MD" && dfa "still labels a report gh-aw filed itself"
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
[ "${docs_chars:-99999999}" -lt "${refine_chars:-0}" ] 2>/dev/null ||
|
|
2683
|
-
dfa "DOCS_AUDIT_MAX_BODY_CHARS is not below refine's REFINE_MAX_BODY_CHARS (${refine_chars:-unset})"
|
|
2684
|
-
fi
|
|
2673
|
+
# Refine has no size gate (1.15.0), so there is no REFINE_MAX_BODY_CHARS to keep
|
|
2674
|
+
# DOCS_AUDIT_MAX_BODY_CHARS below. The docs audit's own limit is about keeping its
|
|
2675
|
+
# filed stories small, measured before filing; it does not depend on refine.
|
|
2685
2676
|
if [ "$DOCS_FILE_OK" -eq 1 ]; then PASS=$((PASS + 1)); else FAIL=$((FAIL + 1)); fi
|
|
2686
2677
|
fi
|
|
2687
2678
|
|
|
@@ -2817,42 +2808,37 @@ fi
|
|
|
2817
2808
|
|
|
2818
2809
|
echo "── Refine size gate ──────────────────────────────────────────────────────"
|
|
2819
2810
|
|
|
2820
|
-
#
|
|
2821
|
-
# the agent's needs
|
|
2822
|
-
#
|
|
2823
|
-
#
|
|
2811
|
+
# Refine had a size-gate + refusal job that skipped in the happy path, and gh-aw adds every
|
|
2812
|
+
# custom job to the agent's needs, so a skip-poisoned implicit success() killed the agent
|
|
2813
|
+
# in 0s (Pliny-Bot #320-322). The size gate was removed at 1.15.0 (the split mechanism
|
|
2814
|
+
# bounds the output, and gating refine on input size while implement accepts any size
|
|
2815
|
+
# mis-routed real specs like Bots #1357). Two claims from that era still hold and are
|
|
2816
|
+
# asserted below:
|
|
2824
2817
|
#
|
|
2825
|
-
# 1. the agent's gate carries !failure()
|
|
2826
|
-
#
|
|
2827
|
-
#
|
|
2828
|
-
#
|
|
2829
|
-
#
|
|
2818
|
+
# 1. the agent's top-level gate still carries !failure(): still_open and eligibility skip
|
|
2819
|
+
# when refinement should not run (issue closed, parked for review), and without
|
|
2820
|
+
# !failure() a skipped need would poison the implicit success() and skip the agent
|
|
2821
|
+
# 2. the split floor: a split child carries a whole stack's machinery, so a 1- or 2-point
|
|
2822
|
+
# slice is a fragment and must be folded into a sibling
|
|
2830
2823
|
if worker_installed refine; then
|
|
2831
|
-
|
|
2824
|
+
REFINE_OK=1
|
|
2832
2825
|
REFINE_WORKER_MD="${WORKFLOWS_DIR}/agent-refine.md"
|
|
2833
2826
|
|
|
2834
2827
|
# The top-level if: starts at column 0 -- job-level ifs: are indented -- so anchor on that,
|
|
2835
|
-
# not on the prose comment above it. It must end with !failure()
|
|
2828
|
+
# not on the prose comment above it. It must end with !failure(): still_open and eligibility
|
|
2829
|
+
# skip in the not-eligible case, and an implicit success() would short-circuit the agent.
|
|
2836
2830
|
top_level_if="$(sed -n 's/^if: //p' "$REFINE_WORKER_MD" | head -1)"
|
|
2837
2831
|
if [[ "$top_level_if" != *'!failure()' ]]; then
|
|
2838
|
-
|
|
2839
|
-
echo "FAIL: refine gates the agent without !failure(); a skipped
|
|
2840
|
-
fi
|
|
2841
|
-
|
|
2842
|
-
# Extract the incomplete job's own block. A whole-file grep cannot make this claim: reserve,
|
|
2843
|
-
# refuse_big_issue and the agent gate all read size_guard, so the exclusion clause could be
|
|
2844
|
-
# deleted from incomplete while every grep still passes.
|
|
2845
|
-
incomplete_block="$(awk '/^ incomplete:/{found=1; next} found && /^ [a-z_]+:/{exit} found{print}' "$REFINE_WORKER_MD")"
|
|
2846
|
-
if ! printf '%s' "$incomplete_block" | grep -qE '^ needs: \[.*size_guard' \
|
|
2847
|
-
|| ! printf '%s' "$incomplete_block" | grep -qF "needs.size_guard.outputs.too_big != 'true'"; then
|
|
2848
|
-
SIZE_GATE_OK=0
|
|
2849
|
-
echo "FAIL: refine's incomplete does not exclude the refusal path; every refused issue also loops attempts" >&2
|
|
2832
|
+
REFINE_OK=0
|
|
2833
|
+
echo "FAIL: refine gates the agent without !failure(); a skipped still_open/eligibility poisons the implicit success() and skips the agent on every closed-or-reviewed issue" >&2
|
|
2850
2834
|
fi
|
|
2851
2835
|
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2836
|
+
# The size gate is gone, so there must be no size_guard job and no refuse_big_issue job
|
|
2837
|
+
# left behind (a leftover job compiles into the agent's needs and re-introduces the
|
|
2838
|
+
# skip-poison the removal was meant to end).
|
|
2839
|
+
if grep -qE '^ (size_guard|refuse_big_issue):' "$REFINE_WORKER_MD"; then
|
|
2840
|
+
REFINE_OK=0
|
|
2841
|
+
echo "FAIL: refine still carries a size_guard or refuse_big_issue job; the size gate was removed at 1.15.0" >&2
|
|
2856
2842
|
fi
|
|
2857
2843
|
|
|
2858
2844
|
# The split floor: a split child carries a whole stack's machinery (issue, feature branch,
|
|
@@ -2861,11 +2847,11 @@ if worker_installed refine; then
|
|
|
2861
2847
|
# so a consumer cannot lower it below 3 without editing the worker.
|
|
2862
2848
|
if ! grep -qF 'MIN_CHILD_POINTS: "3"' "$REFINE_WORKER_MD" \
|
|
2863
2849
|
|| ! grep -qF 'child estimated below ${{ env.MIN_CHILD_POINTS }}' "$REFINE_WORKER_MD"; then
|
|
2864
|
-
|
|
2850
|
+
REFINE_OK=0
|
|
2865
2851
|
echo "FAIL: refine allows split children below 3 points; the floor must stay interpolated from MIN_CHILD_POINTS" >&2
|
|
2866
2852
|
fi
|
|
2867
2853
|
|
|
2868
|
-
if [ "$
|
|
2854
|
+
if [ "$REFINE_OK" -eq 1 ]; then PASS=$((PASS + 1)); else FAIL=$((FAIL + 1)); fi
|
|
2869
2855
|
fi
|
|
2870
2856
|
|
|
2871
2857
|
# The safeoutputs bridge reads its JSON from stdin only for `tool .`. Any --flag on the line makes
|