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.
Files changed (43) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +3 -3
  3. package/dist/commands/labels.d.ts +1 -1
  4. package/dist/commands/labels.d.ts.map +1 -1
  5. package/dist/commands/status.d.ts.map +1 -1
  6. package/dist/commands/sync.d.ts.map +1 -1
  7. package/dist/commands/telemetry.d.ts.map +1 -1
  8. package/dist/index.js +666 -151
  9. package/dist/lib/daemon-keys.d.ts.map +1 -1
  10. package/dist/lib/daemon.d.ts.map +1 -1
  11. package/dist/lib/fleet-query.d.ts.map +1 -1
  12. package/dist/lib/labels.d.ts +20 -0
  13. package/dist/lib/labels.d.ts.map +1 -1
  14. package/dist/lib/manifest.d.ts.map +1 -1
  15. package/dist/lib/presets.d.ts +6 -1
  16. package/dist/lib/presets.d.ts.map +1 -1
  17. package/dist/lib/runner.d.ts +48 -0
  18. package/dist/lib/runner.d.ts.map +1 -1
  19. package/dist/lib/telemetry.d.ts.map +1 -1
  20. package/dist/lib/terminal-card.d.ts +15 -1
  21. package/dist/lib/terminal-card.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/schema.json +10 -5
  24. package/templates/prompts/ORCHESTRATION.md +49 -11
  25. package/templates/prompts/_prompt-template.md +10 -13
  26. package/templates/prompts/analytics-review.md +4 -2
  27. package/templates/prompts/autowork.md +43 -12
  28. package/templates/prompts/dependency-update-security-check.md +4 -2
  29. package/templates/prompts/design-review.md +125 -0
  30. package/templates/prompts/issues-housekeeping.md +9 -7
  31. package/templates/prompts/optimizer.md +31 -12
  32. package/templates/prompts/peer-review.md +29 -4
  33. package/templates/prompts/product-planning.md +14 -10
  34. package/templates/workflows/autowork-cron.yml +99 -39
  35. package/templates/workflows/dependency-check-cron.yml +89 -3
  36. package/templates/workflows/design-review-cron.yml +221 -0
  37. package/templates/workflows/issues-housekeeping-cron.yml +89 -3
  38. package/templates/workflows/prompt-optimizer-cron.yml +96 -10
  39. package/templates/workflows/sync-fleet.yml +4 -0
  40. package/templates/workflows/trigger-autowork-manual.yml +116 -12
  41. package/templates/workflows/trigger-autowork-on-bug.yml +135 -5
  42. package/templates/workflows/trigger-autowork-on-merge.yml +135 -5
  43. 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: 35
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.7-flash-high"
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 "${{ steps.routine-config.outputs.model || 'gemini-3.7-flash-high' }}" \
170
+ --model "$MODEL" \
139
171
  --output-format text \
140
- --print-timeout "${{ steps.routine-config.outputs.print_timeout || '60m' }}" \
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: 35
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.7-flash-high"
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 "${{ steps.routine-config.outputs.model || 'gemini-3.7-flash-high' }}" \
200
+ --model "$MODEL" \
169
201
  --output-format text \
170
- --print-timeout "${{ steps.routine-config.outputs.print_timeout || '60m' }}" \
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: 35
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 [ "${{ github.event_name }}" = "schedule" ]; then
61
- open_prs=$(gh api "repos/${{ github.repository }}/pulls?state=open&per_page=1" --jq 'length' 2>/dev/null || echo "0")
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 ${{ github.repository }} — skipping scheduled review routine scan."
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/${{ github.repository }}/pulls/${PR_NUM}"); then
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 [ "${{ github.event_name }}" = "pull_request" ]; then
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.7-flash-high"
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 "${{ steps.routine-config.outputs.model || 'gemini-3.7-flash-high' }}" \
278
+ --model "$MODEL" \
238
279
  --output-format text \
239
- --print-timeout "${{ steps.routine-config.outputs.print_timeout || '55m' }}" \
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
- 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). The review will be retried automatically on the next scheduled scan sweep or can be re-triggered immediately by commenting \`/review\` on this PR.
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
- LATEST_LOG=$(ls -t .github/prompts/logs/peer-review/*.md 2>/dev/null | head -n 1)
261
- if [ -n "$LATEST_LOG" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
262
- cat "$LATEST_LOG" >> "$GITHUB_STEP_SUMMARY"
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
- LATEST_LOG=$(ls -t .github/prompts/logs/peer-review/*.md 2>/dev/null | head -n 1)
275
- if [ -n "$LATEST_LOG" ] && [ -f "$LATEST_LOG" ]; then
276
- npx --yes jonah-fleet telemetry --emit --log "$LATEST_LOG" --endpoint "$TELEMETRY_ENDPOINT" || true
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