jonah-fleet 1.10.0 → 1.12.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 +27 -0
- package/dist/index.js +243 -11
- package/dist/lib/daemon.d.ts +20 -0
- package/dist/lib/daemon.d.ts.map +1 -1
- package/dist/lib/runner.d.ts +23 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/prompts/ORCHESTRATION.md +21 -6
- package/templates/prompts/autowork.md +2 -0
- package/templates/prompts/peer-review.md +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ 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.12.0](https://github.com/juliendurandeu/jonah-fleet/compare/v1.11.0...v1.12.0) (2026-09-18)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **radar:** add zqiren/Orbital to ecosystem radar and evaluation matrix ([#212](https://github.com/juliendurandeu/jonah-fleet/issues/212)) ([910febb](https://github.com/juliendurandeu/jonah-fleet/commit/910febbbc8196d53c20f05730770aae231a6b8ea)), closes [#206](https://github.com/juliendurandeu/jonah-fleet/issues/206)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* **runner:** prevent premature routine termination on async background tasks in headless mode ([6641b2b](https://github.com/juliendurandeu/jonah-fleet/commit/6641b2b2e46ab363b73d490aac1144a33a1c69f9))
|
|
19
|
+
|
|
20
|
+
## [Unreleased] - 2026-09-18
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* **runner:** detect premature routine termination caused by async background task turn yielding in headless CLI mode (`agy -p`), preventing false-positive success logging on uncompleted runs.
|
|
25
|
+
* **prompts:** add Headless Execution & Asynchronous Non-Yielding Guardrail across `peer-review.md`, `autowork.md`, and `ORCHESTRATION.md` with explicit remote CI trust bar to eliminate redundant verification stalling.
|
|
26
|
+
|
|
27
|
+
## [1.11.0](https://github.com/juliendurandeu/jonah-fleet/compare/v1.10.0...v1.11.0) (2026-09-17)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* **daemon:** auto-reconcile orphaned local routine runs on startup ([#188](https://github.com/juliendurandeu/jonah-fleet/issues/188)) ([dcc7746](https://github.com/juliendurandeu/jonah-fleet/commit/dcc7746268cd1921dbfb8e23c57ac46cf9217b83))
|
|
33
|
+
|
|
8
34
|
## [1.10.0](https://github.com/juliendurandeu/jonah-fleet/compare/v1.9.2...v1.10.0) (2026-09-17)
|
|
9
35
|
|
|
10
36
|
|
|
@@ -58,6 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
58
84
|
|
|
59
85
|
### Features
|
|
60
86
|
|
|
87
|
+
* **daemon:** auto-reconcile orphaned local routine run issues on daemon startup after host reboots or process crashes.
|
|
61
88
|
* **radar:** expand Category A heuristics in `fetch-symphony-radar.js` to detect prompt engineering optimizations and release `tag_name` fallbacks, prioritize Category A invariants over runtime keywords, and refine empty lookback checklist phrasing ([#184](https://github.com/juliendurandeu/jonah-fleet/issues/184)).
|
|
62
89
|
* **radar:** deterministically classify upstream changes across Symphony and Funes into Category A/B/C and surface architectural opportunities with callout summaries, breakdown matrices, and dynamic triage checklists ([#152](https://github.com/juliendurandeu/jonah-fleet/issues/152)).
|
|
63
90
|
* **telemetry:** introduce live progress reporting in routine run tracking issues (`routine-log`) using bounded Compact Milestone Cards (3–5 bullet points for Intake & Strategy, Verification & Tests, Autonomous Handoff, and Run Completed) across `autowork`, `peer-review`, `optimizer`, and `ORCHESTRATION.md`.
|
package/dist/index.js
CHANGED
|
@@ -2656,7 +2656,8 @@ import pc11 from "picocolors";
|
|
|
2656
2656
|
import fs12 from "fs";
|
|
2657
2657
|
import path12 from "path";
|
|
2658
2658
|
import os2 from "os";
|
|
2659
|
-
import { spawn, execSync as execSync2 } from "child_process";
|
|
2659
|
+
import { spawn, execSync as execSync2, execFile as execFile4 } from "child_process";
|
|
2660
|
+
import { promisify as promisify4 } from "util";
|
|
2660
2661
|
|
|
2661
2662
|
// src/lib/worktree.ts
|
|
2662
2663
|
import fs10 from "fs";
|
|
@@ -3496,6 +3497,7 @@ var TerminalSpinner = class {
|
|
|
3496
3497
|
|
|
3497
3498
|
// src/lib/runner.ts
|
|
3498
3499
|
import pc10 from "picocolors";
|
|
3500
|
+
var execFileAsync4 = promisify4(execFile4);
|
|
3499
3501
|
var LineBufferedStreamParser = class {
|
|
3500
3502
|
buffer = "";
|
|
3501
3503
|
onLine;
|
|
@@ -3610,19 +3612,20 @@ function buildRoutinePrompt(targetDir, routine, options = {}) {
|
|
|
3610
3612
|
const promptFile = `.github/prompts/${routine}.md`;
|
|
3611
3613
|
const repoContext = `Working repository is located at ${targetDir}. All git, gh, and workspace commands must execute strictly within this repository.`;
|
|
3612
3614
|
const logPrompt = options.routineIssueNumber ? ` Tracking run log issue: #${options.routineIssueNumber}.` : "";
|
|
3615
|
+
const headlessGuardrail = ` Execution Guardrail: You are executing in a headless autonomous session. You MUST NEVER call schedule or yield your turn with plain text to wait on background tasks or verification checks. If a verification command (tests, type-check, lint) runs in the background, actively inspect its completion with manage_task or execute commands with sufficient WaitMsBeforeAsync. Never stop calling tools or yield your turn until the routine's terminal Definition of Done is fully reached.`;
|
|
3613
3616
|
if (routine === "autowork") {
|
|
3614
3617
|
if (options.issue) {
|
|
3615
|
-
return `You are the Autowork routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}Your target is issue #${options.issue}. You are in Targeted mode: work issue #${options.issue} directly, ahead of Phase 1 convergence and priority scan.${logPrompt}`;
|
|
3618
|
+
return `You are the Autowork routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}Your target is issue #${options.issue}. You are in Targeted mode: work issue #${options.issue} directly, ahead of Phase 1 convergence and priority scan.${logPrompt}${headlessGuardrail}`;
|
|
3616
3619
|
}
|
|
3617
|
-
return `You are the Autowork routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}You are in Scan mode: check open PRs for review comments to fix, close merged issues, then pick the highest-priority unclaimed issue.${logPrompt}`;
|
|
3620
|
+
return `You are the Autowork routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}You are in Scan mode: check open PRs for review comments to fix, close merged issues, then pick the highest-priority unclaimed issue.${logPrompt}${headlessGuardrail}`;
|
|
3618
3621
|
}
|
|
3619
3622
|
if (routine === "peer-review") {
|
|
3620
3623
|
if (options.pr) {
|
|
3621
|
-
return `You are the Peer Review routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}Your target is pull request #${options.pr}. You are in Targeted mode: review PR #${options.pr} directly.${logPrompt}`;
|
|
3624
|
+
return `You are the Peer Review routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}Your target is pull request #${options.pr}. You are in Targeted mode: review PR #${options.pr} directly.${logPrompt}${headlessGuardrail}`;
|
|
3622
3625
|
}
|
|
3623
|
-
return `You are the Peer Review routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}You are in Scan mode: check open PRs and select the highest-priority PR to review.${logPrompt}`;
|
|
3626
|
+
return `You are the Peer Review routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}You are in Scan mode: check open PRs and select the highest-priority PR to review.${logPrompt}${headlessGuardrail}`;
|
|
3624
3627
|
}
|
|
3625
|
-
return `You are the ${routine} routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}${logPrompt}`;
|
|
3628
|
+
return `You are the ${routine} routine for this repository. ${repoContext} Read and follow the instructions in ${promptFile} exactly. ${skillsPrompt}${logPrompt}${headlessGuardrail}`;
|
|
3626
3629
|
}
|
|
3627
3630
|
function tryCreateLocalRunIssue(cwd, routine, timestamp, targetLabel, hostname) {
|
|
3628
3631
|
try {
|
|
@@ -3677,6 +3680,25 @@ function tryPostLocalRunMilestone(cwd, issueNumber, cardContent) {
|
|
|
3677
3680
|
} catch {
|
|
3678
3681
|
}
|
|
3679
3682
|
}
|
|
3683
|
+
async function tryPostLocalRunMilestoneAsync(cwd, issueNumber, cardContent) {
|
|
3684
|
+
const tmpFile = path12.join(os2.tmpdir(), `jonah-fleet-milestone-${issueNumber}-${Date.now()}.md`);
|
|
3685
|
+
try {
|
|
3686
|
+
await fs12.promises.writeFile(tmpFile, cardContent, "utf8");
|
|
3687
|
+
await execFileAsync4("gh", ["issue", "comment", String(issueNumber), "--body-file", tmpFile], {
|
|
3688
|
+
cwd
|
|
3689
|
+
});
|
|
3690
|
+
return true;
|
|
3691
|
+
} catch {
|
|
3692
|
+
return false;
|
|
3693
|
+
} finally {
|
|
3694
|
+
try {
|
|
3695
|
+
if (fs12.existsSync(tmpFile)) {
|
|
3696
|
+
await fs12.promises.unlink(tmpFile);
|
|
3697
|
+
}
|
|
3698
|
+
} catch {
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3680
3702
|
function tryReconcileLocalRunIssue(cwd, issueNumber, reportContent, exitCode, hostname, routine) {
|
|
3681
3703
|
try {
|
|
3682
3704
|
if (exitCode !== 0) {
|
|
@@ -3721,6 +3743,76 @@ _Generated by Jonah Fleet local runner on ${hostname}._`;
|
|
|
3721
3743
|
} catch {
|
|
3722
3744
|
}
|
|
3723
3745
|
}
|
|
3746
|
+
async function tryMarkLocalRunInterruptedAsync(cwd, issueNumber, hostname, reason = "Host machine process terminated mid-execution (machine reboot or SIGKILL)", routine = "local-routine") {
|
|
3747
|
+
try {
|
|
3748
|
+
const interruptionCard = formatInterruptionCard({
|
|
3749
|
+
routine,
|
|
3750
|
+
status: reason,
|
|
3751
|
+
runner: `local (${hostname})`,
|
|
3752
|
+
step: "Local execution interrupted before completion"
|
|
3753
|
+
});
|
|
3754
|
+
await tryPostLocalRunMilestoneAsync(cwd, issueNumber, interruptionCard);
|
|
3755
|
+
await execFileAsync4(
|
|
3756
|
+
"gh",
|
|
3757
|
+
["issue", "edit", String(issueNumber), "--add-label", "status:failure,needs-attention", "--remove-label", "status:running"],
|
|
3758
|
+
{ cwd }
|
|
3759
|
+
);
|
|
3760
|
+
return true;
|
|
3761
|
+
} catch {
|
|
3762
|
+
return false;
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
async function tryReconcileLocalRunIssueAsync(cwd, issueNumber, reportContent, exitCode, hostname, routine) {
|
|
3766
|
+
try {
|
|
3767
|
+
if (exitCode !== 0) {
|
|
3768
|
+
const interruptionCard = formatInterruptionCard({
|
|
3769
|
+
routine: routine || "local-routine",
|
|
3770
|
+
status: `exit code ${exitCode}`,
|
|
3771
|
+
runner: `local (${hostname})`
|
|
3772
|
+
});
|
|
3773
|
+
await tryPostLocalRunMilestoneAsync(cwd, issueNumber, interruptionCard);
|
|
3774
|
+
}
|
|
3775
|
+
const finalBody = `${reportContent}
|
|
3776
|
+
|
|
3777
|
+
---
|
|
3778
|
+
_Generated by Jonah Fleet local runner on ${hostname}._`;
|
|
3779
|
+
const tmpFile = path12.join(os2.tmpdir(), `jonah-fleet-run-${issueNumber}-${Date.now()}.md`);
|
|
3780
|
+
await fs12.promises.writeFile(tmpFile, finalBody, "utf8");
|
|
3781
|
+
try {
|
|
3782
|
+
await execFileAsync4("gh", ["issue", "edit", String(issueNumber), "--body-file", tmpFile], {
|
|
3783
|
+
cwd
|
|
3784
|
+
});
|
|
3785
|
+
if (exitCode === 0) {
|
|
3786
|
+
await execFileAsync4(
|
|
3787
|
+
"gh",
|
|
3788
|
+
["issue", "edit", String(issueNumber), "--add-label", "status:success", "--remove-label", "status:running"],
|
|
3789
|
+
{ cwd }
|
|
3790
|
+
);
|
|
3791
|
+
await execFileAsync4(
|
|
3792
|
+
"gh",
|
|
3793
|
+
["issue", "close", String(issueNumber), "--reason", "completed"],
|
|
3794
|
+
{ cwd }
|
|
3795
|
+
);
|
|
3796
|
+
} else {
|
|
3797
|
+
await execFileAsync4(
|
|
3798
|
+
"gh",
|
|
3799
|
+
["issue", "edit", String(issueNumber), "--add-label", "status:failure,needs-attention", "--remove-label", "status:running"],
|
|
3800
|
+
{ cwd }
|
|
3801
|
+
);
|
|
3802
|
+
}
|
|
3803
|
+
return true;
|
|
3804
|
+
} finally {
|
|
3805
|
+
try {
|
|
3806
|
+
if (fs12.existsSync(tmpFile)) {
|
|
3807
|
+
await fs12.promises.unlink(tmpFile);
|
|
3808
|
+
}
|
|
3809
|
+
} catch {
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
} catch {
|
|
3813
|
+
return false;
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3724
3816
|
function extractFreshRunReport(executionReportPath, targetReportPath, startTime) {
|
|
3725
3817
|
try {
|
|
3726
3818
|
if (fs12.existsSync(executionReportPath)) {
|
|
@@ -3745,6 +3837,43 @@ function extractFreshRunReport(executionReportPath, targetReportPath, startTime)
|
|
|
3745
3837
|
function resolveExitCode(code, signal) {
|
|
3746
3838
|
return code ?? (signal ? 1 : 0);
|
|
3747
3839
|
}
|
|
3840
|
+
function detectPrematureRoutineExit(output, routine) {
|
|
3841
|
+
if (!output) return null;
|
|
3842
|
+
const prematureYieldPatterns = [
|
|
3843
|
+
/verification is in progress/i,
|
|
3844
|
+
/waiting for .* to (?:finish|complete)/i,
|
|
3845
|
+
/waiting for (?:test|type-check|check|task)/i,
|
|
3846
|
+
/check if .* finished/i,
|
|
3847
|
+
/task-.* is running/i
|
|
3848
|
+
];
|
|
3849
|
+
for (const pattern of prematureYieldPatterns) {
|
|
3850
|
+
if (pattern.test(output)) {
|
|
3851
|
+
const terminalSuccessPatterns = [
|
|
3852
|
+
/## (?:Run Summary|Execution Report)/i,
|
|
3853
|
+
/Milestone: Run Completed/i,
|
|
3854
|
+
/Squash-merged/i,
|
|
3855
|
+
/Merged PR/i,
|
|
3856
|
+
/converted .* to draft/i,
|
|
3857
|
+
/bounced .* to draft/i,
|
|
3858
|
+
/No PRs to review/i
|
|
3859
|
+
];
|
|
3860
|
+
const hasTerminalSuccess = terminalSuccessPatterns.some((p) => p.test(output));
|
|
3861
|
+
if (!hasTerminalSuccess) {
|
|
3862
|
+
return "Premature session termination: Agent yielded turn on background task before reaching Definition of Done.";
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
if (routine === "peer-review") {
|
|
3867
|
+
const startedReview = /Starting review/i.test(output);
|
|
3868
|
+
if (startedReview) {
|
|
3869
|
+
const terminalActionTaken = /Squash-merged/i.test(output) || /Merged PR/i.test(output) || /--undo/i.test(output) || /converted .* to draft/i.test(output) || /bounced .* to draft/i.test(output) || /needs-human/i.test(output) || /escalat/i.test(output) || /Milestone: Run Completed/i.test(output) || /Review completed with decision/i.test(output) || /No PRs to review/i.test(output);
|
|
3870
|
+
if (!terminalActionTaken) {
|
|
3871
|
+
return "Premature peer-review termination: Review was started but agent exited without executing terminal action (merge, draft bounce, or escalation).";
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
return null;
|
|
3876
|
+
}
|
|
3748
3877
|
function formatFallbackRunReport(options) {
|
|
3749
3878
|
const result = options.exitCode === 0 ? "SUCCESS" : "FAILURE";
|
|
3750
3879
|
let reportContent = `## Run Summary
|
|
@@ -4068,6 +4197,13 @@ Timeout: ${printTimeout}`,
|
|
|
4068
4197
|
const durationMs = Date.now() - startTime;
|
|
4069
4198
|
const durationSec = Math.round(durationMs / 1e3);
|
|
4070
4199
|
let reportContent = extractFreshRunReport(executionReportPath, targetReportPath, startTime) || "";
|
|
4200
|
+
let prematureError = null;
|
|
4201
|
+
if (exitCode === 0 && !reportContent) {
|
|
4202
|
+
prematureError = detectPrematureRoutineExit(output, routine);
|
|
4203
|
+
if (prematureError) {
|
|
4204
|
+
exitCode = 1;
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4071
4207
|
if (!reportContent) {
|
|
4072
4208
|
reportContent = formatFallbackRunReport({
|
|
4073
4209
|
routine,
|
|
@@ -4077,7 +4213,7 @@ Timeout: ${printTimeout}`,
|
|
|
4077
4213
|
targetLabel,
|
|
4078
4214
|
durationSec,
|
|
4079
4215
|
output,
|
|
4080
|
-
stderr: accumulatedStderr
|
|
4216
|
+
stderr: [accumulatedStderr, prematureError].filter(Boolean).join("\n")
|
|
4081
4217
|
});
|
|
4082
4218
|
}
|
|
4083
4219
|
try {
|
|
@@ -4222,8 +4358,9 @@ import pc14 from "picocolors";
|
|
|
4222
4358
|
// src/lib/daemon.ts
|
|
4223
4359
|
import fs14 from "fs";
|
|
4224
4360
|
import path14 from "path";
|
|
4225
|
-
import
|
|
4226
|
-
import {
|
|
4361
|
+
import os3 from "os";
|
|
4362
|
+
import { spawn as spawn2, execFile as execFile5 } from "child_process";
|
|
4363
|
+
import { promisify as promisify5 } from "util";
|
|
4227
4364
|
|
|
4228
4365
|
// src/lib/daemon-keys.ts
|
|
4229
4366
|
import readline2 from "readline";
|
|
@@ -4612,7 +4749,7 @@ function formatDaemonStatusLine(options = {}) {
|
|
|
4612
4749
|
|
|
4613
4750
|
// src/lib/daemon.ts
|
|
4614
4751
|
import pc13 from "picocolors";
|
|
4615
|
-
var
|
|
4752
|
+
var execFileAsync5 = promisify5(execFile5);
|
|
4616
4753
|
function getDaemonStatePath(repoRoot) {
|
|
4617
4754
|
return path14.join(repoRoot, ".jonah-fleet", "daemon.json");
|
|
4618
4755
|
}
|
|
@@ -4657,7 +4794,7 @@ function filterReviewablePRs(prs) {
|
|
|
4657
4794
|
}
|
|
4658
4795
|
async function getOpenReviewablePRs(repoRoot) {
|
|
4659
4796
|
try {
|
|
4660
|
-
const { stdout } = await
|
|
4797
|
+
const { stdout } = await execFileAsync5(
|
|
4661
4798
|
"gh",
|
|
4662
4799
|
["pr", "list", "--state", "open", "--draft=false", "--json", "number,headRefName,title"],
|
|
4663
4800
|
{ cwd: repoRoot }
|
|
@@ -4727,6 +4864,99 @@ async function stopDaemon(repoRoot) {
|
|
|
4727
4864
|
return false;
|
|
4728
4865
|
}
|
|
4729
4866
|
}
|
|
4867
|
+
async function queryOrphanedLocalRunIssues(repoRoot) {
|
|
4868
|
+
try {
|
|
4869
|
+
const { stdout } = await execFileAsync5(
|
|
4870
|
+
"gh",
|
|
4871
|
+
["issue", "list", "--state", "open", "--label", "runner:local,status:running", "--json", "number,title,createdAt", "--limit", "20"],
|
|
4872
|
+
{ cwd: repoRoot }
|
|
4873
|
+
);
|
|
4874
|
+
return JSON.parse(stdout || "[]");
|
|
4875
|
+
} catch {
|
|
4876
|
+
return [];
|
|
4877
|
+
}
|
|
4878
|
+
}
|
|
4879
|
+
async function reconcileOrphanedLocalRuns(optionsOrRepoRoot) {
|
|
4880
|
+
const options = typeof optionsOrRepoRoot === "string" ? { repoRoot: optionsOrRepoRoot } : optionsOrRepoRoot;
|
|
4881
|
+
const { repoRoot } = options;
|
|
4882
|
+
const queryFn = options.queryIssues || queryOrphanedLocalRunIssues;
|
|
4883
|
+
try {
|
|
4884
|
+
const issues = await queryFn(repoRoot);
|
|
4885
|
+
if (!issues || issues.length === 0) return 0;
|
|
4886
|
+
const runsDir = path14.join(repoRoot, ".jonah-fleet", "runs");
|
|
4887
|
+
let reconciledCount = 0;
|
|
4888
|
+
const hostname = os3.hostname();
|
|
4889
|
+
for (const issue of issues) {
|
|
4890
|
+
try {
|
|
4891
|
+
let completedReport;
|
|
4892
|
+
let isSuccess = false;
|
|
4893
|
+
let metaRoutine;
|
|
4894
|
+
if (fs14.existsSync(runsDir)) {
|
|
4895
|
+
const files = fs14.readdirSync(runsDir);
|
|
4896
|
+
for (const file of files) {
|
|
4897
|
+
if (file.endsWith(".json")) {
|
|
4898
|
+
try {
|
|
4899
|
+
const meta = JSON.parse(fs14.readFileSync(path14.join(runsDir, file), "utf8"));
|
|
4900
|
+
if (meta.issueNumber === issue.number) {
|
|
4901
|
+
metaRoutine = meta.routine;
|
|
4902
|
+
const mdFile = file.replace(/\.json$/, ".md");
|
|
4903
|
+
const mdPath = path14.join(runsDir, mdFile);
|
|
4904
|
+
if (fs14.existsSync(mdPath)) {
|
|
4905
|
+
completedReport = fs14.readFileSync(mdPath, "utf8");
|
|
4906
|
+
isSuccess = meta.success === true || meta.exitCode === 0;
|
|
4907
|
+
break;
|
|
4908
|
+
}
|
|
4909
|
+
}
|
|
4910
|
+
} catch {
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
}
|
|
4914
|
+
}
|
|
4915
|
+
if (options.reconcileRun) {
|
|
4916
|
+
const ok = await options.reconcileRun(
|
|
4917
|
+
repoRoot,
|
|
4918
|
+
issue.number,
|
|
4919
|
+
completedReport,
|
|
4920
|
+
isSuccess,
|
|
4921
|
+
metaRoutine
|
|
4922
|
+
);
|
|
4923
|
+
if (ok) reconciledCount++;
|
|
4924
|
+
} else if (completedReport) {
|
|
4925
|
+
const ok = await tryReconcileLocalRunIssueAsync(
|
|
4926
|
+
repoRoot,
|
|
4927
|
+
issue.number,
|
|
4928
|
+
completedReport,
|
|
4929
|
+
isSuccess ? 0 : 1,
|
|
4930
|
+
hostname,
|
|
4931
|
+
metaRoutine
|
|
4932
|
+
);
|
|
4933
|
+
if (ok) reconciledCount++;
|
|
4934
|
+
} else {
|
|
4935
|
+
const ok = await tryMarkLocalRunInterruptedAsync(
|
|
4936
|
+
repoRoot,
|
|
4937
|
+
issue.number,
|
|
4938
|
+
hostname,
|
|
4939
|
+
"Host machine daemon process was terminated before completion (e.g. machine reboot or SIGKILL).",
|
|
4940
|
+
metaRoutine || "local-routine"
|
|
4941
|
+
);
|
|
4942
|
+
if (ok) reconciledCount++;
|
|
4943
|
+
}
|
|
4944
|
+
} catch {
|
|
4945
|
+
}
|
|
4946
|
+
}
|
|
4947
|
+
if (reconciledCount > 0) {
|
|
4948
|
+
console.log(
|
|
4949
|
+
pc13.yellow(
|
|
4950
|
+
`
|
|
4951
|
+
\u26A0\uFE0F Reconciled ${reconciledCount} orphaned local routine run issue(s) from previous session.`
|
|
4952
|
+
)
|
|
4953
|
+
);
|
|
4954
|
+
}
|
|
4955
|
+
return reconciledCount;
|
|
4956
|
+
} catch {
|
|
4957
|
+
return 0;
|
|
4958
|
+
}
|
|
4959
|
+
}
|
|
4730
4960
|
async function drainReviewQueue(drainOptions) {
|
|
4731
4961
|
const {
|
|
4732
4962
|
repoRoot,
|
|
@@ -5386,6 +5616,8 @@ ${pc13.cyan("Enter Issue # to work (Esc/Enter to cancel):")} `, {
|
|
|
5386
5616
|
}
|
|
5387
5617
|
});
|
|
5388
5618
|
keyboard?.start();
|
|
5619
|
+
void reconcileOrphanedLocalRuns(repoRoot).catch(() => {
|
|
5620
|
+
});
|
|
5389
5621
|
if (routines.includes("peer-review")) {
|
|
5390
5622
|
await performReviewDrain();
|
|
5391
5623
|
}
|
package/dist/lib/daemon.d.ts
CHANGED
|
@@ -58,6 +58,26 @@ export declare function startBackgroundDaemon(repoRoot: string, options?: Daemon
|
|
|
58
58
|
* Stops a running daemon process.
|
|
59
59
|
*/
|
|
60
60
|
export declare function stopDaemon(repoRoot: string): Promise<boolean>;
|
|
61
|
+
export interface ReconcileOrphanedRunsOptions {
|
|
62
|
+
repoRoot: string;
|
|
63
|
+
queryIssues?: (repoRoot: string) => Promise<Array<{
|
|
64
|
+
number: number;
|
|
65
|
+
title: string;
|
|
66
|
+
createdAt: string;
|
|
67
|
+
}>>;
|
|
68
|
+
reconcileRun?: (repoRoot: string, issueNumber: number, report: string | undefined, isSuccess: boolean, routine?: string) => Promise<boolean>;
|
|
69
|
+
}
|
|
70
|
+
export declare function queryOrphanedLocalRunIssues(repoRoot: string): Promise<Array<{
|
|
71
|
+
number: number;
|
|
72
|
+
title: string;
|
|
73
|
+
createdAt: string;
|
|
74
|
+
}>>;
|
|
75
|
+
/**
|
|
76
|
+
* Scans for open routine run issues labeled `runner:local,status:running` that were abandoned
|
|
77
|
+
* by a process crash, SIGKILL, or host machine reboot, and reconciles them.
|
|
78
|
+
* Operates asynchronously and fails gracefully on network / CLI errors without preventing daemon startup.
|
|
79
|
+
*/
|
|
80
|
+
export declare function reconcileOrphanedLocalRuns(optionsOrRepoRoot: string | ReconcileOrphanedRunsOptions): Promise<number>;
|
|
61
81
|
export interface DrainReviewQueueOptions {
|
|
62
82
|
repoRoot: string;
|
|
63
83
|
state?: DaemonState;
|
package/dist/lib/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/lib/daemon.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/lib/daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/runner.d.ts
CHANGED
|
@@ -140,12 +140,29 @@ export declare function formatInterruptionCard(options: InterruptionCardOptions)
|
|
|
140
140
|
* Fails gracefully if offline or unauthenticated.
|
|
141
141
|
*/
|
|
142
142
|
export declare function tryPostLocalRunMilestone(cwd: string, issueNumber: number, cardContent: string): void;
|
|
143
|
+
/**
|
|
144
|
+
* Posts a milestone comment to a local routine tracking issue asynchronously.
|
|
145
|
+
* Fails gracefully if offline or unauthenticated.
|
|
146
|
+
*/
|
|
147
|
+
export declare function tryPostLocalRunMilestoneAsync(cwd: string, issueNumber: number, cardContent: string): Promise<boolean>;
|
|
143
148
|
/**
|
|
144
149
|
* Reconciles a GitHub issue for local routine execution.
|
|
145
150
|
* Closes the issue if success, leaves it open with needs-attention if failure.
|
|
146
151
|
* Fails gracefully if offline or unauthenticated.
|
|
147
152
|
*/
|
|
148
153
|
export declare function tryReconcileLocalRunIssue(cwd: string, issueNumber: number, reportContent: string, exitCode: number, hostname: string, routine?: string): void;
|
|
154
|
+
/**
|
|
155
|
+
* Asynchronously marks an interrupted local routine run as failed and posts an interruption card.
|
|
156
|
+
* Leaves the issue open with status:failure,needs-attention for maintainer triage.
|
|
157
|
+
* Fails gracefully if offline or unauthenticated.
|
|
158
|
+
*/
|
|
159
|
+
export declare function tryMarkLocalRunInterruptedAsync(cwd: string, issueNumber: number, hostname: string, reason?: string, routine?: string): Promise<boolean>;
|
|
160
|
+
/**
|
|
161
|
+
* Asynchronously reconciles a GitHub issue for local routine execution.
|
|
162
|
+
* Closes the issue if success, leaves it open with needs-attention if failure.
|
|
163
|
+
* Fails gracefully if offline or unauthenticated.
|
|
164
|
+
*/
|
|
165
|
+
export declare function tryReconcileLocalRunIssueAsync(cwd: string, issueNumber: number, reportContent: string, exitCode: number, hostname: string, routine?: string): Promise<boolean>;
|
|
149
166
|
/**
|
|
150
167
|
* Reads a freshly generated run report from execution or target directory.
|
|
151
168
|
* Returns null if no fresh report exists (e.g. file missing or older than run start).
|
|
@@ -166,6 +183,12 @@ export interface FallbackReportOptions {
|
|
|
166
183
|
* resolve to a non-zero exit code instead of defaulting to 0.
|
|
167
184
|
*/
|
|
168
185
|
export declare function resolveExitCode(code: number | null, signal: NodeJS.Signals | string | null): number;
|
|
186
|
+
/**
|
|
187
|
+
* Detects whether an autonomous routine exited prematurely (e.g. agent yielded its
|
|
188
|
+
* turn to "wait" on background tasks or timers, which causes headless agy -p to terminate
|
|
189
|
+
* with exit code 0 before reaching the routine's Definition of Done).
|
|
190
|
+
*/
|
|
191
|
+
export declare function detectPrematureRoutineExit(output: string, routine: string): string | null;
|
|
169
192
|
/**
|
|
170
193
|
* Formats a fallback summary markdown report when no fresh run-report.md was generated.
|
|
171
194
|
* Includes sanitized trailing error output from stdout and/or stderr if exitCode is non-zero.
|
package/dist/lib/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/lib/runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/lib/runner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -210,11 +210,11 @@ How the fleet guarantees continuous review throughput, recovers from transient A
|
|
|
210
210
|
|
|
211
211
|
---
|
|
212
212
|
|
|
213
|
-
## Upstream Symphony &
|
|
213
|
+
## Upstream Symphony, Funes & Orbital Intel & Architectural Evaluation Framework
|
|
214
214
|
|
|
215
|
-
How changes and innovations from upstream ecosystems—[openai/symphony](https://github.com/openai/symphony) for issue-tracker orchestration
|
|
215
|
+
How changes and innovations from upstream ecosystems—[openai/symphony](https://github.com/openai/symphony) for issue-tracker orchestration, [huggingface/funes](https://github.com/huggingface/funes) for agent memory & session indexing, and [zqiren/Orbital](https://github.com/zqiren/Orbital) for project agents & worker transports—are systematically audited and evaluated for incorporation into Jonah Fleet:
|
|
216
216
|
|
|
217
|
-
1. **Automated Ecosystem Radar (`symphony-radar.yml`)**: A weekly scheduled workflow runs `.github/scripts/fetch-symphony-radar.js` to inspect upstream commits, specification updates (`SPEC.md`), and
|
|
217
|
+
1. **Automated Ecosystem Radar (`symphony-radar.yml`)**: A weekly scheduled workflow runs `.github/scripts/fetch-symphony-radar.js` to inspect upstream commits, specification updates (`SPEC.md`), releases, and pull requests across `openai/symphony` (orchestration), `huggingface/funes` (memory tooling), and `zqiren/Orbital` (project agents & worker transports), generating an actionable digest issue in Jonah Fleet.
|
|
218
218
|
2. **The 4 Evaluation Layers**:
|
|
219
219
|
- **Layer 1 (Zero-Daemon Invariant)**: Can the enhancement execute in ephemeral GitHub Actions and `agy` CLI sessions without requiring a 24/7 background server or persistent WebSocket?
|
|
220
220
|
- **Layer 2 (Issue Tracker Abstraction)**: Does the pattern map cleanly to native GitHub Issues, labels, and PR checks without proprietary tracker dependencies?
|
|
@@ -225,9 +225,14 @@ How changes and innovations from upstream ecosystems—[openai/symphony](https:/
|
|
|
225
225
|
- **Pull-Based Memory Delivery**: Memory served strictly on demand via MCP (`recall`, `get`) to prevent prompt context bloat.
|
|
226
226
|
- **Cross-Session Provenance**: Verbatim turns and provenance retention instead of lossy summary drift.
|
|
227
227
|
- **Multi-Agent Portability**: Standardized trace ingestion across Antigravity CLI (`agy`), Claude Code, and Codex.
|
|
228
|
-
4. **
|
|
229
|
-
-
|
|
230
|
-
-
|
|
228
|
+
4. **Project Agent & Worker Transports Evaluation Dimensions (Orbital Watch)**:
|
|
229
|
+
- **Layer-1 Context Memory Files**: In-repo memory files (`LESSONS.md`, `CONTEXT.md`) maintained directly by agents on PR branches to avoid uncommitted disk drift or git merge collisions.
|
|
230
|
+
- **ACP/PTY Worker Transports**: Agent Client Protocol (ACP) and pseudo-terminal delegation to sub-agents, adaptable for local CLI runner execution.
|
|
231
|
+
- **Prompt Prefix Caching Benchmarks**: Partitioning prompt structures into Static $\rightarrow$ Semi-Stable $\rightarrow$ Dynamic tiers to maximize prefix cache hit rates (~95%).
|
|
232
|
+
- **Fail-Closed Safety Guards**: Deterministic action-hash repetition guards, cycle detection, and circuit breakers that halt runaway execution loops before token budgets are breached.
|
|
233
|
+
5. **Classification & Action Protocol**:
|
|
234
|
+
- **🟢 Category A (Adopt Directly)**: Security guardrails, claim lock invariants, reader/writer rules, prompt engineering & prefix caching optimizations, fail-closed safety guards, deterministic zero-LLM indexing.
|
|
235
|
+
- **🟡 Category B (Adapt to Actions/CLI)**: Dynamic orchestrator pacing, backpressure controls, multi-stage review checks, pull-based memory MCP integrations, ACP/PTY worker transports.
|
|
231
236
|
- **🔴 Category C (Skip)**: Elixir/OTP supervision trees, BEAM memory tuning, proprietary runtime internals, always-loaded memory context dumps.
|
|
232
237
|
|
|
233
238
|
---
|
|
@@ -257,3 +262,13 @@ How agent routines are partitioned between cloud GitHub Actions (24/7 cloud runn
|
|
|
257
262
|
- Local agent PR convergence claims post: `🔒 Addressing review findings by local autowork session (host: <hostname>) <timestamp>`.
|
|
258
263
|
- Local processes trap `SIGINT`/`SIGTERM` to unassign claims and remove worktrees cleanly on exit.
|
|
259
264
|
- Standard stale-claim rules (6h for issues, 2h for PRs) safely reclaim orphaned local claims if a machine powers down unexpectedly.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Headless Execution & Asynchronous Non-Yielding Guardrail
|
|
269
|
+
|
|
270
|
+
In headless CLI environments (`agy -p` / GitHub Actions), agent sessions terminate immediately whenever the model yields a turn without active tool calls. Therefore:
|
|
271
|
+
|
|
272
|
+
1. **Zero-Yield Waiting Invariant**: Agents MUST NEVER call `schedule` or emit a terminal turn with plain text to "wait" for background commands, timers, or long-running checks. In headless mode, yielding the turn halts the process immediately with exit code 0 before reaching the Definition of Done.
|
|
273
|
+
2. **Active Task Supervision**: If a verification command (`npm test`, `npm run type-check`) is sent to the background by `run_command`, the agent must actively poll `manage_task(Action='status')` or inspect code while waiting within the continuous tool-calling loop.
|
|
274
|
+
3. **CI Trust Bar & Test Discipline**: Peer review routines should trust green passing remote CI checks (GitHub Actions or Vercel preview deployments) on the PR's head commit rather than initiating slow, background-prone full test runs. Run repository verification locally ONLY if CI status is unconfirmed, missing, or failing.
|
|
@@ -29,6 +29,7 @@ If any criterion cannot be met, stop immediately and log FAILURE with the reason
|
|
|
29
29
|
- **Single-flight per issue & PR**: multiple autowork runs can execute concurrently. Both issues and pull requests are shared resources — never begin implementing an issue without first claiming it (see Claim protocol in Phase 2), and never begin addressing findings on an open PR without first claiming it (see PR Claim protocol in Phase 1).
|
|
30
30
|
- **Language Requirement**: All GitHub issue titles, descriptions, task checklists, and comments MUST be written in **English**.
|
|
31
31
|
- **Session link footer**: sign every GitHub post (issue comments, PR comments, PR descriptions) with the Antigravity run footer (`_Generated by [Antigravity](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})_`). Inline review-thread line comments are exempt.
|
|
32
|
+
- **Headless Execution & Asynchronous Non-Yielding Guardrail**: You are running in a headless autonomous session. You MUST NEVER call `schedule` or yield the turn with plain text while waiting for background tasks or verification checks. If a verification command runs in the background, actively inspect its completion with `manage_task` or run with sufficient `WaitMsBeforeAsync` (up to `10000` ms). Never stop calling tools or yield your turn until the routine's terminal Definition of Done is fully reached.
|
|
32
33
|
|
|
33
34
|
## Negative examples (DO NOT do these)
|
|
34
35
|
|
|
@@ -45,6 +46,7 @@ If any criterion cannot be met, stop immediately and log FAILURE with the reason
|
|
|
45
46
|
- Do not mark a PR ready while its `mergeable_state` is `dirty` — resolve merge conflicts first.
|
|
46
47
|
- Do not fall into the **Telemetry Rabbit Hole**: do not spend cycles instrumenting elaborate fallback telemetry or defensive error handling for features that suffer from lack of user intent rather than software bugs.
|
|
47
48
|
- Do not guess or invent arbitrary specifications for ambiguous issues — post clarifying questions, label `needs-info`, and release the claim instead of blindly writing code.
|
|
49
|
+
- Do not call `schedule` or yield the turn with plain text while waiting for background verification tasks — stay in the tool loop until the Definition of Done is met.
|
|
48
50
|
|
|
49
51
|
## Instructions
|
|
50
52
|
|
|
@@ -33,6 +33,8 @@ If any criterion cannot be met, stop immediately and log FAILURE with the reason
|
|
|
33
33
|
- **No speculative work**: review only the diff in the PR.
|
|
34
34
|
- **Language Requirement**: All GitHub comments, review notes, and follow-up issues MUST be written in **English**.
|
|
35
35
|
- **Session link footer**: sign every GitHub post with the Antigravity run footer (`_Generated by [Antigravity](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})_`).
|
|
36
|
+
- **Headless Execution & Asynchronous Non-Yielding Guardrail**: You are running in a headless autonomous CLI session. You MUST NEVER call `schedule` or yield the turn with plain text to "wait" for background tasks, timers, or long-running commands. In headless CLI mode, yielding the turn terminates the session immediately before reaching the Definition of Done. When invoking `run_command` for test runs or type checks, ALWAYS set `WaitMsBeforeAsync` high enough (up to the maximum `10000` ms) or if a command moves to the background, keep your execution turn active by checking task status (`manage_task(Action='status')`) or inspecting files; NEVER call `schedule` or emit a terminal turn with plain text before taking the final action.
|
|
37
|
+
- **Verification Command & CI Discipline**: When remote CI checks (e.g. GitHub Actions, Vercel preview deployments) are already present and passed on the PR's head commit, treat CI as verified and green. Avoid executing slow, redundant local full test suites or full type-checks when CI is already green. Run local verification commands (`npm test`, `npm run type-check`) ONLY if CI is missing, unconfirmed, or failing.
|
|
36
38
|
|
|
37
39
|
## Final action: merge or bounce to draft
|
|
38
40
|
|
|
@@ -58,6 +60,8 @@ Every review ends in exactly one of two states:
|
|
|
58
60
|
- On re-review, do not raise new findings in code that was unchanged since the prior review — only inspect the delta commits.
|
|
59
61
|
- Do not bounce a PR for non-blocking style/preference findings when all correctness checks pass.
|
|
60
62
|
- Do not bounce an external contributor PR purely for missing `Closes #N` when the PR description provides a clear specification.
|
|
63
|
+
- Do not call `schedule` or yield the turn with plain text while waiting for background verification tasks — stay in the tool loop until the final action is taken.
|
|
64
|
+
- Do not rerun full local test suites when remote CI checks on the head commit are already green and passing.
|
|
61
65
|
|
|
62
66
|
## Instructions
|
|
63
67
|
|
|
@@ -108,7 +112,7 @@ Check if `$PR_NUMBER` is set:
|
|
|
108
112
|
- **CTA Hierarchy**: Verify at most one primary forward CTA (`.btn-primary`) per active screen/tab.
|
|
109
113
|
- **Mobile Viewport Budget**: Verify that new banners, nudges, or sticky elements do not stack concurrently above the fold on mobile viewports (~390px).
|
|
110
114
|
4. If PR modifies rendered UI, verify screenshots or visual components if tooling/scripts are available.
|
|
111
|
-
5. Run repository verification commands (tests, type-check) if CI status is unconfirmed.
|
|
115
|
+
5. Run repository verification commands (tests, type-check) ONLY if CI status is unconfirmed or failing. If remote CI (such as GitHub Actions or Vercel preview) is already green and passing on the head commit, treat CI as verified. If verification commands must be run locally, specify `WaitMsBeforeAsync: 10000` and NEVER call `schedule` or yield the turn with plain text while waiting for background tasks.
|
|
112
116
|
|
|
113
117
|
### Step 5: Classify Findings & Make Decision
|
|
114
118
|
|