jonah-fleet 1.2.0 → 1.4.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 (64) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +9 -2
  3. package/dist/commands/contribute.d.ts +29 -0
  4. package/dist/commands/contribute.d.ts.map +1 -0
  5. package/dist/commands/daemon.d.ts +10 -0
  6. package/dist/commands/daemon.d.ts.map +1 -0
  7. package/dist/commands/init.d.ts +13 -0
  8. package/dist/commands/init.d.ts.map +1 -0
  9. package/dist/commands/monitor.d.ts +16 -0
  10. package/dist/commands/monitor.d.ts.map +1 -0
  11. package/dist/commands/run.d.ts +11 -0
  12. package/dist/commands/run.d.ts.map +1 -0
  13. package/dist/commands/status.d.ts +9 -0
  14. package/dist/commands/status.d.ts.map +1 -0
  15. package/dist/commands/sync.d.ts +7 -0
  16. package/dist/commands/sync.d.ts.map +1 -0
  17. package/dist/commands/telemetry.d.ts +14 -0
  18. package/dist/commands/telemetry.d.ts.map +1 -0
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +1781 -120
  22. package/dist/lib/daemon.d.ts +42 -0
  23. package/dist/lib/daemon.d.ts.map +1 -0
  24. package/dist/lib/dashboard.d.ts +10 -0
  25. package/dist/lib/dashboard.d.ts.map +1 -0
  26. package/dist/lib/detector.d.ts +25 -0
  27. package/dist/lib/detector.d.ts.map +1 -0
  28. package/dist/lib/diff.d.ts +10 -0
  29. package/dist/lib/diff.d.ts.map +1 -0
  30. package/dist/lib/evals.d.ts +72 -0
  31. package/dist/lib/evals.d.ts.map +1 -0
  32. package/dist/lib/fleet-query.d.ts +102 -0
  33. package/dist/lib/fleet-query.d.ts.map +1 -0
  34. package/dist/lib/global-config.d.ts +10 -0
  35. package/dist/lib/global-config.d.ts.map +1 -0
  36. package/dist/lib/installer.d.ts +27 -0
  37. package/dist/lib/installer.d.ts.map +1 -0
  38. package/dist/lib/manifest.d.ts +6 -0
  39. package/dist/lib/manifest.d.ts.map +1 -0
  40. package/dist/lib/presets.d.ts +52 -0
  41. package/dist/lib/presets.d.ts.map +1 -0
  42. package/dist/lib/runner.d.ts +40 -0
  43. package/dist/lib/runner.d.ts.map +1 -0
  44. package/dist/lib/telemetry.d.ts +90 -0
  45. package/dist/lib/telemetry.d.ts.map +1 -0
  46. package/dist/lib/worktree.d.ts +34 -0
  47. package/dist/lib/worktree.d.ts.map +1 -0
  48. package/package.json +9 -5
  49. package/schema.json +44 -1
  50. package/templates/docs/AGENTS.template.md +15 -0
  51. package/templates/prompts/ORCHESTRATION.md +74 -3
  52. package/templates/prompts/analytics-review.md +91 -0
  53. package/templates/prompts/autowork.md +15 -4
  54. package/templates/prompts/issues-housekeeping.md +2 -1
  55. package/templates/prompts/optimizer.md +2 -0
  56. package/templates/prompts/peer-review.md +14 -5
  57. package/templates/prompts/product-planning.md +18 -7
  58. package/templates/skills/diagnosing-bugs/SKILL.md +9 -0
  59. package/templates/workflows/autowork-cron.yml +19 -1
  60. package/templates/workflows/prompt-optimizer-cron.yml +22 -0
  61. package/templates/workflows/trigger-autowork-manual.yml +169 -0
  62. package/templates/workflows/trigger-autowork-on-bug.yml +5 -5
  63. package/templates/workflows/trigger-autowork-on-merge.yml +3 -3
  64. package/templates/workflows/trigger-review-routine.yml +107 -11
