jonah-fleet 1.6.0 → 1.9.0
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 +130 -0
- package/README.md +25 -2
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/labels.d.ts +11 -0
- package/dist/commands/labels.d.ts.map +1 -0
- 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 +2527 -519
- package/dist/lib/daemon-keys.d.ts +103 -0
- package/dist/lib/daemon-keys.d.ts.map +1 -0
- package/dist/lib/daemon.d.ts +8 -2
- 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 +68 -0
- package/dist/lib/labels.d.ts.map +1 -0
- package/dist/lib/manifest.d.ts +6 -0
- package/dist/lib/manifest.d.ts.map +1 -1
- package/dist/lib/presets.d.ts +52 -1
- package/dist/lib/presets.d.ts.map +1 -1
- package/dist/lib/runner.d.ts +114 -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 +24 -1
- package/dist/lib/terminal-card.d.ts.map +1 -1
- package/package.json +1 -1
- package/schema.json +74 -1
- package/templates/prompts/ORCHESTRATION.md +84 -41
- package/templates/prompts/_prompt-template.md +10 -13
- package/templates/prompts/analytics-review.md +4 -2
- package/templates/prompts/autowork.md +76 -35
- package/templates/prompts/dependency-update-security-check.md +4 -2
- package/templates/prompts/design-review.md +125 -0
- package/templates/prompts/issues-housekeeping.md +10 -8
- package/templates/prompts/optimizer.md +31 -12
- package/templates/prompts/peer-review.md +42 -7
- package/templates/prompts/product-planning.md +14 -10
- package/templates/workflows/autowork-cron.yml +137 -38
- package/templates/workflows/dependency-check-cron.yml +127 -2
- package/templates/workflows/design-review-cron.yml +221 -0
- package/templates/workflows/issues-housekeeping-cron.yml +127 -2
- package/templates/workflows/prompt-optimizer-cron.yml +134 -9
- package/templates/workflows/sync-fleet.yml +4 -0
- package/templates/workflows/trigger-autowork-manual.yml +154 -11
- package/templates/workflows/trigger-autowork-on-bug.yml +177 -9
- package/templates/workflows/trigger-autowork-on-merge.yml +178 -9
- package/templates/workflows/trigger-review-routine.yml +162 -22
|
@@ -8,7 +8,7 @@ Review a pull request (in Targeted mode for a specific `$PR_NUMBER`, or in Scan
|
|
|
8
8
|
|
|
9
9
|
Before reading further, before any tool call, and before deciding the mode, check the environment variable `$PR_NUMBER`.
|
|
10
10
|
|
|
11
|
-
- **$PR_NUMBER is set → Targeted mode.** The value of `$PR_NUMBER`
|
|
11
|
+
- **$PR_NUMBER is set → Targeted mode.** The value of `$PR_NUMBER`is your target PR. You may also check`$PR_URL`. Skip all selection logic.
|
|
12
12
|
- **$PR_NUMBER is not set → Scan mode.** Only then select a PR by priority.
|
|
13
13
|
|
|
14
14
|
**Targeted mode is sticky: it can never fall back to Scan mode.** Once the invocation contains a PR reference, you must review exactly that PR. If you cannot act on it (closed/merged/missing), STOP and log FAILURE.
|
|
@@ -19,7 +19,7 @@ The run is SUCCESS only if ALL of these are true:
|
|
|
19
19
|
|
|
20
20
|
- [ ] Identified the target PR: if one was named in the invocation, reviewed exactly that PR; otherwise listed open PRs and selected one by priority
|
|
21
21
|
- [ ] Ran the code-review pass (`/code-review` and security pass), and posted findings as inline review comments
|
|
22
|
-
- [ ] Took exactly one final action: squash-merged (if PR is good, CI green and present; executed Autonomous Issue Synthesis if unlinked) OR posted findings and **converted the PR back to draft** (`gh pr ready <N> --undo`) for author/autowork in-session fixes OR, if round cap reached at round 5 with blocking findings, converted to draft and escalated to human
|
|
22
|
+
- [ ] Took exactly one final action: squash-merged (if PR is good, CI green and present; executed Autonomous Issue Synthesis if unlinked; closed tracking issue explicitly if referenced) OR posted findings and **converted the PR back to draft** (`gh pr ready <N> --undo`) for author/autowork in-session fixes OR, if round cap reached at round 5 with blocking findings, converted to draft and escalated to human
|
|
23
23
|
- [ ] If merging: captured deferred non-blocking findings per materiality bar (filed follow-up issues for material ones, batched or dropped immaterial ones)
|
|
24
24
|
- [ ] If in Scan mode and no eligible PRs exist, logged SUCCESS with "No PRs to review"
|
|
25
25
|
|
|
@@ -37,8 +37,9 @@ If any criterion cannot be met, stop immediately and log FAILURE with the reason
|
|
|
37
37
|
## Final action: merge or bounce to draft
|
|
38
38
|
|
|
39
39
|
Every review ends in exactly one of two states:
|
|
40
|
+
|
|
40
41
|
- **Merge** — only if PR is good, CI is green and verified on the head commit. If the PR does not reference a tracked issue (`Closes #N`), execute Autonomous Issue Synthesis prior to merge.
|
|
41
|
-
- Sequence: (1) if unlinked, synthesize tracking issue (`gh issue create`) and link to PR (`gh pr edit`), (2) squash-merge, (3) submit held review comments, (
|
|
42
|
+
- Sequence: (1) if unlinked, synthesize tracking issue (`gh issue create`) and link to PR (`gh pr edit`), (2) squash-merge (`gh pr merge <N> --squash --delete-branch`), (3) explicitly close tracking issue if referenced (`gh issue close <ISSUE_NUMBER>`), (4) submit held review comments, (5) file follow-up issues for deferred material findings.
|
|
42
43
|
- Immaterial findings (style/preference) default to dying in the review thread or getting batched.
|
|
43
44
|
- Mechanical doc fixes (missing changelog line, doc typo in diff) can be committed directly to `main` after squash-merge.
|
|
44
45
|
- **Bounce to draft** — if any **blocking** finding remains (correctness bug, security flaw, failing/missing CI, broken contract):
|
|
@@ -63,12 +64,13 @@ Every review ends in exactly one of two states:
|
|
|
63
64
|
### Step 0: Determine the target PR (do this FIRST)
|
|
64
65
|
|
|
65
66
|
Check if `$PR_NUMBER` is set:
|
|
67
|
+
|
|
66
68
|
- **$PR_NUMBER is set → Targeted mode.** Review that exact PR. Skip selection steps 1–2.
|
|
67
69
|
- **$PR_NUMBER is not set → Scan mode.** Proceed to steps 1–2.
|
|
68
70
|
|
|
69
71
|
### Steps 1–2: Select a PR (Scan mode only)
|
|
70
72
|
|
|
71
|
-
1. List all open PRs, excluding drafts
|
|
73
|
+
1. List all open PRs, excluding drafts and automated release PRs (`release-please--*` / `chore(main): release*`).
|
|
72
74
|
2. **Dual Execution Priority Routing**:
|
|
73
75
|
- If running in **Cloud Actions** (`$GITHUB_ACTIONS` / `$CI`): Scan mode prioritizes PRs labeled `priority/P0` or `priority/P1` (or untagged PRs). Lower-priority PRs (`priority/P2`, `priority/P3`) are eligible for cloud review ONLY if they have remained ready and unreviewed for more than 48 hours (`created_at` older than 48h, acting as a cloud catchup sweep).
|
|
74
76
|
- If running in **Local Agent** (`$LOCAL_AGENT`): Scan mode reviews any ready PR across all priorities (P0 → P1 → P2 → P3) with no age gating.
|
|
@@ -78,8 +80,21 @@ Check if `$PR_NUMBER` is set:
|
|
|
78
80
|
|
|
79
81
|
### Step 3: Round tracking & Starting Review marker
|
|
80
82
|
|
|
81
|
-
- Post a "Starting review (round N)" comment on the target PR to claim the review window
|
|
83
|
+
- Post a "Starting review (round N)" comment on the target PR to claim the review window:
|
|
84
|
+
- If `$ROUTINE_ISSUE_NUMBER` is set in the environment or routine prompt, include a link to the tracking log issue:
|
|
85
|
+
`Starting review (round N) · [Run Log #$ROUTINE_ISSUE_NUMBER](${GITHUB_SERVER_URL:-https://github.com}/${GITHUB_REPOSITORY}/issues/${ROUTINE_ISSUE_NUMBER})`
|
|
86
|
+
(or `Starting review (round N) · Run log: #$ROUTINE_ISSUE_NUMBER`).
|
|
87
|
+
- If `$ROUTINE_ISSUE_NUMBER` is not set, post `Starting review (round N)`.
|
|
82
88
|
- Check round count `N`. If `N >= 5` and blocking findings persist, prepare to escalate.
|
|
89
|
+
- **Milestone 1 (Intake & Review Scope)**: If `$ROUTINE_ISSUE_NUMBER` is set, emit milestone card to the routine issue thread:
|
|
90
|
+
```bash
|
|
91
|
+
gh issue comment "$ROUTINE_ISSUE_NUMBER" --body "### 🧭 Milestone: Intake & Review Scope
|
|
92
|
+
- **Phase**: \`Phase 1 · Review Target & Scope\`
|
|
93
|
+
- **Status**: ⏳ In Progress
|
|
94
|
+
- **Target / Context**: \`PR #<PR_NUMBER> (Round N)\`
|
|
95
|
+
- **Key Decision / Finding**: Claimed review window; starting multi-angle evaluation passes.
|
|
96
|
+
- **Next**: Multi-Angle Code Review Pass" || true
|
|
97
|
+
```
|
|
83
98
|
|
|
84
99
|
### Step 4: Multi-Angle Code Review Pass
|
|
85
100
|
|
|
@@ -98,12 +113,14 @@ Check if `$PR_NUMBER` is set:
|
|
|
98
113
|
### Step 5: Classify Findings & Make Decision
|
|
99
114
|
|
|
100
115
|
Classify each finding:
|
|
116
|
+
|
|
101
117
|
- **Blocking**: Broken logic, security hole, data loss, regression, broken tests, missing deliverable from the issue/PR specification.
|
|
102
118
|
- **Non-blocking**: Minor refactor, style preference, performance micro-optimization, missing `Closes #N` on contributor PRs with self-contained descriptions.
|
|
103
119
|
|
|
104
120
|
### Step 5.5: Autonomous Issue Synthesis (for unlinked PRs)
|
|
105
121
|
|
|
106
122
|
If the PR is clean and approved for merge, but lacks a `Closes #N` tracking link:
|
|
123
|
+
|
|
107
124
|
1. Synthesize a retroactive tracking issue on GitHub:
|
|
108
125
|
```bash
|
|
109
126
|
gh issue create --title "<PR Title>" --body "Tracked retroactively from external pull request #<PR_NUMBER>.\n\n## Deliverables & Context\n<PR Description>\n\n_Synthesized autonomously by Jonah Fleet Peer Review_"
|
|
@@ -120,17 +137,35 @@ If the PR is clean and approved for merge, but lacks a `Closes #N` tracking link
|
|
|
120
137
|
- If `N < 5`: Post inline comments, submit review as `COMMENT`, and convert PR to draft (`gh pr ready <N> --undo`).
|
|
121
138
|
- If `N >= 5`: Convert PR to draft, post summary comment escalating to repo maintainer, and apply `needs-human` label.
|
|
122
139
|
- **If Clean (or only Non-blocking findings)**:
|
|
140
|
+
- If the PR branch has minor mechanical merge conflicts against `origin/main` (e.g. adjacent `CHANGELOG.md` entries from concurrent merges) while code and tests are sound, resolve the conflict mechanically via `/resolving-merge-conflicts` before squash-merging rather than bouncing the PR back to draft.
|
|
123
141
|
- If PR lacks `Closes #N`, execute Autonomous Issue Synthesis (Step 5.5).
|
|
142
|
+
- Extract the tracking issue number `$ISSUE_NUMBER` from the PR description or title (e.g. `Closes #<N>`, `Fixes #<N>`, `Resolves #<N>`).
|
|
124
143
|
- Squash-merge the PR: `gh pr merge <N> --squash --delete-branch`.
|
|
144
|
+
- **Explicit Tracking Issue Closure Guardrail**: If a tracking issue was referenced (`$ISSUE_NUMBER`), explicitly close it immediately after merge rather than relying solely on GitHub's native keyword parser (which often fails to trigger on bot-merged squash commits or draft PRs):
|
|
145
|
+
```bash
|
|
146
|
+
gh issue close "$ISSUE_NUMBER" --comment "Closed via PR #<N> (merged into main)."
|
|
147
|
+
```
|
|
125
148
|
- Submit held review comments.
|
|
149
|
+
- In any review summary, decision comment, or escalation comment posted to the PR, include the run log reference if `$ROUTINE_ISSUE_NUMBER` is set (e.g. `- **Run Log**: [#$ROUTINE_ISSUE_NUMBER](${GITHUB_SERVER_URL:-https://github.com}/${GITHUB_REPOSITORY}/issues/${ROUTINE_ISSUE_NUMBER})`).
|
|
126
150
|
- File follow-up issues for material non-blocking findings.
|
|
127
151
|
- If mechanical doc fixes are needed, commit directly to `main`.
|
|
128
152
|
|
|
129
153
|
## Logging
|
|
130
154
|
|
|
131
|
-
After completing (SUCCESS or FAILURE),
|
|
155
|
+
After completing (SUCCESS or FAILURE), record run execution details to `.jonah-fleet/run-report.md`. Include:
|
|
156
|
+
|
|
132
157
|
- Prompt SHA
|
|
133
158
|
- Target PR number and decision (MERGE / BOUNCE / ESCALATE)
|
|
134
159
|
- Execution trace and findings summary
|
|
135
160
|
|
|
136
|
-
**
|
|
161
|
+
**Issue Logging Protocol**:
|
|
162
|
+
- **Milestone 4 (Run Completed)**: If `$ROUTINE_ISSUE_NUMBER` is set, emit compact milestone card to close out the comment stream:
|
|
163
|
+
```bash
|
|
164
|
+
gh issue comment "$ROUTINE_ISSUE_NUMBER" --body "### 🏁 Milestone: Run Completed
|
|
165
|
+
- **Phase**: \`Phase 4 · Reconciliation\`
|
|
166
|
+
- **Status**: ✅ SUCCESS
|
|
167
|
+
- **Target / Context**: \`PR #<PR_NUMBER>\`
|
|
168
|
+
- **Key Decision / Finding**: Review completed with decision \`<MERGE | BOUNCE | ESCALATE>\`.
|
|
169
|
+
- **Next**: Routine finished; issue closed by harness" || true
|
|
170
|
+
```
|
|
171
|
+
- Follow the Routine Issue Logging & Telemetry Protocol in `ORCHESTRATION.md`. Never commit run logs to git branches.
|
|
@@ -11,8 +11,8 @@ This routine runs behind a **human approval gate**: it **never files autowork-re
|
|
|
11
11
|
This routine runs in two modes: **Propose** (scheduled cron sweep / unapproved fire) and **Promote** (operator-approved fire).
|
|
12
12
|
|
|
13
13
|
In **Propose mode**, SUCCESS requires:
|
|
14
|
-
- [ ] Read current roadmap, domain documentation, closed measurement trackers,
|
|
15
|
-
- [ ] Performed Feature Pruning & Deprecation Audit: evaluated shipped features
|
|
14
|
+
- [ ] Read current roadmap, domain documentation, closed measurement trackers, recent feedback/analytics findings, and the latest open `🎨 Design Review` issue / recent design-review routine run issues
|
|
15
|
+
- [ ] Performed Feature Pruning & Deprecation Audit: evaluated shipped features, measurement outcomes (<2% user adoption or >50% failure rate), and Design Review pruning/clutter directives, drafting deprecation, removal, or simplification proposals
|
|
16
16
|
- [ ] Created or updated exactly one dated staging issue (`🗺️ Product Plan — {date}`) containing:
|
|
17
17
|
- Up to 3 well-scoped proposals (Summary/Tasks/Why/Complexity), covering additions, pivots, or deprecations
|
|
18
18
|
- Backlog re-ranking recommendations
|
|
@@ -51,10 +51,10 @@ If any criterion cannot be met, stop immediately and log FAILURE with the reason
|
|
|
51
51
|
|
|
52
52
|
### Steps 1–3: Propose Mode (Staging Proposals)
|
|
53
53
|
|
|
54
|
-
1. Read `ROADMAP.md`, `AGENTS.md`, closed measurement trackers with `RECOMMENDATION: [PIVOT | DEPRECATE | ITERATE]`, and open issues.
|
|
54
|
+
1. Read `ROADMAP.md`, `AGENTS.md`, closed measurement trackers with `RECOMMENDATION: [PIVOT | DEPRECATE | ITERATE]`, the latest open `🎨 Design Review` issue (and recent run issues with `gh issue list --label "routine:design-review"`), and open issues.
|
|
55
55
|
2. **Feature Pruning & Deprecation Audit**:
|
|
56
|
-
- Audit shipped features
|
|
57
|
-
- For any feature with <2% user adoption, sub-threshold CTR,
|
|
56
|
+
- Audit shipped features, closed measurement tracker verdicts, and `🎨 Design Review` clutter/pruning findings.
|
|
57
|
+
- For any feature with <2% user adoption, sub-threshold CTR, >50% failure rate, or persistent UI clutter flagged by Design Review, draft explicit deprecation, removal, or pivot proposals to keep the codebase lean and eliminate maintenance waste.
|
|
58
58
|
3. Draft up to 3 high-impact proposals (including additions, pivots, or deprecations) based on roadmap priorities, measurement outcomes, and user feedback.
|
|
59
59
|
4. For proposals sized `size/M` or above, draft a formal specification using `/to-spec`.
|
|
60
60
|
5. Stage all proposals in a dedicated staging issue: `🗺️ Product Plan — {YYYY-MM-DD}` assigned to the repo maintainer.
|
|
@@ -70,9 +70,13 @@ If any criterion cannot be met, stop immediately and log FAILURE with the reason
|
|
|
70
70
|
|
|
71
71
|
## Logging
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-
|
|
73
|
+
Follow the Routine Issue Logging Protocol in `ORCHESTRATION.md`:
|
|
74
|
+
1. Write the final run report to `.jonah-fleet/run-report.md`.
|
|
75
|
+
2. Include the Run Summary table with:
|
|
76
|
+
- Routine: `product-planning`
|
|
77
|
+
- Mode: `Propose` or `Promote`
|
|
78
|
+
- Result: `SUCCESS` or `FAILURE`
|
|
79
|
+
- Prompt SHA: (run `git rev-parse --short HEAD:.github/prompts/product-planning.md` or template)
|
|
80
|
+
- Staged or promoted proposals tally
|
|
81
|
+
3. The surrounding execution harness will reconcile the corresponding GitHub issue.
|
|
77
82
|
|
|
78
|
-
**Important**: Commit the log file directly to `main` and push. Follow the Log delivery fallback in `ORCHESTRATION.md` if direct push fails.
|
|
@@ -24,7 +24,7 @@ concurrency:
|
|
|
24
24
|
jobs:
|
|
25
25
|
run-autowork:
|
|
26
26
|
runs-on: ubuntu-latest
|
|
27
|
-
timeout-minutes:
|
|
27
|
+
timeout-minutes: 70
|
|
28
28
|
permissions:
|
|
29
29
|
contents: write
|
|
30
30
|
issues: write
|
|
@@ -37,7 +37,7 @@ jobs:
|
|
|
37
37
|
with:
|
|
38
38
|
fetch-depth: 0
|
|
39
39
|
token: ${{ secrets.GH_PAT || github.token }}
|
|
40
|
-
|
|
40
|
+
persist-credentials: false
|
|
41
41
|
|
|
42
42
|
- name: Setup Node.js
|
|
43
43
|
uses: actions/setup-node@v4
|
|
@@ -45,10 +45,13 @@ jobs:
|
|
|
45
45
|
node-version: 22
|
|
46
46
|
|
|
47
47
|
- name: Configure Git author identity
|
|
48
|
+
env:
|
|
49
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
48
50
|
run: |
|
|
49
51
|
git config --global user.name "github-actions[bot]"
|
|
50
52
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
51
53
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
54
|
+
gh auth setup-git
|
|
52
55
|
|
|
53
56
|
- name: Cache Antigravity CLI
|
|
54
57
|
id: cache-agy
|
|
@@ -105,6 +108,74 @@ jobs:
|
|
|
105
108
|
fi
|
|
106
109
|
echo "skills_prompt=$SKILLS_PROMPT" >> "$GITHUB_OUTPUT"
|
|
107
110
|
|
|
111
|
+
- name: Resolve routine configuration
|
|
112
|
+
id: routine-config
|
|
113
|
+
run: |
|
|
114
|
+
ROUTINE="autowork"
|
|
115
|
+
DEFAULT_MODEL="gemini-3.8-flash-high"
|
|
116
|
+
DEFAULT_TIMEOUT="60"
|
|
117
|
+
|
|
118
|
+
MODEL="$DEFAULT_MODEL"
|
|
119
|
+
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
120
|
+
|
|
121
|
+
if [ -f "agents-manifest.json" ]; then
|
|
122
|
+
CONFIG_JSON=$(node -e '
|
|
123
|
+
try {
|
|
124
|
+
const fs = require("fs");
|
|
125
|
+
const m = JSON.parse(fs.readFileSync("agents-manifest.json", "utf8"));
|
|
126
|
+
const r = process.argv[1];
|
|
127
|
+
const model = m.models?.[r] || m.models?.default;
|
|
128
|
+
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
129
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "" }));
|
|
130
|
+
} catch (e) {
|
|
131
|
+
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
132
|
+
}
|
|
133
|
+
' "$ROUTINE")
|
|
134
|
+
|
|
135
|
+
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
136
|
+
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
137
|
+
|
|
138
|
+
if [ -n "$RESOLVED_MODEL" ]; then
|
|
139
|
+
MODEL="$RESOLVED_MODEL"
|
|
140
|
+
fi
|
|
141
|
+
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
142
|
+
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
143
|
+
fi
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
147
|
+
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
148
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
149
|
+
|
|
150
|
+
- name: Initialize Routine Run Issue
|
|
151
|
+
id: run-issue
|
|
152
|
+
env:
|
|
153
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
154
|
+
TARGET_ARG: ${{ inputs.target_issue || inputs.issue_number }}
|
|
155
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
156
|
+
RUN_ID: ${{ github.run_id }}
|
|
157
|
+
SERVER_URL: ${{ github.server_url }}
|
|
158
|
+
REPOSITORY: ${{ github.repository }}
|
|
159
|
+
run: |
|
|
160
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
161
|
+
if [ -n "$TARGET_ARG" ]; then
|
|
162
|
+
TITLE="[autowork] run ${TIMESTAMP} (Issue #${TARGET_ARG})"
|
|
163
|
+
else
|
|
164
|
+
TITLE="[autowork] run ${TIMESTAMP}"
|
|
165
|
+
fi
|
|
166
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
167
|
+
- **Routine**: \`autowork\`
|
|
168
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
169
|
+
- **Trigger**: \`${EVENT_NAME}\`
|
|
170
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
174
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:autowork,status:running,runner:github-actions")
|
|
175
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
176
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
177
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
178
|
+
|
|
108
179
|
- name: Run Autowork
|
|
109
180
|
timeout-minutes: 60
|
|
110
181
|
env:
|
|
@@ -113,7 +184,10 @@ jobs:
|
|
|
113
184
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
114
185
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
115
186
|
TARGET_ISSUE: ${{ inputs.target_issue || inputs.issue_number }}
|
|
187
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
116
188
|
SKILLS_PROMPT: ${{ steps.skills.outputs.skills_prompt }}
|
|
189
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-high' }}
|
|
190
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '60m' }}
|
|
117
191
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
118
192
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
119
193
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -125,17 +199,17 @@ jobs:
|
|
|
125
199
|
fi
|
|
126
200
|
|
|
127
201
|
agy -p "$PROMPT" \
|
|
128
|
-
--model
|
|
202
|
+
--model "$MODEL" \
|
|
129
203
|
--output-format text \
|
|
130
|
-
--print-timeout
|
|
204
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
131
205
|
--dangerously-skip-permissions
|
|
132
206
|
|
|
133
207
|
- name: Emit run summary
|
|
134
208
|
if: always()
|
|
135
209
|
run: |
|
|
136
|
-
|
|
137
|
-
if [ -
|
|
138
|
-
cat "$
|
|
210
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
211
|
+
if [ -f "$REPORT_FILE" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
|
|
212
|
+
cat "$REPORT_FILE" >> "$GITHUB_STEP_SUMMARY"
|
|
139
213
|
fi
|
|
140
214
|
|
|
141
215
|
- name: Emit Fleet Telemetry (Opt-in)
|
|
@@ -147,9 +221,9 @@ jobs:
|
|
|
147
221
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
148
222
|
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
149
223
|
run: |
|
|
150
|
-
|
|
151
|
-
if [ -
|
|
152
|
-
npx --yes jonah-fleet telemetry --emit --log "$
|
|
224
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
225
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
226
|
+
npx --yes jonah-fleet telemetry --emit --log "$REPORT_FILE" --endpoint "$TELEMETRY_ENDPOINT" || true
|
|
153
227
|
fi
|
|
154
228
|
|
|
155
229
|
- name: Verify Atomic Handoff Invariant (PR Existence Guard)
|
|
@@ -157,10 +231,10 @@ jobs:
|
|
|
157
231
|
env:
|
|
158
232
|
GH_TOKEN: ${{ github.token }}
|
|
159
233
|
run: |
|
|
160
|
-
|
|
161
|
-
if [ -
|
|
162
|
-
if grep -q "Result.*SUCCESS" "$
|
|
163
|
-
WORKED_BRANCH=$(grep -E '^\s*-\s*(Pushed branch|Branch):' "$
|
|
234
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
235
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
236
|
+
if grep -q "Result.*SUCCESS" "$REPORT_FILE"; then
|
|
237
|
+
WORKED_BRANCH=$(grep -E '^\s*-\s*(Pushed branch|Branch):' "$REPORT_FILE" | head -n 1 | sed -E 's/.*`([^`]+)`.*/\1/')
|
|
164
238
|
if [ -n "$WORKED_BRANCH" ] && [[ "$WORKED_BRANCH" =~ (feat|fix)/ ]]; then
|
|
165
239
|
echo "Verifying PR existence for branch: $WORKED_BRANCH"
|
|
166
240
|
PR_COUNT=$(gh pr list --head "$WORKED_BRANCH" --state all --json number --jq 'length' 2>/dev/null || echo "0")
|
|
@@ -173,33 +247,58 @@ jobs:
|
|
|
173
247
|
fi
|
|
174
248
|
fi
|
|
175
249
|
|
|
176
|
-
- name:
|
|
250
|
+
- name: Reconcile Routine Run Issue
|
|
177
251
|
if: always()
|
|
178
252
|
env:
|
|
179
253
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
254
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
255
|
+
JOB_STATUS: ${{ job.status }}
|
|
256
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
257
|
+
RUN_ID: ${{ github.run_id }}
|
|
258
|
+
SERVER_URL: ${{ github.server_url }}
|
|
259
|
+
REPOSITORY: ${{ github.repository }}
|
|
180
260
|
run: |
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
261
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
262
|
+
echo "No routine issue to reconcile."
|
|
263
|
+
exit 0
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
267
|
+
|
|
268
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
269
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
270
|
+
else
|
|
271
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
272
|
+
- **Routine**: \`autowork\`
|
|
273
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
274
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
281
|
+
|
|
282
|
+
TEMP_BODY=$(mktemp)
|
|
283
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
284
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
285
|
+
rm -f "$TEMP_BODY"
|
|
286
|
+
|
|
287
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
288
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
289
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
290
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
291
|
+
else
|
|
292
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
293
|
+
- **Routine**: \`autowork\`
|
|
294
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
295
|
+
- **Step**: Actions execution halted before normal completion
|
|
296
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
300
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
301
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
302
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
204
303
|
fi
|
|
205
304
|
|
|
@@ -25,6 +25,7 @@ jobs:
|
|
|
25
25
|
uses: actions/checkout@v4
|
|
26
26
|
with:
|
|
27
27
|
fetch-depth: 0
|
|
28
|
+
persist-credentials: false
|
|
28
29
|
|
|
29
30
|
- name: Setup Node.js
|
|
30
31
|
uses: actions/setup-node@v4
|
|
@@ -32,10 +33,13 @@ jobs:
|
|
|
32
33
|
node-version: 22
|
|
33
34
|
|
|
34
35
|
- name: Configure Git author identity
|
|
36
|
+
env:
|
|
37
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
35
38
|
run: |
|
|
36
39
|
git config --global user.name "github-actions[bot]"
|
|
37
40
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
38
41
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
42
|
+
gh auth setup-git
|
|
39
43
|
|
|
40
44
|
- name: Cache Antigravity CLI
|
|
41
45
|
id: cache-agy
|
|
@@ -65,6 +69,69 @@ jobs:
|
|
|
65
69
|
printf '%s' "$ANTIGRAVITY_OAUTH_TOKEN" > "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
66
70
|
chmod 600 "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
67
71
|
|
|
72
|
+
- name: Resolve routine configuration
|
|
73
|
+
id: routine-config
|
|
74
|
+
run: |
|
|
75
|
+
ROUTINE="dependency-update-security-check"
|
|
76
|
+
DEFAULT_MODEL="gemini-3.8-flash-medium"
|
|
77
|
+
DEFAULT_TIMEOUT="25"
|
|
78
|
+
|
|
79
|
+
MODEL="$DEFAULT_MODEL"
|
|
80
|
+
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
81
|
+
|
|
82
|
+
if [ -f "agents-manifest.json" ]; then
|
|
83
|
+
CONFIG_JSON=$(node -e '
|
|
84
|
+
try {
|
|
85
|
+
const fs = require("fs");
|
|
86
|
+
const m = JSON.parse(fs.readFileSync("agents-manifest.json", "utf8"));
|
|
87
|
+
const r = process.argv[1];
|
|
88
|
+
const model = m.models?.[r] || m.models?.default;
|
|
89
|
+
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
90
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "" }));
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
93
|
+
}
|
|
94
|
+
' "$ROUTINE")
|
|
95
|
+
|
|
96
|
+
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
97
|
+
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
98
|
+
|
|
99
|
+
if [ -n "$RESOLVED_MODEL" ]; then
|
|
100
|
+
MODEL="$RESOLVED_MODEL"
|
|
101
|
+
fi
|
|
102
|
+
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
103
|
+
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
104
|
+
fi
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
108
|
+
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
109
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
110
|
+
|
|
111
|
+
- name: Initialize Routine Run Issue
|
|
112
|
+
id: run-issue
|
|
113
|
+
env:
|
|
114
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
115
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
116
|
+
RUN_ID: ${{ github.run_id }}
|
|
117
|
+
SERVER_URL: ${{ github.server_url }}
|
|
118
|
+
REPOSITORY: ${{ github.repository }}
|
|
119
|
+
run: |
|
|
120
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
121
|
+
TITLE="[dependency-check] run ${TIMESTAMP}"
|
|
122
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
123
|
+
- **Routine**: \`dependency-update-security-check\`
|
|
124
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
125
|
+
- **Trigger**: \`${EVENT_NAME}\`
|
|
126
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
130
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:dependency-check,status:running,runner:github-actions")
|
|
131
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
132
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
133
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
134
|
+
|
|
68
135
|
- name: Run Dependency Update Check
|
|
69
136
|
timeout-minutes: 25
|
|
70
137
|
env:
|
|
@@ -72,6 +139,9 @@ jobs:
|
|
|
72
139
|
GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
73
140
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
74
141
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
142
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
143
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-medium' }}
|
|
144
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '25m' }}
|
|
75
145
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
76
146
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
77
147
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -79,7 +149,62 @@ jobs:
|
|
|
79
149
|
PROMPT="You are the Dependency Update & Security Check routine. Read and follow .github/prompts/dependency-update-security-check.md exactly. Check dependencies for updates and vulnerabilities, and create or update tracking issues."
|
|
80
150
|
|
|
81
151
|
agy -p "$PROMPT" \
|
|
82
|
-
--model
|
|
152
|
+
--model "$MODEL" \
|
|
83
153
|
--output-format text \
|
|
84
|
-
--print-timeout
|
|
154
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
85
155
|
--dangerously-skip-permissions
|
|
156
|
+
|
|
157
|
+
- name: Reconcile Routine Run Issue
|
|
158
|
+
if: always()
|
|
159
|
+
env:
|
|
160
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
161
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
162
|
+
JOB_STATUS: ${{ job.status }}
|
|
163
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
164
|
+
RUN_ID: ${{ github.run_id }}
|
|
165
|
+
SERVER_URL: ${{ github.server_url }}
|
|
166
|
+
REPOSITORY: ${{ github.repository }}
|
|
167
|
+
run: |
|
|
168
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
169
|
+
echo "No routine issue to reconcile."
|
|
170
|
+
exit 0
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
174
|
+
|
|
175
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
176
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
177
|
+
else
|
|
178
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
179
|
+
- **Routine**: \`dependency-update-security-check\`
|
|
180
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
181
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
188
|
+
|
|
189
|
+
TEMP_BODY=$(mktemp)
|
|
190
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
191
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
192
|
+
rm -f "$TEMP_BODY"
|
|
193
|
+
|
|
194
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
195
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
196
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
197
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
198
|
+
else
|
|
199
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
200
|
+
- **Routine**: \`dependency-check\`
|
|
201
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
202
|
+
- **Step**: Actions execution halted before normal completion
|
|
203
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
207
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
208
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
209
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
210
|
+
fi
|