jonah-fleet 1.8.0 → 1.9.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/CHANGELOG.md +52 -0
- package/README.md +3 -3
- package/dist/commands/labels.d.ts +1 -1
- package/dist/commands/labels.d.ts.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/telemetry.d.ts.map +1 -1
- package/dist/index.js +666 -151
- package/dist/lib/daemon-keys.d.ts.map +1 -1
- package/dist/lib/daemon.d.ts.map +1 -1
- package/dist/lib/fleet-query.d.ts.map +1 -1
- package/dist/lib/labels.d.ts +20 -0
- package/dist/lib/labels.d.ts.map +1 -1
- package/dist/lib/manifest.d.ts.map +1 -1
- package/dist/lib/presets.d.ts +6 -1
- package/dist/lib/presets.d.ts.map +1 -1
- package/dist/lib/runner.d.ts +48 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/telemetry.d.ts.map +1 -1
- package/dist/lib/terminal-card.d.ts +15 -1
- package/dist/lib/terminal-card.d.ts.map +1 -1
- package/package.json +1 -1
- package/schema.json +10 -5
- package/templates/prompts/ORCHESTRATION.md +49 -11
- package/templates/prompts/_prompt-template.md +10 -13
- package/templates/prompts/analytics-review.md +4 -2
- package/templates/prompts/autowork.md +43 -12
- package/templates/prompts/dependency-update-security-check.md +4 -2
- package/templates/prompts/design-review.md +125 -0
- package/templates/prompts/issues-housekeeping.md +9 -7
- package/templates/prompts/optimizer.md +31 -12
- package/templates/prompts/peer-review.md +29 -4
- package/templates/prompts/product-planning.md +14 -10
- package/templates/workflows/autowork-cron.yml +99 -39
- package/templates/workflows/dependency-check-cron.yml +89 -3
- package/templates/workflows/design-review-cron.yml +221 -0
- package/templates/workflows/issues-housekeeping-cron.yml +89 -3
- package/templates/workflows/prompt-optimizer-cron.yml +96 -10
- package/templates/workflows/sync-fleet.yml +4 -0
- package/templates/workflows/trigger-autowork-manual.yml +116 -12
- package/templates/workflows/trigger-autowork-on-bug.yml +135 -5
- package/templates/workflows/trigger-autowork-on-merge.yml +135 -5
- package/templates/workflows/trigger-review-routine.yml +119 -18
|
@@ -13,7 +13,7 @@ jobs:
|
|
|
13
13
|
group: autowork-bug-${{ github.event.issue.number }}
|
|
14
14
|
cancel-in-progress: true
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
|
-
timeout-minutes:
|
|
16
|
+
timeout-minutes: 70
|
|
17
17
|
permissions:
|
|
18
18
|
contents: write
|
|
19
19
|
issues: write
|
|
@@ -26,7 +26,7 @@ jobs:
|
|
|
26
26
|
with:
|
|
27
27
|
fetch-depth: 0
|
|
28
28
|
token: ${{ secrets.GH_PAT || github.token }}
|
|
29
|
-
|
|
29
|
+
persist-credentials: false
|
|
30
30
|
|
|
31
31
|
- name: Setup Node.js
|
|
32
32
|
uses: actions/setup-node@v4
|
|
@@ -34,10 +34,13 @@ jobs:
|
|
|
34
34
|
node-version: 22
|
|
35
35
|
|
|
36
36
|
- name: Configure Git author identity
|
|
37
|
+
env:
|
|
38
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
37
39
|
run: |
|
|
38
40
|
git config --global user.name "github-actions[bot]"
|
|
39
41
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
40
42
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
43
|
+
gh auth setup-git
|
|
41
44
|
|
|
42
45
|
- name: Cache Antigravity CLI
|
|
43
46
|
id: cache-agy
|
|
@@ -84,7 +87,7 @@ jobs:
|
|
|
84
87
|
id: routine-config
|
|
85
88
|
run: |
|
|
86
89
|
ROUTINE="autowork"
|
|
87
|
-
DEFAULT_MODEL="gemini-3.
|
|
90
|
+
DEFAULT_MODEL="gemini-3.8-flash-high"
|
|
88
91
|
DEFAULT_TIMEOUT="60"
|
|
89
92
|
|
|
90
93
|
MODEL="$DEFAULT_MODEL"
|
|
@@ -119,6 +122,32 @@ jobs:
|
|
|
119
122
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
120
123
|
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
121
124
|
|
|
125
|
+
- name: Initialize Routine Run Issue
|
|
126
|
+
id: run-issue
|
|
127
|
+
env:
|
|
128
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
129
|
+
ISSUE_NUM: ${{ github.event.issue.number }}
|
|
130
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
131
|
+
RUN_ID: ${{ github.run_id }}
|
|
132
|
+
SERVER_URL: ${{ github.server_url }}
|
|
133
|
+
REPOSITORY: ${{ github.repository }}
|
|
134
|
+
run: |
|
|
135
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
136
|
+
TITLE="[autowork] run ${TIMESTAMP} (Issue #${ISSUE_NUM})"
|
|
137
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
138
|
+
- **Routine**: \`autowork\`
|
|
139
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
140
|
+
- **Trigger**: \`${EVENT_NAME}\` (High-priority bug)
|
|
141
|
+
- **Target**: Issue #${ISSUE_NUM}
|
|
142
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
146
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:autowork,status:running,runner:github-actions")
|
|
147
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
148
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
149
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
150
|
+
|
|
122
151
|
- name: Run Autowork
|
|
123
152
|
timeout-minutes: 60
|
|
124
153
|
env:
|
|
@@ -127,7 +156,10 @@ jobs:
|
|
|
127
156
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
128
157
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
129
158
|
TARGET_ISSUE: ${{ github.event.issue.number }}
|
|
159
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
130
160
|
SKILLS_PROMPT: ${{ steps.skills.outputs.skills_prompt }}
|
|
161
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-high' }}
|
|
162
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '60m' }}
|
|
131
163
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
132
164
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
133
165
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -135,7 +167,105 @@ jobs:
|
|
|
135
167
|
PROMPT="You are the Autowork routine for this repository. A high-priority bug was filed. Read and follow .github/prompts/autowork.md. ${SKILLS_PROMPT} Your target is issue #${TARGET_ISSUE}. You are in Targeted mode: work issue #${TARGET_ISSUE} directly."
|
|
136
168
|
|
|
137
169
|
agy -p "$PROMPT" \
|
|
138
|
-
--model "$
|
|
170
|
+
--model "$MODEL" \
|
|
139
171
|
--output-format text \
|
|
140
|
-
--print-timeout "$
|
|
172
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
141
173
|
--dangerously-skip-permissions
|
|
174
|
+
|
|
175
|
+
- name: Emit run summary
|
|
176
|
+
if: always()
|
|
177
|
+
run: |
|
|
178
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
179
|
+
if [ -f "$REPORT_FILE" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
|
|
180
|
+
cat "$REPORT_FILE" >> "$GITHUB_STEP_SUMMARY"
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
- name: Emit Fleet Telemetry (Opt-in)
|
|
184
|
+
if: always()
|
|
185
|
+
env:
|
|
186
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
187
|
+
TELEMETRY_ENDPOINT: ${{ secrets.JONAH_FLEET_TELEMETRY_ENDPOINT }}
|
|
188
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
189
|
+
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
190
|
+
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
191
|
+
run: |
|
|
192
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
193
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
194
|
+
npx --yes jonah-fleet telemetry --emit --log "$REPORT_FILE" --endpoint "$TELEMETRY_ENDPOINT" || true
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
- name: Verify Atomic Handoff Invariant (PR Existence Guard)
|
|
198
|
+
if: always()
|
|
199
|
+
env:
|
|
200
|
+
GH_TOKEN: ${{ github.token }}
|
|
201
|
+
run: |
|
|
202
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
203
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
204
|
+
if grep -q "Result.*SUCCESS" "$REPORT_FILE"; then
|
|
205
|
+
WORKED_BRANCH=$(grep -E '^\s*-\s*(Pushed branch|Branch):' "$REPORT_FILE" | head -n 1 | sed -E 's/.*`([^`]+)`.*/\1/')
|
|
206
|
+
if [ -n "$WORKED_BRANCH" ] && [[ "$WORKED_BRANCH" =~ (feat|fix)/ ]]; then
|
|
207
|
+
echo "Verifying PR existence for branch: $WORKED_BRANCH"
|
|
208
|
+
PR_COUNT=$(gh pr list --head "$WORKED_BRANCH" --state all --json number --jq 'length' 2>/dev/null || echo "0")
|
|
209
|
+
if [ "$PR_COUNT" -eq 0 ]; then
|
|
210
|
+
echo "::error::Atomic Handoff Invariant Violated: Branch '$WORKED_BRANCH' was implemented and pushed, but no pull request exists on GitHub!" >&2
|
|
211
|
+
exit 1
|
|
212
|
+
fi
|
|
213
|
+
echo "✓ Verified pull request exists on GitHub for branch: $WORKED_BRANCH"
|
|
214
|
+
fi
|
|
215
|
+
fi
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
- name: Reconcile Routine Run Issue
|
|
219
|
+
if: always()
|
|
220
|
+
env:
|
|
221
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
222
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
223
|
+
JOB_STATUS: ${{ job.status }}
|
|
224
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
225
|
+
RUN_ID: ${{ github.run_id }}
|
|
226
|
+
SERVER_URL: ${{ github.server_url }}
|
|
227
|
+
REPOSITORY: ${{ github.repository }}
|
|
228
|
+
run: |
|
|
229
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
230
|
+
echo "No routine issue to reconcile."
|
|
231
|
+
exit 0
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
235
|
+
|
|
236
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
237
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
238
|
+
else
|
|
239
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
240
|
+
- **Routine**: \`autowork\`
|
|
241
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
242
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
249
|
+
|
|
250
|
+
TEMP_BODY=$(mktemp)
|
|
251
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
252
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
253
|
+
rm -f "$TEMP_BODY"
|
|
254
|
+
|
|
255
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
256
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
257
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
258
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
259
|
+
else
|
|
260
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
261
|
+
- **Routine**: \`autowork\`
|
|
262
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
263
|
+
- **Step**: Actions execution halted before normal completion
|
|
264
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
268
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
269
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
270
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
271
|
+
fi
|
|
@@ -14,7 +14,7 @@ jobs:
|
|
|
14
14
|
group: autowork-merge-pr-${{ github.event.pull_request.number }}
|
|
15
15
|
cancel-in-progress: true
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
|
-
timeout-minutes:
|
|
17
|
+
timeout-minutes: 70
|
|
18
18
|
permissions:
|
|
19
19
|
contents: write
|
|
20
20
|
issues: write
|
|
@@ -49,7 +49,7 @@ jobs:
|
|
|
49
49
|
with:
|
|
50
50
|
fetch-depth: 0
|
|
51
51
|
token: ${{ secrets.GH_PAT || github.token }}
|
|
52
|
-
|
|
52
|
+
persist-credentials: false
|
|
53
53
|
|
|
54
54
|
- name: Setup Node.js
|
|
55
55
|
if: steps.pick.outputs.skip != 'true'
|
|
@@ -59,10 +59,13 @@ jobs:
|
|
|
59
59
|
|
|
60
60
|
- name: Configure Git author identity
|
|
61
61
|
if: steps.pick.outputs.skip != 'true'
|
|
62
|
+
env:
|
|
63
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
62
64
|
run: |
|
|
63
65
|
git config --global user.name "github-actions[bot]"
|
|
64
66
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
65
67
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
68
|
+
gh auth setup-git
|
|
66
69
|
|
|
67
70
|
- name: Cache Antigravity CLI
|
|
68
71
|
if: steps.pick.outputs.skip != 'true'
|
|
@@ -114,7 +117,7 @@ jobs:
|
|
|
114
117
|
id: routine-config
|
|
115
118
|
run: |
|
|
116
119
|
ROUTINE="autowork"
|
|
117
|
-
DEFAULT_MODEL="gemini-3.
|
|
120
|
+
DEFAULT_MODEL="gemini-3.8-flash-high"
|
|
118
121
|
DEFAULT_TIMEOUT="60"
|
|
119
122
|
|
|
120
123
|
MODEL="$DEFAULT_MODEL"
|
|
@@ -149,6 +152,32 @@ jobs:
|
|
|
149
152
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
150
153
|
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
151
154
|
|
|
155
|
+
- name: Initialize Routine Run Issue
|
|
156
|
+
if: steps.pick.outputs.skip != 'true'
|
|
157
|
+
id: run-issue
|
|
158
|
+
env:
|
|
159
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
160
|
+
PR_NUM: ${{ github.event.pull_request.number }}
|
|
161
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
162
|
+
RUN_ID: ${{ github.run_id }}
|
|
163
|
+
SERVER_URL: ${{ github.server_url }}
|
|
164
|
+
REPOSITORY: ${{ github.repository }}
|
|
165
|
+
run: |
|
|
166
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
167
|
+
TITLE="[autowork] run ${TIMESTAMP} (on PR #${PR_NUM} merge)"
|
|
168
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
169
|
+
- **Routine**: \`autowork\`
|
|
170
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
171
|
+
- **Trigger**: \`${EVENT_NAME}\` (PR #${PR_NUM} merged)
|
|
172
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
176
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:autowork,status:running,runner:github-actions")
|
|
177
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
178
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
179
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
180
|
+
|
|
152
181
|
- name: Run Autowork
|
|
153
182
|
if: steps.pick.outputs.skip != 'true'
|
|
154
183
|
timeout-minutes: 60
|
|
@@ -157,7 +186,10 @@ jobs:
|
|
|
157
186
|
GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
158
187
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
159
188
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
189
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
160
190
|
SKILLS_PROMPT: ${{ steps.skills.outputs.skills_prompt }}
|
|
191
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-high' }}
|
|
192
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '60m' }}
|
|
161
193
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
162
194
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
163
195
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -165,7 +197,105 @@ jobs:
|
|
|
165
197
|
PROMPT="You are the Autowork routine for this repository. A PR was recently merged. Read and follow .github/prompts/autowork.md. ${SKILLS_PROMPT} You are in Scan mode: converge on open PRs, close merged issues, and pick the next unblocked priority issue."
|
|
166
198
|
|
|
167
199
|
agy -p "$PROMPT" \
|
|
168
|
-
--model "$
|
|
200
|
+
--model "$MODEL" \
|
|
169
201
|
--output-format text \
|
|
170
|
-
--print-timeout "$
|
|
202
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
171
203
|
--dangerously-skip-permissions
|
|
204
|
+
|
|
205
|
+
- name: Emit run summary
|
|
206
|
+
if: always() && steps.pick.outputs.skip != 'true'
|
|
207
|
+
run: |
|
|
208
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
209
|
+
if [ -f "$REPORT_FILE" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
|
|
210
|
+
cat "$REPORT_FILE" >> "$GITHUB_STEP_SUMMARY"
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
- name: Emit Fleet Telemetry (Opt-in)
|
|
214
|
+
if: always() && steps.pick.outputs.skip != 'true'
|
|
215
|
+
env:
|
|
216
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
217
|
+
TELEMETRY_ENDPOINT: ${{ secrets.JONAH_FLEET_TELEMETRY_ENDPOINT }}
|
|
218
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
219
|
+
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
220
|
+
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
221
|
+
run: |
|
|
222
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
223
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
224
|
+
npx --yes jonah-fleet telemetry --emit --log "$REPORT_FILE" --endpoint "$TELEMETRY_ENDPOINT" || true
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
- name: Verify Atomic Handoff Invariant (PR Existence Guard)
|
|
228
|
+
if: always() && steps.pick.outputs.skip != 'true'
|
|
229
|
+
env:
|
|
230
|
+
GH_TOKEN: ${{ github.token }}
|
|
231
|
+
run: |
|
|
232
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
233
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
234
|
+
if grep -q "Result.*SUCCESS" "$REPORT_FILE"; then
|
|
235
|
+
WORKED_BRANCH=$(grep -E '^\s*-\s*(Pushed branch|Branch):' "$REPORT_FILE" | head -n 1 | sed -E 's/.*`([^`]+)`.*/\1/')
|
|
236
|
+
if [ -n "$WORKED_BRANCH" ] && [[ "$WORKED_BRANCH" =~ (feat|fix)/ ]]; then
|
|
237
|
+
echo "Verifying PR existence for branch: $WORKED_BRANCH"
|
|
238
|
+
PR_COUNT=$(gh pr list --head "$WORKED_BRANCH" --state all --json number --jq 'length' 2>/dev/null || echo "0")
|
|
239
|
+
if [ "$PR_COUNT" -eq 0 ]; then
|
|
240
|
+
echo "::error::Atomic Handoff Invariant Violated: Branch '$WORKED_BRANCH' was implemented and pushed, but no pull request exists on GitHub!" >&2
|
|
241
|
+
exit 1
|
|
242
|
+
fi
|
|
243
|
+
echo "✓ Verified pull request exists on GitHub for branch: $WORKED_BRANCH"
|
|
244
|
+
fi
|
|
245
|
+
fi
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
- name: Reconcile Routine Run Issue
|
|
249
|
+
if: always() && steps.pick.outputs.skip != 'true'
|
|
250
|
+
env:
|
|
251
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
252
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
253
|
+
JOB_STATUS: ${{ job.status }}
|
|
254
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
255
|
+
RUN_ID: ${{ github.run_id }}
|
|
256
|
+
SERVER_URL: ${{ github.server_url }}
|
|
257
|
+
REPOSITORY: ${{ github.repository }}
|
|
258
|
+
run: |
|
|
259
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
260
|
+
echo "No routine issue to reconcile."
|
|
261
|
+
exit 0
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
265
|
+
|
|
266
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
267
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
268
|
+
else
|
|
269
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
270
|
+
- **Routine**: \`autowork\`
|
|
271
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
272
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
279
|
+
|
|
280
|
+
TEMP_BODY=$(mktemp)
|
|
281
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
282
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
283
|
+
rm -f "$TEMP_BODY"
|
|
284
|
+
|
|
285
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
286
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
287
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
288
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
289
|
+
else
|
|
290
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
291
|
+
- **Routine**: \`autowork\`
|
|
292
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
293
|
+
- **Step**: Actions execution halted before normal completion
|
|
294
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
298
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
299
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
300
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
301
|
+
fi
|
|
@@ -3,8 +3,6 @@ name: Trigger Review Routine
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
5
5
|
types: [ready_for_review, opened, reopened, synchronize, review_requested]
|
|
6
|
-
paths-ignore:
|
|
7
|
-
- '.github/prompts/logs/**'
|
|
8
6
|
schedule:
|
|
9
7
|
# Periodic scan sweep every 2 hours to catch and recover any orphaned or unreviewed ready PRs
|
|
10
8
|
- cron: '45 */2 * * *'
|
|
@@ -42,7 +40,7 @@ jobs:
|
|
|
42
40
|
group: review-routine-pr-${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number || 'scan' }}
|
|
43
41
|
cancel-in-progress: true
|
|
44
42
|
runs-on: ubuntu-latest
|
|
45
|
-
timeout-minutes:
|
|
43
|
+
timeout-minutes: 65
|
|
46
44
|
permissions:
|
|
47
45
|
contents: write
|
|
48
46
|
actions: read
|
|
@@ -55,12 +53,14 @@ jobs:
|
|
|
55
53
|
env:
|
|
56
54
|
GH_TOKEN: ${{ github.token }}
|
|
57
55
|
PR_NUM: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
|
|
56
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
57
|
+
REPOSITORY: ${{ github.repository }}
|
|
58
58
|
run: |
|
|
59
59
|
if [ -z "$PR_NUM" ]; then
|
|
60
|
-
if [ "$
|
|
61
|
-
open_prs=$(gh api "repos/${
|
|
60
|
+
if [ "$EVENT_NAME" = "schedule" ]; then
|
|
61
|
+
open_prs=$(gh api "repos/${REPOSITORY}/pulls?state=open&per_page=1" --jq 'length' 2>/dev/null || echo "0")
|
|
62
62
|
if [ "$open_prs" -eq "0" ]; then
|
|
63
|
-
echo "No open PRs found in ${
|
|
63
|
+
echo "No open PRs found in ${REPOSITORY} — skipping scheduled review routine scan."
|
|
64
64
|
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
65
65
|
exit 0
|
|
66
66
|
fi
|
|
@@ -86,7 +86,7 @@ jobs:
|
|
|
86
86
|
return 1
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
if ! pr=$(gh_api_retry "repos/${
|
|
89
|
+
if ! pr=$(gh_api_retry "repos/${REPOSITORY}/pulls/${PR_NUM}"); then
|
|
90
90
|
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
91
91
|
exit 0
|
|
92
92
|
fi
|
|
@@ -109,7 +109,7 @@ jobs:
|
|
|
109
109
|
# Strict allowlist: only trigger immediate cloud review if explicitly labeled priority/P0 or priority/P1.
|
|
110
110
|
# Untagged PRs and lower-priority PRs (P2/P3) skip immediate cloud review and are handled by local peer-review daemons
|
|
111
111
|
# (cloud scheduled watchdog sweep will catch up if unreviewed > 48h).
|
|
112
|
-
if [ "$
|
|
112
|
+
if [ "$EVENT_NAME" = "pull_request" ]; then
|
|
113
113
|
labels=$(echo "$pr" | jq -r '.labels[].name' 2>/dev/null || echo "")
|
|
114
114
|
if ! echo "$labels" | grep -qE '^priority/P[01]$'; then
|
|
115
115
|
echo "PR is not explicitly labeled priority/P0 or priority/P1 — skipping immediate cloud review for local peer-review daemon."
|
|
@@ -125,6 +125,7 @@ jobs:
|
|
|
125
125
|
uses: actions/checkout@v4
|
|
126
126
|
with:
|
|
127
127
|
fetch-depth: 0
|
|
128
|
+
persist-credentials: false
|
|
128
129
|
|
|
129
130
|
- name: Setup Node.js
|
|
130
131
|
if: steps.guard.outputs.skip != 'true'
|
|
@@ -134,10 +135,13 @@ jobs:
|
|
|
134
135
|
|
|
135
136
|
- name: Configure Git author identity
|
|
136
137
|
if: steps.guard.outputs.skip != 'true'
|
|
138
|
+
env:
|
|
139
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
137
140
|
run: |
|
|
138
141
|
git config --global user.name "github-actions[bot]"
|
|
139
142
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
140
143
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
144
|
+
gh auth setup-git
|
|
141
145
|
|
|
142
146
|
- name: Cache Antigravity CLI
|
|
143
147
|
if: steps.guard.outputs.skip != 'true'
|
|
@@ -175,7 +179,7 @@ jobs:
|
|
|
175
179
|
id: routine-config
|
|
176
180
|
run: |
|
|
177
181
|
ROUTINE="peer-review"
|
|
178
|
-
DEFAULT_MODEL="gemini-3.
|
|
182
|
+
DEFAULT_MODEL="gemini-3.8-flash-high"
|
|
179
183
|
DEFAULT_TIMEOUT="55"
|
|
180
184
|
|
|
181
185
|
MODEL="$DEFAULT_MODEL"
|
|
@@ -210,6 +214,36 @@ jobs:
|
|
|
210
214
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
211
215
|
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
212
216
|
|
|
217
|
+
- name: Initialize Routine Run Issue
|
|
218
|
+
if: steps.guard.outputs.skip != 'true'
|
|
219
|
+
id: run-issue
|
|
220
|
+
env:
|
|
221
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
222
|
+
PR_ARG: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
|
|
223
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
224
|
+
RUN_ID: ${{ github.run_id }}
|
|
225
|
+
SERVER_URL: ${{ github.server_url }}
|
|
226
|
+
REPOSITORY: ${{ github.repository }}
|
|
227
|
+
run: |
|
|
228
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
229
|
+
if [ -n "$PR_ARG" ]; then
|
|
230
|
+
TITLE="[peer-review] run ${TIMESTAMP} (PR #${PR_ARG})"
|
|
231
|
+
else
|
|
232
|
+
TITLE="[peer-review] run ${TIMESTAMP}"
|
|
233
|
+
fi
|
|
234
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
235
|
+
- **Routine**: \`peer-review\`
|
|
236
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
237
|
+
- **Trigger**: \`${EVENT_NAME}\`
|
|
238
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
242
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:peer-review,status:running,runner:github-actions")
|
|
243
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
244
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
245
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
246
|
+
|
|
213
247
|
- name: Run Peer Review
|
|
214
248
|
if: steps.guard.outputs.skip != 'true'
|
|
215
249
|
timeout-minutes: 55
|
|
@@ -220,6 +254,9 @@ jobs:
|
|
|
220
254
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
221
255
|
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
|
|
222
256
|
PR_URL: ${{ github.event.pull_request.html_url || github.event.issue.html_url }}
|
|
257
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
258
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-high' }}
|
|
259
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '55m' }}
|
|
223
260
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
224
261
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
225
262
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -233,10 +270,14 @@ jobs:
|
|
|
233
270
|
PROMPT="You are the Peer Review routine for this repository. Read and follow the instructions in .github/prompts/peer-review.md exactly. You are in Scan mode: check open PRs and select the highest-priority PR to review."
|
|
234
271
|
fi
|
|
235
272
|
|
|
273
|
+
if [ -n "$ROUTINE_ISSUE_NUMBER" ]; then
|
|
274
|
+
PROMPT="$PROMPT Tracking run log issue: #${ROUTINE_ISSUE_NUMBER}."
|
|
275
|
+
fi
|
|
276
|
+
|
|
236
277
|
agy -p "$PROMPT" \
|
|
237
|
-
--model "$
|
|
278
|
+
--model "$MODEL" \
|
|
238
279
|
--output-format text \
|
|
239
|
-
--print-timeout "$
|
|
280
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
240
281
|
--dangerously-skip-permissions
|
|
241
282
|
|
|
242
283
|
- name: Handle Review Failure & PR Notification
|
|
@@ -244,12 +285,17 @@ jobs:
|
|
|
244
285
|
env:
|
|
245
286
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
246
287
|
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
|
|
288
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
247
289
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
248
290
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
249
291
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
250
292
|
run: |
|
|
251
293
|
if [ -n "$PR_NUMBER" ]; then
|
|
252
|
-
|
|
294
|
+
LOG_REF=""
|
|
295
|
+
if [ -n "$ROUTINE_ISSUE_NUMBER" ]; then
|
|
296
|
+
LOG_REF=" · [Run Log #${ROUTINE_ISSUE_NUMBER}](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/issues/${ROUTINE_ISSUE_NUMBER})"
|
|
297
|
+
fi
|
|
298
|
+
gh pr comment "$PR_NUMBER" --body "⚠️ **Peer Review Routine Notice**: The automated review session encountered an execution error (e.g., API rate/quota limit or runner interruption)${LOG_REF}. The review will be retried automatically on the next scheduled scan sweep or can be re-triggered immediately by commenting \`/review\` on this PR.
|
|
253
299
|
|
|
254
300
|
_Generated by [Antigravity](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})_" || true
|
|
255
301
|
fi
|
|
@@ -257,9 +303,9 @@ jobs:
|
|
|
257
303
|
- name: Emit run summary
|
|
258
304
|
if: always() && steps.guard.outputs.skip != 'true'
|
|
259
305
|
run: |
|
|
260
|
-
|
|
261
|
-
if [ -
|
|
262
|
-
cat "$
|
|
306
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
307
|
+
if [ -f "$REPORT_FILE" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
|
|
308
|
+
cat "$REPORT_FILE" >> "$GITHUB_STEP_SUMMARY"
|
|
263
309
|
fi
|
|
264
310
|
|
|
265
311
|
- name: Emit Fleet Telemetry (Opt-in)
|
|
@@ -271,7 +317,62 @@ jobs:
|
|
|
271
317
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
272
318
|
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
273
319
|
run: |
|
|
274
|
-
|
|
275
|
-
if [ -
|
|
276
|
-
npx --yes jonah-fleet telemetry --emit --log "$
|
|
320
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
321
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
322
|
+
npx --yes jonah-fleet telemetry --emit --log "$REPORT_FILE" --endpoint "$TELEMETRY_ENDPOINT" || true
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
- name: Reconcile Routine Run Issue
|
|
326
|
+
if: always() && steps.guard.outputs.skip != 'true'
|
|
327
|
+
env:
|
|
328
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
329
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
330
|
+
JOB_STATUS: ${{ job.status }}
|
|
331
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
332
|
+
RUN_ID: ${{ github.run_id }}
|
|
333
|
+
SERVER_URL: ${{ github.server_url }}
|
|
334
|
+
REPOSITORY: ${{ github.repository }}
|
|
335
|
+
run: |
|
|
336
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
337
|
+
echo "No routine issue to reconcile."
|
|
338
|
+
exit 0
|
|
339
|
+
fi
|
|
340
|
+
|
|
341
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
342
|
+
|
|
343
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
344
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
345
|
+
else
|
|
346
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
347
|
+
- **Routine**: \`peer-review\`
|
|
348
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
349
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
350
|
+
fi
|
|
351
|
+
|
|
352
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
356
|
+
|
|
357
|
+
TEMP_BODY=$(mktemp)
|
|
358
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
359
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
360
|
+
rm -f "$TEMP_BODY"
|
|
361
|
+
|
|
362
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
363
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
364
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
365
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
366
|
+
else
|
|
367
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
368
|
+
- **Routine**: \`peer-review\`
|
|
369
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
370
|
+
- **Step**: Actions execution halted before normal completion
|
|
371
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
375
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
376
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
377
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
277
378
|
fi
|