@@ -0,0 +1,169 @@
1
+ name: Trigger Autowork Manually (Targeted)
2
+
3
+ # Manual execution of the Autowork routine on a specific issue via workflow_dispatch or badge link click.
4
+
5
+ on:
6
+ workflow_dispatch:
7
+ inputs:
8
+ issue_number:
9
+ description: 'Target issue number to work in Targeted mode (e.g. 18)'
10
+ required: true
11
+ type: string
12
+ mode:
13
+ description: 'Execution mode (targeted or scan)'
14
+ required: false
15
+ default: 'targeted'
16
+ type: choice
17
+ options:
18
+ - targeted
19
+ - scan
20
+ custom_prompt:
21
+ description: 'Optional custom instructions or overrides'
22
+ required: false
23
+ type: string
24
+
25
+ concurrency:
26
+ group: autowork-manual-${{ inputs.issue_number || github.run_id }}
27
+ cancel-in-progress: false
28
+
29
+ jobs:
30
+ run-autowork:
31
+ runs-on: ubuntu-latest
32
+ timeout-minutes: 65
33
+ permissions:
34
+ contents: write
35
+ issues: write
36
+ pull-requests: write
37
+ statuses: write
38
+ actions: read
39
+ steps:
40
+ - name: Checkout repository
41
+ uses: actions/checkout@v4
42
+ with:
43
+ fetch-depth: 0
44
+
45
+ - name: Setup Node.js
46
+ uses: actions/setup-node@v4
47
+ with:
48
+ node-version: 22
49
+
50
+ - name: Configure Git author identity
51
+ run: |
52
+ git config --global user.name "github-actions[bot]"
53
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
54
+ git config --global --add safe.directory "$GITHUB_WORKSPACE"
55
+
56
+ - name: Cache Antigravity CLI
57
+ id: cache-agy
58
+ uses: actions/cache@v4
59
+ with:
60
+ path: ~/.local/bin/agy
61
+ key: agy-cli-linux-amd64-v1
62
+
63
+ - name: Install Antigravity CLI
64
+ if: steps.cache-agy.outputs.cache-hit != 'true'
65
+ run: |
66
+ curl -fsSL https://antigravity.google/cli/install.sh | bash
67
+
68
+ - name: Add Antigravity CLI to PATH
69
+ run: echo "$HOME/.local/bin" >> $GITHUB_PATH
70
+
71
+ - name: Write Antigravity OAuth Token
72
+ env:
73
+ ANTIGRAVITY_OAUTH_TOKEN: ${{ secrets.ANTIGRAVITY_OAUTH_TOKEN || secrets.GEMINI_API_KEY }}
74
+ run: |
75
+ if [ -z "$ANTIGRAVITY_OAUTH_TOKEN" ]; then
76
+ echo "::error::Neither ANTIGRAVITY_OAUTH_TOKEN nor GEMINI_API_KEY secret is set; cannot authenticate Antigravity CLI." >&2
77
+ exit 1
78
+ fi
79
+ mkdir -p "$HOME/.gemini/antigravity-cli"
80
+ chmod 700 "$HOME/.gemini/antigravity-cli"
81
+ printf '%s' "$ANTIGRAVITY_OAUTH_TOKEN" > "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
82
+ chmod 600 "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
83
+
84
+ - name: Preflight validation
85
+ env:
86
+ GH_TOKEN: ${{ github.token }}
87
+ run: |
88
+ if [ ! -s "$HOME/.gemini/antigravity-cli/antigravity-oauth-token" ]; then
89
+ echo "::error::Preflight check failed: Antigravity OAuth token file is missing or empty." >&2
90
+ exit 1
91
+ fi
92
+ if ! gh auth status >/dev/null 2>&1; then
93
+ echo "::error::GitHub CLI authentication check failed with GITHUB_TOKEN." >&2
94
+ exit 1
95
+ fi
96
+ echo "✓ Preflight credential and GitHub CLI validation passed."
97
+
98
+ - name: Discover domain skills
99
+ id: skills
100
+ run: |
101
+ SKILLS_PROMPT=""
102
+ if [ -d ".agents/skills" ]; then
103
+ for skill_path in .agents/skills/*/SKILL.md; do
104
+ if [ -f "$skill_path" ]; then
105
+ SKILLS_PROMPT="${SKILLS_PROMPT}Read and follow ${skill_path}. "
106
+ fi
107
+ done
108
+ fi
109
+ echo "skills_prompt=$SKILLS_PROMPT" >> "$GITHUB_OUTPUT"
110
+
111
+ - name: Run Autowork
112
+ timeout-minutes: 60
113
+ env:
114
+ GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
115
+ GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
116
+ ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
117
+ GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
118
+ TARGET_ISSUE: ${{ inputs.issue_number }}
119
+ MODE: ${{ inputs.mode || 'targeted' }}
120
+ CUSTOM_PROMPT: ${{ inputs.custom_prompt }}
121
+ SKILLS_PROMPT: ${{ steps.skills.outputs.skills_prompt }}
122
+ GITHUB_SERVER_URL: ${{ github.server_url }}
123
+ GITHUB_REPOSITORY: ${{ github.repository }}
124
+ GITHUB_RUN_ID: ${{ github.run_id }}
125
+ run: |
126
+ if [ -n "$TARGET_ISSUE" ] && [ "$MODE" != "scan" ]; then
127
+ PROMPT="You are the Autowork routine for this repository. Read and follow the instructions in .github/prompts/autowork.md exactly. ${SKILLS_PROMPT} Your target is issue #${TARGET_ISSUE}. You are in Targeted mode: work issue #${TARGET_ISSUE} directly, ahead of Phase 1 convergence and priority scan."
128
+ else
129
+ PROMPT="You are the Autowork routine for this repository. Read and follow the instructions in .github/prompts/autowork.md exactly. ${SKILLS_PROMPT} You are in Scan mode: check open PRs for review comments to fix, close merged issues, then pick the highest-priority unclaimed issue."
130
+ fi
131
+
132
+ if [ -n "$CUSTOM_PROMPT" ]; then
133
+ PROMPT="${PROMPT} Additional instructions: ${CUSTOM_PROMPT}"
134
+ fi
135
+
136
+ agy -p "$PROMPT" \
137
+ --model gemini-3.7-flash-high \
138
+ --output-format text \
139
+ --print-timeout 60m \
140
+ --dangerously-skip-permissions
141
+
142
+ - name: Emit run summary
143
+ if: always()
144
+ run: |
145
+ LATEST_LOG=$(ls -t .github/prompts/logs/autowork/*.md 2>/dev/null | head -n 1)
146
+ if [ -n "$LATEST_LOG" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
147
+ cat "$LATEST_LOG" >> "$GITHUB_STEP_SUMMARY"
148
+ fi
149
+
150
+ - name: Verify Atomic Handoff Invariant (PR Existence Guard)
151
+ if: always()
152
+ env:
153
+ GH_TOKEN: ${{ github.token }}
154
+ run: |
155
+ LATEST_LOG=$(ls -t .github/prompts/logs/autowork/*.md 2>/dev/null | head -n 1)
156
+ if [ -n "$LATEST_LOG" ]; then
157
+ if grep -q "Result.*SUCCESS" "$LATEST_LOG"; then
158
+ WORKED_BRANCH=$(grep -E '^\s*-\s*(Pushed branch|Branch):' "$LATEST_LOG" | head -n 1 | sed -E 's/.*`([^`]+)`.*/\1/')
159
+ if [ -n "$WORKED_BRANCH" ] && [[ "$WORKED_BRANCH" =~ (feat|fix)/ ]]; then
160
+ echo "Verifying PR existence for branch: $WORKED_BRANCH"
161
+ PR_COUNT=$(gh pr list --head "$WORKED_BRANCH" --state all --json number --jq 'length' 2>/dev/null || echo "0")
162
+ if [ "$PR_COUNT" -eq 0 ]; then
163
+ echo "::error::Atomic Handoff Invariant Violated: Branch '$WORKED_BRANCH' was implemented and pushed, but no pull request exists on GitHub!" >&2
164
+ exit 1
165
+ fi
166
+ echo "✓ Verified pull request exists on GitHub for branch: $WORKED_BRANCH"
167
+ fi
168
+ fi
169
+ fi
@@ -11,10 +11,10 @@ concurrency:
11
11
  jobs:
