jonah-fleet 1.30.0 → 1.30.2
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 +15 -0
- package/package.json +1 -1
- package/templates/prompts/ORCHESTRATION.md +1 -1
- package/templates/prompts/analytics-review.md +17 -3
- package/templates/scripts/run-with-loop-guard.js +5 -0
- package/templates/workflows/analytics-review-cron.yml +19 -6
- package/templates/workflows/autowork-cron.yml +20 -7
- package/templates/workflows/dependency-check-cron.yml +18 -5
- package/templates/workflows/issues-housekeeping-cron.yml +18 -5
- package/templates/workflows/prompt-optimizer-cron.yml +19 -6
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ All notable changes to `jonah-fleet` will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.30.2](https://github.com/Jonah-Projects/jonah-fleet/compare/v1.30.1...v1.30.2) (2026-09-30)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **workflows:** respect routine toggle flags in agents-manifest.json during scheduled cron runs ([#509](https://github.com/Jonah-Projects/jonah-fleet/issues/509)) ([dfb188a](https://github.com/Jonah-Projects/jonah-fleet/commit/dfb188a7a4189875e6fb61efb8ea0f0093bbed65))
|
|
14
|
+
|
|
15
|
+
## [1.30.1](https://github.com/Jonah-Projects/jonah-fleet/compare/v1.30.0...v1.30.1) (2026-09-25)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **analytics-review:** forbid staging into or commenting on closed product plans ([e945366](https://github.com/Jonah-Projects/jonah-fleet/commit/e945366f8d645d54b3c3de2c9bf7d8c4aaa8cf5f))
|
|
21
|
+
|
|
8
22
|
## [1.30.0](https://github.com/Jonah-Projects/jonah-fleet/compare/v1.29.0...v1.30.0) (2026-09-25)
|
|
9
23
|
|
|
10
24
|
|
|
@@ -48,6 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
48
62
|
|
|
49
63
|
### Bug Fixes
|
|
50
64
|
|
|
65
|
+
* **analytics-review:** require active product planning staging issues to be strictly open (`--state open`), forbid commenting on or editing closed product plans from past planning sweeps, and make DoD staging conditional on having emitted directives
|
|
51
66
|
* **runner:** introduce granular tool output evaluation descriptions, live subagent progress tracking, and non-TTY spinner deduplication to replace long-running generic `Evaluating tool output...` states
|
|
52
67
|
* **autowork:** prevent local and GitHub-hosted autowork runner collisions by excluding bot and self-assignments from `trigger-autowork-on-assign.yml`, enforcing a 2-hour active claim lock in Step 0.5a / Step 11a, and mandating concrete pre-PR collision checks with collision bail in Step 13
|
|
53
68
|
* **daemon:** query `statusCheckRollup` in `getOpenReviewablePRs` and filter out PRs with in-progress CI to prevent premature review dispatch and repetition loop trips
|
package/package.json
CHANGED
|
@@ -261,7 +261,7 @@ How changes and innovations from upstream ecosystems—[openai/symphony](https:/
|
|
|
261
261
|
|
|
262
262
|
How closed-loop feedback from product telemetry and measurement trackers drives product decisions while preventing autonomous agents from falling into telemetry rabbit holes:
|
|
263
263
|
|
|
264
|
-
1. **Mandatory Post-Measurement Action Rule**: When `analytics-review` concludes an evaluation of a feature or experiment tracker (especially sub-threshold features with <2% user adoption or >50% failure rates), it MUST emit a structured directive: `RECOMMENDATION: [PIVOT | DEPRECATE | ITERATE]`. Measurement closure is never a terminal dead-end; outcomes are staged into
|
|
264
|
+
1. **Mandatory Post-Measurement Action Rule**: When `analytics-review` concludes an evaluation of a feature or experiment tracker (especially sub-threshold features with <2% user adoption or >50% failure rates), it MUST emit a structured directive: `RECOMMENDATION: [PIVOT | DEPRECATE | ITERATE]`. Measurement closure is never a terminal dead-end; outcomes are staged into an active `🗺️ Product Plan` (which must be currently `state: open`; agents must never stage into or comment on closed/past product plans) or actionable `roadmap/*` issues.
|
|
265
265
|
2. **Feature Pruning & Deprecation Audit**: During Propose mode sweeps, `product-planning` actively audits shipped roadmap items and closed measurement trackers. For features with low ROI (<2% adoption, >50% error/failure rate), it drafts explicit deprecation, removal, or simplification proposals alongside new feature additions, keeping the codebase and UI lean.
|
|
266
266
|
3. **Intent vs. Defect Guardrail**: When investigating underperforming or zero-conversion features, `autowork` and `diagnosing-bugs` verify whether the issue is a software defect or a lack of user intent. If the feature functions properly without runtime errors but user interaction is negligible, agents must classify the issue as a **product/UX intent question** (`needs-design` / `roadmap/*`) rather than falling into the **Telemetry Rabbit Hole** (adding redundant fallback telemetry, defensive error handling, or retry loops for unwanted features).
|
|
267
267
|
4. **Post-Merge Measurement Tracker Ingestion**: When `peer-review` squash-merges an approved PR, it inspects the tracking issue or spec for `## Telemetry & Measurement Decisions`. If a Tier 1 or Tier 2 companion measurement issue is outlined (`Measure: <Feature Name>`), `peer-review` automatically files the tracker with the `measurement` label upon merge, ensuring downstream `analytics-review` sweeps are never starved of intake.
|
|
@@ -20,7 +20,7 @@ The run is SUCCESS only if ALL of these are true:
|
|
|
20
20
|
- [ ] For conclusive measurement issues: synthesized adoption metrics (CTR, conversion rate, error frequency) against defined success criteria
|
|
21
21
|
- [ ] For sub-threshold features (<2% user adoption or >50% failure rate) or conclusive outcomes, outputted a structured directive: `RECOMMENDATION: [PIVOT | DEPRECATE | ITERATE]`
|
|
22
22
|
- [ ] Evaluated UI friction signals (grouping `$rageclick` by URL and element) and applied the Nudge & Banner Fatigue rule for promotional elements exceeding 500 impressions with CTR < 2.0%
|
|
23
|
-
- [ ]
|
|
23
|
+
- [ ] For conclusive measurement trackers or sub-threshold features: staged the recommendation directly into an active, open `🗺️ Product Plan` staging issue or filed an actionable `roadmap/*` issue for `product-planning` to review; if all trackers remain active/healthy with no new directives, logged scan status to the routine run issue
|
|
24
24
|
- [ ] Closed resolved measurement trackers with full analysis summaries and Antigravity run footer
|
|
25
25
|
|
|
26
26
|
If any criterion cannot be met, stop immediately and log FAILURE with the reason.
|
|
@@ -37,6 +37,8 @@ If any criterion cannot be met, stop immediately and log FAILURE with the reason
|
|
|
37
37
|
|
|
38
38
|
- Do not close a measurement tracker with a failed adoption verdict without emitting a mandatory `RECOMMENDATION: [PIVOT | DEPRECATE | ITERATE]` directive.
|
|
39
39
|
- Do not treat measurement closure as a terminal dead-end — always bridge outcomes to `product-planning`.
|
|
40
|
+
- Do not comment on, edit, or stage directives into closed product plans (`state: closed`) from past planning sweeps. Once closed, product plans are completed historical records and must never receive new comments.
|
|
41
|
+
- Do not search issues with `--state all` when querying for active product plans; active plans are strictly open issues (`--state open`).
|
|
40
42
|
- Do not file bug tickets or request additional telemetry when users simply lack intent to interact with a feature.
|
|
41
43
|
|
|
42
44
|
## Instructions
|
|
@@ -96,8 +98,20 @@ When a measurement tracker is conclusive or reaches sub-threshold adoption (<2%
|
|
|
96
98
|
|
|
97
99
|
### Step 4: Bridge outcome to `product-planning`
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
When conclusive measurement directives (`RECOMMENDATION: [PIVOT | DEPRECATE | ITERATE]`) are emitted:
|
|
102
|
+
1. Search for an **active, OPEN** product planning staging issue:
|
|
103
|
+
```bash
|
|
104
|
+
gh issue list --state open --search "Product Plan"
|
|
105
|
+
```
|
|
106
|
+
**Active Staging Issue Invariant**: A staging issue is active ONLY if its state is currently **OPEN**. If an issue is closed, it is a historical plan from a past cycle and MUST be ignored. **NEVER comment on, reopen, or edit closed product plan issues (`state: closed`).**
|
|
107
|
+
2. If an open staging issue exists (e.g. `🗺️ Product Plan — {YYYY-MM-DD}`):
|
|
108
|
+
- Stage the recommendation under its `### Feature Pruning & Deprecation Audit` or `### Backlog Re-rankings` section.
|
|
109
|
+
3. If no open staging issue exists (the expected state between planning sweeps):
|
|
110
|
+
- Do NOT comment on past closed product plans.
|
|
111
|
+
- For actionable pivots, deprecations, or feature modifications requiring planning review, open an actionable `roadmap/*` issue labeled `needs-design` or `enhancement` detailing the measurement verdict and recommendation for the next product planning sweep.
|
|
112
|
+
4. If no trackers reached a conclusive state during this run and all evaluated trackers remain healthy/within measurement horizon:
|
|
113
|
+
- Do not stage redundant directives or file unnecessary roadmap issues.
|
|
114
|
+
- Record tracker evaluation progress in the routine run issue (`$ROUTINE_ISSUE_NUMBER`) and `.jonah-fleet/run-report.md`.
|
|
101
115
|
|
|
102
116
|
### Step 5: Close conclusive measurement trackers
|
|
103
117
|
|
|
@@ -453,6 +453,11 @@ async function main() {
|
|
|
453
453
|
}
|
|
454
454
|
} else if (parsed.event === 'result' && parsed.result?.response) {
|
|
455
455
|
console.log(`\n${parsed.result.response}\n`);
|
|
456
|
+
} else if (parsed.event === 'error' || parsed.error) {
|
|
457
|
+
const errMsg =
|
|
458
|
+
parsed.error?.message ||
|
|
459
|
+
(typeof parsed.error === 'string' ? parsed.error : JSON.stringify(parsed.error || parsed));
|
|
460
|
+
console.error(`\n[agent:error] ${errMsg}`);
|
|
456
461
|
}
|
|
457
462
|
return;
|
|
458
463
|
}
|
|
@@ -128,6 +128,7 @@ jobs:
|
|
|
128
128
|
|
|
129
129
|
MODEL="$DEFAULT_MODEL"
|
|
130
130
|
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
131
|
+
ENABLED="true"
|
|
131
132
|
|
|
132
133
|
if [ -f "agents-manifest.json" ]; then
|
|
133
134
|
CONFIG_JSON=$(node -e '
|
|
@@ -137,14 +138,16 @@ jobs:
|
|
|
137
138
|
const r = process.argv[1];
|
|
138
139
|
const model = m.models?.[r] || m.models?.default;
|
|
139
140
|
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
140
|
-
|
|
141
|
+
const enabled = m.routines?.[r] !== false;
|
|
142
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "", enabled }));
|
|
141
143
|
} catch (e) {
|
|
142
|
-
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
144
|
+
console.log(JSON.stringify({ model: "", timeout: "", enabled: true }));
|
|
143
145
|
}
|
|
144
146
|
' "$ROUTINE")
|
|
145
147
|
|
|
146
148
|
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
147
149
|
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
150
|
+
RESOLVED_ENABLED=$(node -e "try { console.log(JSON.parse(process.argv[1]).enabled); } catch {}" "$CONFIG_JSON")
|
|
148
151
|
|
|
149
152
|
if [ -n "$RESOLVED_MODEL" ]; then
|
|
150
153
|
MODEL="$RESOLVED_MODEL"
|
|
@@ -152,13 +155,22 @@ jobs:
|
|
|
152
155
|
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
153
156
|
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
154
157
|
fi
|
|
158
|
+
if [ -n "$RESOLVED_ENABLED" ]; then
|
|
159
|
+
ENABLED="$RESOLVED_ENABLED"
|
|
160
|
+
fi
|
|
155
161
|
fi
|
|
156
162
|
|
|
157
163
|
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
158
164
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
159
|
-
echo "
|
|
165
|
+
echo "enabled=$ENABLED" >> "$GITHUB_OUTPUT"
|
|
166
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m, enabled=$ENABLED"
|
|
167
|
+
|
|
168
|
+
if [ "$ENABLED" = "false" ] && [ "${{ github.event_name }}" = "schedule" ]; then
|
|
169
|
+
echo "⏸️ Routine '$ROUTINE' is disabled in agents-manifest.json. Skipping scheduled run."
|
|
170
|
+
fi
|
|
160
171
|
|
|
161
172
|
- name: Initialize Routine Run Issue
|
|
173
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
162
174
|
id: run-issue
|
|
163
175
|
env:
|
|
164
176
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
@@ -183,6 +195,7 @@ jobs:
|
|
|
183
195
|
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
184
196
|
|
|
185
197
|
- name: Run Analytics Review
|
|
198
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
186
199
|
timeout-minutes: 50
|
|
187
200
|
env:
|
|
188
201
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
@@ -224,7 +237,7 @@ jobs:
|
|
|
224
237
|
fi
|
|
225
238
|
|
|
226
239
|
- name: Emit run summary
|
|
227
|
-
if: always()
|
|
240
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
228
241
|
run: |
|
|
229
242
|
if [ "$QUOTA_PAUSED" = "true" ]; then
|
|
230
243
|
echo "### ⏸️ Milestone: Routine Execution Quota-Paused" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -238,7 +251,7 @@ jobs:
|
|
|
238
251
|
fi
|
|
239
252
|
|
|
240
253
|
- name: Emit Fleet Telemetry (Opt-in)
|
|
241
|
-
if: always()
|
|
254
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
242
255
|
env:
|
|
243
256
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
244
257
|
TELEMETRY_ENDPOINT: ${{ secrets.JONAH_FLEET_TELEMETRY_ENDPOINT }}
|
|
@@ -252,7 +265,7 @@ jobs:
|
|
|
252
265
|
fi
|
|
253
266
|
|
|
254
267
|
- name: Reconcile Routine Run Issue
|
|
255
|
-
if: always()
|
|
268
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
256
269
|
env:
|
|
257
270
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
258
271
|
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
@@ -130,6 +130,7 @@ jobs:
|
|
|
130
130
|
|
|
131
131
|
MODEL="$DEFAULT_MODEL"
|
|
132
132
|
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
133
|
+
ENABLED="true"
|
|
133
134
|
|
|
134
135
|
if [ -f "agents-manifest.json" ]; then
|
|
135
136
|
CONFIG_JSON=$(node -e '
|
|
@@ -139,14 +140,16 @@ jobs:
|
|
|
139
140
|
const r = process.argv[1];
|
|
140
141
|
const model = m.models?.[r] || m.models?.default;
|
|
141
142
|
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
142
|
-
|
|
143
|
+
const enabled = m.routines?.[r] !== false;
|
|
144
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "", enabled }));
|
|
143
145
|
} catch (e) {
|
|
144
|
-
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
146
|
+
console.log(JSON.stringify({ model: "", timeout: "", enabled: true }));
|
|
145
147
|
}
|
|
146
148
|
' "$ROUTINE")
|
|
147
149
|
|
|
148
150
|
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
149
151
|
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
152
|
+
RESOLVED_ENABLED=$(node -e "try { console.log(JSON.parse(process.argv[1]).enabled); } catch {}" "$CONFIG_JSON")
|
|
150
153
|
|
|
151
154
|
if [ -n "$RESOLVED_MODEL" ]; then
|
|
152
155
|
MODEL="$RESOLVED_MODEL"
|
|
@@ -154,13 +157,22 @@ jobs:
|
|
|
154
157
|
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
155
158
|
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
156
159
|
fi
|
|
160
|
+
if [ -n "$RESOLVED_ENABLED" ]; then
|
|
161
|
+
ENABLED="$RESOLVED_ENABLED"
|
|
162
|
+
fi
|
|
157
163
|
fi
|
|
158
164
|
|
|
159
165
|
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
160
166
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
161
|
-
echo "
|
|
167
|
+
echo "enabled=$ENABLED" >> "$GITHUB_OUTPUT"
|
|
168
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m, enabled=$ENABLED"
|
|
169
|
+
|
|
170
|
+
if [ "$ENABLED" = "false" ] && [ "${{ github.event_name }}" = "schedule" ]; then
|
|
171
|
+
echo "⏸️ Routine '$ROUTINE' is disabled in agents-manifest.json. Skipping scheduled run."
|
|
172
|
+
fi
|
|
162
173
|
|
|
163
174
|
- name: Initialize Routine Run Issue
|
|
175
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
164
176
|
id: run-issue
|
|
165
177
|
env:
|
|
166
178
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
@@ -190,6 +202,7 @@ jobs:
|
|
|
190
202
|
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
191
203
|
|
|
192
204
|
- name: Run Autowork
|
|
205
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
193
206
|
timeout-minutes: 60
|
|
194
207
|
env:
|
|
195
208
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
@@ -234,7 +247,7 @@ jobs:
|
|
|
234
247
|
fi
|
|
235
248
|
|
|
236
249
|
- name: Emit run summary
|
|
237
|
-
if: always()
|
|
250
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
238
251
|
run: |
|
|
239
252
|
if [ "$QUOTA_PAUSED" = "true" ]; then
|
|
240
253
|
echo "### ⏸️ Milestone: Routine Execution Quota-Paused" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -248,7 +261,7 @@ jobs:
|
|
|
248
261
|
fi
|
|
249
262
|
|
|
250
263
|
- name: Emit Fleet Telemetry (Opt-in)
|
|
251
|
-
if: always()
|
|
264
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
252
265
|
env:
|
|
253
266
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
254
267
|
TELEMETRY_ENDPOINT: ${{ secrets.JONAH_FLEET_TELEMETRY_ENDPOINT }}
|
|
@@ -262,7 +275,7 @@ jobs:
|
|
|
262
275
|
fi
|
|
263
276
|
|
|
264
277
|
- name: Verify Atomic Handoff Invariant (PR Existence Guard)
|
|
265
|
-
if: always()
|
|
278
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
266
279
|
env:
|
|
267
280
|
GH_TOKEN: ${{ github.token }}
|
|
268
281
|
run: |
|
|
@@ -283,7 +296,7 @@ jobs:
|
|
|
283
296
|
fi
|
|
284
297
|
|
|
285
298
|
- name: Reconcile Routine Run Issue
|
|
286
|
-
if: always()
|
|
299
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
287
300
|
env:
|
|
288
301
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
289
302
|
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
@@ -91,6 +91,7 @@ jobs:
|
|
|
91
91
|
|
|
92
92
|
MODEL="$DEFAULT_MODEL"
|
|
93
93
|
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
94
|
+
ENABLED="true"
|
|
94
95
|
|
|
95
96
|
if [ -f "agents-manifest.json" ]; then
|
|
96
97
|
CONFIG_JSON=$(node -e '
|
|
@@ -100,14 +101,16 @@ jobs:
|
|
|
100
101
|
const r = process.argv[1];
|
|
101
102
|
const model = m.models?.[r] || m.models?.default;
|
|
102
103
|
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
103
|
-
|
|
104
|
+
const enabled = m.routines?.[r] !== false;
|
|
105
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "", enabled }));
|
|
104
106
|
} catch (e) {
|
|
105
|
-
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
107
|
+
console.log(JSON.stringify({ model: "", timeout: "", enabled: true }));
|
|
106
108
|
}
|
|
107
109
|
' "$ROUTINE")
|
|
108
110
|
|
|
109
111
|
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
110
112
|
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
113
|
+
RESOLVED_ENABLED=$(node -e "try { console.log(JSON.parse(process.argv[1]).enabled); } catch {}" "$CONFIG_JSON")
|
|
111
114
|
|
|
112
115
|
if [ -n "$RESOLVED_MODEL" ]; then
|
|
113
116
|
MODEL="$RESOLVED_MODEL"
|
|
@@ -115,13 +118,22 @@ jobs:
|
|
|
115
118
|
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
116
119
|
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
117
120
|
fi
|
|
121
|
+
if [ -n "$RESOLVED_ENABLED" ]; then
|
|
122
|
+
ENABLED="$RESOLVED_ENABLED"
|
|
123
|
+
fi
|
|
118
124
|
fi
|
|
119
125
|
|
|
120
126
|
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
121
127
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
122
|
-
echo "
|
|
128
|
+
echo "enabled=$ENABLED" >> "$GITHUB_OUTPUT"
|
|
129
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m, enabled=$ENABLED"
|
|
130
|
+
|
|
131
|
+
if [ "$ENABLED" = "false" ] && [ "${{ github.event_name }}" = "schedule" ]; then
|
|
132
|
+
echo "⏸️ Routine '$ROUTINE' is disabled in agents-manifest.json. Skipping scheduled run."
|
|
133
|
+
fi
|
|
123
134
|
|
|
124
135
|
- name: Initialize Routine Run Issue
|
|
136
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
125
137
|
id: run-issue
|
|
126
138
|
env:
|
|
127
139
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
@@ -146,6 +158,7 @@ jobs:
|
|
|
146
158
|
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
147
159
|
|
|
148
160
|
- name: Run Dependency Update Check
|
|
161
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
149
162
|
timeout-minutes: 25
|
|
150
163
|
env:
|
|
151
164
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
@@ -184,7 +197,7 @@ jobs:
|
|
|
184
197
|
fi
|
|
185
198
|
|
|
186
199
|
- name: Emit run summary
|
|
187
|
-
if: always()
|
|
200
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
188
201
|
run: |
|
|
189
202
|
if [ "$QUOTA_PAUSED" = "true" ]; then
|
|
190
203
|
echo "### ⏸️ Milestone: Routine Execution Quota-Paused" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -198,7 +211,7 @@ jobs:
|
|
|
198
211
|
fi
|
|
199
212
|
|
|
200
213
|
- name: Reconcile Routine Run Issue
|
|
201
|
-
if: always()
|
|
214
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
202
215
|
env:
|
|
203
216
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
204
217
|
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
@@ -91,6 +91,7 @@ jobs:
|
|
|
91
91
|
|
|
92
92
|
MODEL="$DEFAULT_MODEL"
|
|
93
93
|
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
94
|
+
ENABLED="true"
|
|
94
95
|
|
|
95
96
|
if [ -f "agents-manifest.json" ]; then
|
|
96
97
|
CONFIG_JSON=$(node -e '
|
|
@@ -100,14 +101,16 @@ jobs:
|
|
|
100
101
|
const r = process.argv[1];
|
|
101
102
|
const model = m.models?.[r] || m.models?.default;
|
|
102
103
|
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
103
|
-
|
|
104
|
+
const enabled = m.routines?.[r] !== false;
|
|
105
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "", enabled }));
|
|
104
106
|
} catch (e) {
|
|
105
|
-
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
107
|
+
console.log(JSON.stringify({ model: "", timeout: "", enabled: true }));
|
|
106
108
|
}
|
|
107
109
|
' "$ROUTINE")
|
|
108
110
|
|
|
109
111
|
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
110
112
|
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
113
|
+
RESOLVED_ENABLED=$(node -e "try { console.log(JSON.parse(process.argv[1]).enabled); } catch {}" "$CONFIG_JSON")
|
|
111
114
|
|
|
112
115
|
if [ -n "$RESOLVED_MODEL" ]; then
|
|
113
116
|
MODEL="$RESOLVED_MODEL"
|
|
@@ -115,13 +118,22 @@ jobs:
|
|
|
115
118
|
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
116
119
|
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
117
120
|
fi
|
|
121
|
+
if [ -n "$RESOLVED_ENABLED" ]; then
|
|
122
|
+
ENABLED="$RESOLVED_ENABLED"
|
|
123
|
+
fi
|
|
118
124
|
fi
|
|
119
125
|
|
|
120
126
|
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
121
127
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
122
|
-
echo "
|
|
128
|
+
echo "enabled=$ENABLED" >> "$GITHUB_OUTPUT"
|
|
129
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m, enabled=$ENABLED"
|
|
130
|
+
|
|
131
|
+
if [ "$ENABLED" = "false" ] && [ "${{ github.event_name }}" = "schedule" ]; then
|
|
132
|
+
echo "⏸️ Routine '$ROUTINE' is disabled in agents-manifest.json. Skipping scheduled run."
|
|
133
|
+
fi
|
|
123
134
|
|
|
124
135
|
- name: Initialize Routine Run Issue
|
|
136
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
125
137
|
id: run-issue
|
|
126
138
|
env:
|
|
127
139
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
@@ -146,6 +158,7 @@ jobs:
|
|
|
146
158
|
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
147
159
|
|
|
148
160
|
- name: Run Issues Housekeeping
|
|
161
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
149
162
|
timeout-minutes: 40
|
|
150
163
|
env:
|
|
151
164
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
@@ -184,7 +197,7 @@ jobs:
|
|
|
184
197
|
fi
|
|
185
198
|
|
|
186
199
|
- name: Emit run summary
|
|
187
|
-
if: always()
|
|
200
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
188
201
|
run: |
|
|
189
202
|
if [ "$QUOTA_PAUSED" = "true" ]; then
|
|
190
203
|
echo "### ⏸️ Milestone: Routine Execution Quota-Paused" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -198,7 +211,7 @@ jobs:
|
|
|
198
211
|
fi
|
|
199
212
|
|
|
200
213
|
- name: Reconcile Routine Run Issue
|
|
201
|
-
if: always()
|
|
214
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
202
215
|
env:
|
|
203
216
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
204
217
|
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
@@ -91,6 +91,7 @@ jobs:
|
|
|
91
91
|
|
|
92
92
|
MODEL="$DEFAULT_MODEL"
|
|
93
93
|
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
94
|
+
ENABLED="true"
|
|
94
95
|
|
|
95
96
|
if [ -f "agents-manifest.json" ]; then
|
|
96
97
|
CONFIG_JSON=$(node -e '
|
|
@@ -100,14 +101,16 @@ jobs:
|
|
|
100
101
|
const r = process.argv[1];
|
|
101
102
|
const model = m.models?.[r] || m.models?.default;
|
|
102
103
|
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
103
|
-
|
|
104
|
+
const enabled = m.routines?.[r] !== false;
|
|
105
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "", enabled }));
|
|
104
106
|
} catch (e) {
|
|
105
|
-
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
107
|
+
console.log(JSON.stringify({ model: "", timeout: "", enabled: true }));
|
|
106
108
|
}
|
|
107
109
|
' "$ROUTINE")
|
|
108
110
|
|
|
109
111
|
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
110
112
|
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
113
|
+
RESOLVED_ENABLED=$(node -e "try { console.log(JSON.parse(process.argv[1]).enabled); } catch {}" "$CONFIG_JSON")
|
|
111
114
|
|
|
112
115
|
if [ -n "$RESOLVED_MODEL" ]; then
|
|
113
116
|
MODEL="$RESOLVED_MODEL"
|
|
@@ -115,13 +118,22 @@ jobs:
|
|
|
115
118
|
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
116
119
|
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
117
120
|
fi
|
|
121
|
+
if [ -n "$RESOLVED_ENABLED" ]; then
|
|
122
|
+
ENABLED="$RESOLVED_ENABLED"
|
|
123
|
+
fi
|
|
118
124
|
fi
|
|
119
125
|
|
|
120
126
|
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
121
127
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
122
|
-
echo "
|
|
128
|
+
echo "enabled=$ENABLED" >> "$GITHUB_OUTPUT"
|
|
129
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m, enabled=$ENABLED"
|
|
130
|
+
|
|
131
|
+
if [ "$ENABLED" = "false" ] && [ "${{ github.event_name }}" = "schedule" ]; then
|
|
132
|
+
echo "⏸️ Routine '\''$ROUTINE'\'' is disabled in agents-manifest.json. Skipping scheduled run."
|
|
133
|
+
fi
|
|
123
134
|
|
|
124
135
|
- name: Initialize Routine Run Issue
|
|
136
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
125
137
|
id: run-issue
|
|
126
138
|
env:
|
|
127
139
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
@@ -146,6 +158,7 @@ jobs:
|
|
|
146
158
|
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
147
159
|
|
|
148
160
|
- name: Run Prompt Optimizer
|
|
161
|
+
if: steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule'
|
|
149
162
|
timeout-minutes: 35
|
|
150
163
|
env:
|
|
151
164
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
@@ -184,7 +197,7 @@ jobs:
|
|
|
184
197
|
fi
|
|
185
198
|
|
|
186
199
|
- name: Emit run summary
|
|
187
|
-
if: always()
|
|
200
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
188
201
|
run: |
|
|
189
202
|
if [ "$QUOTA_PAUSED" = "true" ]; then
|
|
190
203
|
echo "### ⏸️ Milestone: Routine Execution Quota-Paused" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -198,7 +211,7 @@ jobs:
|
|
|
198
211
|
fi
|
|
199
212
|
|
|
200
213
|
- name: Emit Fleet Telemetry (Opt-in)
|
|
201
|
-
if: always()
|
|
214
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
202
215
|
env:
|
|
203
216
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
204
217
|
TELEMETRY_ENDPOINT: ${{ secrets.JONAH_FLEET_TELEMETRY_ENDPOINT }}
|
|
@@ -212,7 +225,7 @@ jobs:
|
|
|
212
225
|
fi
|
|
213
226
|
|
|
214
227
|
- name: Reconcile Routine Run Issue
|
|
215
|
-
if: always()
|
|
228
|
+
if: always() && (steps.routine-config.outputs.enabled != 'false' || github.event_name != 'schedule')
|
|
216
229
|
env:
|
|
217
230
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
218
231
|
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|