Skip to content

Commit 7644b30

Browse files
authored
fix(igla): harden auto-merge and brain-seal-refresh workflows
Closes #1440
1 parent 5850c30 commit 7644b30

6 files changed

Lines changed: 72 additions & 155 deletions

File tree

.github/workflows/auto-merge-ready-prs.yml

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ on:
1414
default: false
1515

1616
permissions:
17+
contents: write
1718
pull-requests: write
1819

1920
jobs:
@@ -29,46 +30,79 @@ jobs:
2930
GH_TOKEN: ${{ github.token }}
3031
run: |
3132
READY_PRS=()
32-
echo "Finding PRs with all CI checks passing..."
33+
echo "Finding PRs with all CI checks passing and L1 traceability..."
3334
3435
PR_LIST=$(gh pr list --state open --limit 50 --json number --jq '.[].number' 2>/dev/null || echo "")
3536
3637
if [ -z "$PR_LIST" ]; then
3738
echo "No open PRs found"
3839
echo "ready_prs=" >> $GITHUB_OUTPUT
3940
echo "count=0" >> $GITHUB_OUTPUT
41+
echo "skipped=0" >> $GITHUB_OUTPUT
4042
exit 0
4143
fi
4244
45+
SKIPPED=0
46+
L1_RE='(Closes?|Fixes?|Resolves?|Refs?|Updates?)\s*#[0-9]+'
47+
4348
for pr in $PR_LIST; do
44-
MAIN_CHECKS=$(gh pr view "$pr" --json statusCheckRollup --jq \
45-
'[.statusCheckRollup[] | select(.name != "NotebookLM Auto-Sync" and .name != ".github/workflows/notebook-sync.yml")]' 2>/dev/null || echo "[]")
49+
echo "Evaluating PR #$pr..."
50+
51+
# L1 TRACEABILITY: require an issue reference in title or body.
52+
PR_METADATA=$(gh pr view "$pr" --json title,body,reviews,statusCheckRollup 2>/dev/null || echo "")
53+
if [ -z "$PR_METADATA" ]; then
54+
echo " Skipped: cannot fetch PR metadata"
55+
SKIPPED=$((SKIPPED + 1))
56+
continue
57+
fi
58+
59+
TITLE=$(echo "$PR_METADATA" | jq -r '.title // empty')
60+
BODY=$(echo "$PR_METADATA" | jq -r '.body // empty')
61+
if ! echo "$TITLE
62+
$BODY" | grep -qiE "$L1_RE"; then
63+
echo " Skipped: missing L1 TRACEABILITY issue reference"
64+
SKIPPED=$((SKIPPED + 1))
65+
continue
66+
fi
67+
68+
# Review gate: require at least one APPROVED review.
69+
APPROVED_REVIEWS=$(echo "$PR_METADATA" | jq '[.reviews[]? | select(.state == "APPROVED")] | length')
70+
if [ "$APPROVED_REVIEWS" = "0" ]; then
71+
echo " Skipped: no approved review"
72+
SKIPPED=$((SKIPPED + 1))
73+
continue
74+
fi
4675

47-
FAILING=$(echo "$MAIN_CHECKS" | jq '[.[] | select(.conclusion != "SUCCESS" and .conclusion != "SKIPPED")] | length' 2>/dev/null || echo "1")
76+
MAIN_CHECKS=$(echo "$PR_METADATA" | jq \
77+
'[.statusCheckRollup[]? | select(.name != "NotebookLM Auto-Sync" and .name != ".github/workflows/notebook-sync.yml")]')
78+
FAILING=$(echo "$MAIN_CHECKS" | jq '[.[] | select(.conclusion != "SUCCESS" and .conclusion != "SKIPPED")] | length')
4879

49-
echo "PR #$pr: $FAILING failing checks"
80+
echo " Failing checks: $FAILING | Approved reviews: $APPROVED_REVIEWS"
5081

5182
if [ "$FAILING" = "0" ]; then
5283
READY_PRS+=("$pr")
5384
echo " Ready to merge"
5485
else
55-
echo " Skipped ($FAILING failing)"
86+
echo " Skipped ($FAILING failing checks)"
87+
SKIPPED=$((SKIPPED + 1))
5688
fi
5789
done
5890

5991
echo "ready_prs=${READY_PRS[*]}" >> $GITHUB_OUTPUT
6092
echo "count=${#READY_PRS[@]}" >> $GITHUB_OUTPUT
93+
echo "skipped=$SKIPPED" >> $GITHUB_OUTPUT
6194