12
12
  fire-autowork:
13
13
  if: >-
14
- (github.event.action == 'opened' && contains(github.event.issue.labels.*.name, 'bug') && contains(github.event.issue.labels.*.name, 'priority/P1')) ||
15
- (github.event.action == 'labeled' && (github.event.label.name == 'bug' || github.event.label.name == 'priority/P1'))
14
+ (github.event.action == 'opened' && contains(github.event.issue.labels.*.name, 'bug') && (contains(github.event.issue.labels.*.name, 'priority/P1') || contains(github.event.issue.labels.*.name, 'priority/P0'))) ||
15
+ (github.event.action == 'labeled' && contains(github.event.issue.labels.*.name, 'bug') && (contains(github.event.issue.labels.*.name, 'priority/P1') || contains(github.event.issue.labels.*.name, 'priority/P0')))
16
16
  runs-on: ubuntu-latest
17
- timeout-minutes: 65
17
+ timeout-minutes: 35
18
18
  permissions:
19
19
  contents: write
20
20
  issues: write
@@ -80,7 +80,7 @@ jobs:
80
80
  echo "skills_prompt=$SKILLS_PROMPT" >> "$GITHUB_OUTPUT"
81
81
 
82
82
  - name: Run Autowork
83
- timeout-minutes: 60
83
+ timeout-minutes: 30
84
84
  env:
85
85
  GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
86
86
  GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
@@ -97,5 +97,5 @@ jobs:
97
97
  agy -p "$PROMPT" \
98
98
  --model gemini-3.7-flash-high \
99
99
  --output-format text \
100
- --print-timeout 60m \
100
+ --print-timeout 30m \
101
101
  --dangerously-skip-permissions
@@ -15,7 +15,7 @@ jobs:
15
15
  github.event.pull_request.base.ref == 'main' &&
16
16
  github.event.pull_request.head.repo.full_name == github.repository
17
17
  runs-on: ubuntu-latest
18
- timeout-minutes: 65
18
+ timeout-minutes: 35
19
19
  permissions:
20
20
  contents: write
21
21
  issues: write
@@ -110,7 +110,7 @@ jobs:
110
110
 
111
111
  - name: Run Autowork
112
112
  if: steps.pick.outputs.skip != 'true'
113
- timeout-minutes: 60
113
+ timeout-minutes: 30
114
114
  env:
115
115
  GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
116
116
  GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
@@ -126,5 +126,5 @@ jobs:
126
126
  agy -p "$PROMPT" \
127
127
  --model gemini-3.7-flash-high \
128
128
  --output-format text \
129
- --print-timeout 60m \
129
+ --print-timeout 30m \
130
130
  --dangerously-skip-permissions
@@ -2,21 +2,48 @@ name: Trigger Review Routine
2
2
 
3
3
  on:
4
4
  pull_request:
5
- types: [ready_for_review, opened, reopened, synchronize]
5
+ types: [ready_for_review, opened, reopened, synchronize, review_requested]
6
6
  paths-ignore:
7
7
  - '.github/prompts/logs/**'
8
+ schedule:
9
+ # Periodic scan sweep every 2 hours to catch and recover any orphaned or unreviewed ready PRs
10
+ - cron: '45 */2 * * *'
11
+ workflow_dispatch:
12
+ inputs:
13
+ pr_number:
14
+ description: 'Optional PR number to review in Targeted mode (leave blank for Scan mode)'
15
+ required: false
16
+ type: string
17
+ issue_comment:
18
+ types: [created]
8
19
 
9
20
  concurrency:
10
- group: review-routine-pr-${{ github.event.pull_request.number }}
21
+ group: review-routine-pr-${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number || 'scan' }}
11
22
  cancel-in-progress: true
12
23
 
13
24
  jobs:
14
25
  trigger-routine:
15
26
  if: >-