6295
- name: Dry Run Check
63-
if: inputs.dry_run == 'true'
96+
if: inputs.dry_run
6497
run: |
6598
echo "DRY RUN - No actual merges will occur"
6699
echo "Ready PRs: ${{ steps.find-ready.outputs.count }}"
100+
echo "Skipped PRs: ${{ steps.find-ready.outputs.skipped }}"
67101
echo "PRs: ${{ steps.find-ready.outputs.ready_prs }}"
68102
exit 0
69103
70104
- name: Merge Ready PRs
71-
if: steps.find-ready.outputs.count != '0'
105+
if: ${{ steps.find-ready.outputs.count != '0' && !inputs.dry_run }}
72106
env:
73107
GH_TOKEN: ${{ github.token }}
74108
run: |
@@ -84,4 +118,5 @@ jobs:
84118
run: |
85119
echo "## Summary"
86120
echo ""
87-
echo "**PRs processed:** ${{ steps.find-ready.outputs.count }}"
121+
echo "**PRs merged/ready:** ${{ steps.find-ready.outputs.count }}"
122+
echo "**PRs skipped:** ${{ steps.find-ready.outputs.skipped }}"

.github/workflows/brain-seal-refresh.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ on:
88
- 'scripts/aggregate-experience.sh'
99
workflow_dispatch:
1010

11+
permissions:
12+
contents: write
13+
1114
jobs:
1215
refresh-brain-seals:
1316
runs-on: ubuntu-latest
@@ -43,10 +46,15 @@ jobs:
4346
path: .trinity/seals/brain_*.json
4447

4548
- name: Commit brain seals
49+
env:
50+
GH_TOKEN: ${{ github.token }}
4651
run: |
47-
git config --local user.email "admin@t27.ai"
52+
git config --local user.email "t27-bot@trinity.ai"
4853
git config --local user.name "T27 Autonomous Agent"
4954
git add .trinity/seals/brain_*.json
50-
git diff --staged --quiet || echo "No changes to commit"
51-
git commit -m "chore: refresh brain seals from experience aggregation" || echo "Nothing to commit"
55+
if git diff --staged --quiet; then
56+
echo "No brain seal changes to commit"
57+
exit 0
58+
fi
59+
git commit -m "chore: refresh brain seals from experience aggregation (Refs #1440)"
5260
git push

.trinity/current_task/activity.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,3 +1504,11 @@
15041504
- **Commit:**
15051505
- **Files:** .trinity/audit/igla-loop-state.json
15061506

1507+
## 2026-07-07T11:58:01Z — igla/w470-auto-workflow-harden
1508+
- **Commit:**
1509+
- **Files:** .github/workflows/auto-merge-ready-prs.yml,.github/workflows/brain-seal-refresh.yml,scripts/auto-close-prs.sh,scripts/auto-merge.sh
1510+
1511+
## 2026-07-07T12:14:42Z — igla/w470-auto-workflow-harden
1512+
- **Commit:**
1513+
- **Files:** docs/NOW.md
1514+

docs/NOW.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ Last updated: 2026-07-07
1212
- Completed: worktree cleanup (#1442); salvaged compiler postfix-array change to `salvage/ae9fe-postfix-array-notation`.
1313
- Blocked: W469 2D-struct-array Verilog lowering (#1443, blocked on `wave-loop-469`); Digilent FTDI `cli/dlc10` support (#1446, blocked on hardware access).
1414

15+
## IGLA cycle 1 — auto-workflow hardening (Closes #1440)
16+
17+
- PR #1441 hardens `.github/workflows/auto-merge-ready-prs.yml` and
18+
`.github/workflows/brain-seal-refresh.yml` with explicit permissions,
19+
L1 traceability gating, correct dry-run boolean handling, and change-detection
20+
guards before `git commit`.
21+
- This closes issue #1440 (automated workflows could merge/commit without
22+
issue linkage or review).
23+
1524
## Architecture — ADR-007 documents de-jure/de-facto split for generated .v in specs/ (Closes #1435)
1625

1726
- Fact-check on HEAD 6c704801: specs/**/*.v = 61 files, gen/**/*.v = 33. Issues

scripts/auto-close-prs.sh

Lines changed: 0 additions & 57 deletions
This file was deleted.

scripts/auto-merge.sh

Lines changed: 0 additions & 86 deletions
This file was deleted.

0 commit comments

Comments
 (0)