16
- github.event.pull_request.draft == false &&
17
- github.event.pull_request.head.repo.full_name == github.repository
27
+ (github.event_name == 'pull_request' &&
28
+ github.event.pull_request.draft == false &&
29
+ github.event.pull_request.head.repo.full_name == github.repository &&
30
+ !startsWith(github.event.pull_request.head.ref, 'release-please--')) ||
31
+ (github.event_name == 'schedule') ||
32
+ (github.event_name == 'workflow_dispatch') ||
33
+ (github.event_name == 'issue_comment' &&
34
+ github.event.issue.pull_request != null &&
35
+ !endsWith(github.event.comment.user.login, '[bot]') &&
36
+ github.event.comment.user.type != 'Bot' &&
37
+ (startsWith(github.event.comment.body, '/review') ||
38
+ startsWith(github.event.comment.body, '/peer-review') ||
39
+ startsWith(github.event.comment.body, '/retrigger') ||
40
+ startsWith(github.event.comment.body, '/re-review') ||
41
+ contains(github.event.comment.body, '/review') ||
42
+ contains(github.event.comment.body, '/peer-review') ||
43
+ contains(github.event.comment.body, '/retrigger') ||
44
+ contains(github.event.comment.body, '/re-review')))
18
45
  runs-on: ubuntu-latest
19
- timeout-minutes: 60
46
+ timeout-minutes: 35
20
47
  permissions:
21
48
  contents: write
22
49
  actions: read
@@ -28,7 +55,21 @@ jobs:
28
55
  id: guard
29
56
  env:
30
57
  GH_TOKEN: ${{ github.token }}
58
+ PR_NUM: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
31
59
  run: |
60
+ if [ -z "$PR_NUM" ]; then
61
+ if [ "${{ github.event_name }}" = "schedule" ]; then
62
+ open_prs=$(gh api "repos/${{ github.repository }}/pulls?state=open&per_page=1" --jq 'length' 2>/dev/null || echo "0")
63
+ if [ "$open_prs" -eq "0" ]; then
64
+ echo "No open PRs found in ${{ github.repository }} — skipping scheduled review routine scan."
65
+ echo "skip=true" >> "$GITHUB_OUTPUT"
66
+ exit 0
67
+ fi
68
+ fi
69
+ echo "skip=false" >> "$GITHUB_OUTPUT"
70
+ exit 0
71
+ fi
72
+
32
73
  gh_api_retry() {
33
74
  local endpoint="$1"
34
75
  shift
@@ -46,18 +87,37 @@ jobs:
46
87
  return 1
47
88
  }
48
89
 
49
- if ! pr=$(gh_api_retry "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}"); then
90
+ if ! pr=$(gh_api_retry "repos/${{ github.repository }}/pulls/${PR_NUM}"); then
50
91
  echo "skip=false" >> "$GITHUB_OUTPUT"
51
92
  exit 0
52
93
  fi
53
94
 
54
95
  state=$(echo "$pr" | jq -r '.state')
55
96
  merged=$(echo "$pr" | jq -r '.merged')
97
+ head_ref=$(echo "$pr" | jq -r '.head.ref')
56
98
  if [ "$state" = "closed" ] || [ "$merged" = "true" ]; then
57
99
  echo "PR is already $state/merged=$merged — skipping review."
58
100
  echo "skip=true" >> "$GITHUB_OUTPUT"
59
101
  exit 0
60
102
  fi
103
+ if [[ "$head_ref" == release-please--* ]]; then
104
+ echo "PR head branch $head_ref is an automated release PR — skipping review."
105
+ echo "skip=true" >> "$GITHUB_OUTPUT"
106
+ exit 0
107
+ fi
108
+
109
+ # Priority-driven dual execution filter on direct pull_request triggers:
110
+ # If PR is labeled priority/P2 or priority/P3, skip immediate cloud review to let local agent daemons review it
111
+ # (cloud scheduled watchdog sweep will catch up if unreviewed > 48h).
112
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
113
+ labels=$(echo "$pr" | jq -r '.labels[].name' 2>/dev/null || echo "")
114
+ if echo "$labels" | grep -qE '^priority/P[23]$'; then
115
+ echo "PR is labeled as lower priority (P2/P3) — skipping immediate cloud review for local peer-review daemon."
116
+ echo "skip=true" >> "$GITHUB_OUTPUT"
117
+ exit 0
118
+ fi
119
+ fi
120
+
61
121
  echo "skip=false" >> "$GITHUB_OUTPUT"
62
122
 
63
123
  - name: Checkout repository
@@ -112,26 +172,48 @@ jobs:
112
172
 
113
173
  - name: Run Peer Review
114
174
  if: steps.guard.outputs.skip != 'true'
115
- timeout-minutes: 55
175
+ timeout-minutes: 30
116
176
  env:
117
177
  GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
118
178
  GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
119
179
  ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
120
180
  GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
121
- PR_NUMBER: ${{ github.event.pull_request.number }}
122
- PR_URL: ${{ github.event.pull_request.html_url }}
181
+ PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
182
+ PR_URL: ${{ github.event.pull_request.html_url || github.event.issue.html_url }}
123
183
  GITHUB_SERVER_URL: ${{ github.server_url }}
124
184
  GITHUB_REPOSITORY: ${{ github.repository }}
125
185
  GITHUB_RUN_ID: ${{ github.run_id }}
126
186
  run: |
127
- PROMPT="You are the Peer Review routine for this repository. Read and follow the instructions in .github/prompts/peer-review.md exactly. Your target is pull request #${PR_NUMBER} (${PR_URL}). You are in Targeted mode: review PR #${PR_NUMBER} directly."
187
+ if [ -n "$PR_NUMBER" ]; then
188
+ if [ -z "$PR_URL" ] || [[ "$PR_URL" == *"/issues/"* ]]; then
189
+ PR_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}"
190
+ fi
191
+ PROMPT="You are the Peer Review routine for this repository. Read and follow the instructions in .github/prompts/peer-review.md exactly. Your target is pull request #${PR_NUMBER} (${PR_URL}). You are in Targeted mode: review PR #${PR_NUMBER} directly."
192
+ else
193
+ 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."
194
+ fi
128
195
 
129
196
  agy -p "$PROMPT" \
130
197
  --model gemini-3.7-flash-high \
131
198
  --output-format text \
132
- --print-timeout 55m \
199
+ --print-timeout 30m \
133
200
  --dangerously-skip-permissions
134
201
 
202
+ - name: Handle Review Failure & PR Notification
203
+ if: failure() && steps.guard.outputs.skip != 'true'
204
+ env:
205
+ GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
206
+ PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
207
+ GITHUB_SERVER_URL: ${{ github.server_url }}
208
+ GITHUB_REPOSITORY: ${{ github.repository }}
209
+ GITHUB_RUN_ID: ${{ github.run_id }}
210
+ run: |
211
+ if [ -n "$PR_NUMBER" ]; then
212
+ 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.
213
+
214
+ _Generated by [Antigravity](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})_" || true
215
+ fi
216
+
135
217
  - name: Emit run summary
136
218
  if: always() && steps.guard.outputs.skip != 'true'
137
219
  run: |
@@ -139,3 +221,17 @@ jobs:
139
221
  if [ -n "$LATEST_LOG" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
140
222
  cat "$LATEST_LOG" >> "$GITHUB_STEP_SUMMARY"
141
223
  fi
224
+
225
+ - name: Emit Fleet Telemetry (Opt-in)
226
+ if: always() && steps.guard.outputs.skip != 'true'
227
+ env:
228
+ GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
229
+ TELEMETRY_ENDPOINT: ${{ secrets.JONAH_FLEET_TELEMETRY_ENDPOINT }}
230
+ GITHUB_REPOSITORY: ${{ github.repository }}
231
+ GITHUB_RUN_ID: ${{ github.run_id }}
232
+ GITHUB_RUN_NUMBER: ${{ github.run_number }}
233
+ run: |
234
+ LATEST_LOG=$(ls -t .github/prompts/logs/peer-review/*.md 2>/dev/null | head -n 1)
235
+ if [ -n "$LATEST_LOG" ] && [ -f "$LATEST_LOG" ]; then
236
+ npx --yes jonah-fleet telemetry --emit --log "$LATEST_LOG" --endpoint "$TELEMETRY_ENDPOINT" || true
237
+ fi