diff --git a/.cursor/bin/riven-loop-tick.ts b/.cursor/bin/riven-loop-tick.ts index 4f0998d261..e3dcf8a8fc 100644 --- a/.cursor/bin/riven-loop-tick.ts +++ b/.cursor/bin/riven-loop-tick.ts @@ -32,7 +32,8 @@ function nowIso(): string { } function log(message: string): void { - appendFileSync(join(logDir, "runner.log"), `${nowIso()} ${message}\n`); + appendFileSync(join(logDir, "runner.log"), `${nowIso()} ${message} +`); } function run(command: string, args: string[], timeoutMs: number): { status: number; stdout: string; stderr: string } { @@ -54,13 +55,17 @@ function run(command: string, args: string[], timeoutMs: number): { status: numb } function lines(text: string): string[] { - return text.split(/\r?\n/).map(l => l.trim()).filter(l => l.length > 0); + return text.split(/ ? +/).map(l => l.trim()).filter(l => l.length > 0); } function acquireLock(): boolean { try { mkdirSync(lockDir, { recursive: false }); - writeFileSync(join(lockDir, "metadata"), `pid=${process.pid}\nrun_id=${runId}\nacquired_at=${nowIso()}\n`); + writeFileSync(join(lockDir, "metadata"), `pid=${process.pid} +run_id=${runId} +acquired_at=${nowIso()} +`); return true; } catch { try { @@ -77,7 +82,10 @@ function acquireLock(): boolean { } rmSync(lockDir, { recursive: true, force: true }); mkdirSync(lockDir, { recursive: false }); - writeFileSync(join(lockDir, "metadata"), `pid=${process.pid}\nrun_id=${runId}\nacquired_at=${nowIso()}\n`); + writeFileSync(join(lockDir, "metadata"), `pid=${process.pid} +run_id=${runId} +acquired_at=${nowIso()} +`); return true; } catch { return false; } } @@ -97,7 +105,8 @@ function readBroadcasts(): void { const path = join(broadcastDir, peer); if (existsSync(path)) { const content = readFileSync(path, "utf8").trim(); - if (content) log(`broadcast from ${peer.replace(".md", "")}: ${content.split("\n")[0] ?? "(empty)"}`); + if (content) log(`broadcast from ${peer.replace(".md", "")}: ${content.split(" +")[0] ?? "(empty)"}`); } } } @@ -109,7 +118,8 @@ function writeBroadcast(summary: string): void { "", "## Background tick status", summary, - ].join("\n")); + ].join(" +")); } function gh(...args: string[]): { status: number; stdout: string } { @@ -146,7 +156,8 @@ function forwardTick(): void { return; } - const prNumbers = prsResult.stdout.trim().split("\n").filter(n => n.trim()).map(Number); + const prNumbers = prsResult.stdout.trim().split(" +").filter(n => n.trim()).map(Number); for (const pr of prNumbers) { const gateResult = gh( "pr", "view", String(pr), "--repo", "Lucent-Financial-Group/Zeta", @@ -198,59 +209,31 @@ function heartbeat(): void { const elapsed = Date.now() - lastTime; if (elapsed >= agentIntervalMs) { - const prNum = Number(prCount) || 0; - const workMode = prNum === 0 ? "pickup" : "drain"; agentStatus = "running"; - log(`riven work cycle start run_id=${runId} mode=${workMode} open_prs=${prNum}`); + log(`riven agent gate start run_id=${runId}`); if (dryRun) { - log(`dry-run: would run riven ${workMode}`); + log(`dry-run: would run agent gate`); agentStatus = "dry-run"; } else { - let prompt: string; - if (workMode === "pickup") { - const pickup = run("bun", ["tools/backlog/autonomous-pickup.ts", "--json"], 30_000); - let executionPrompt = ""; - try { - const selection = JSON.parse(pickup.stdout); - executionPrompt = selection.executionPrompt ?? ""; - log(`pickup selected: ${selection.selected?.id ?? "none"} action=${selection.action ?? "none"}`); - } catch { log(`pickup parse error: ${pickup.stderr.slice(0, 200)}`); } - - const preamble = [ - `You are Rivens background worker in Lucent-Financial-Group/Zeta.`, - `BEFORE ANY WORK: 1) Read CLAUDE.md and AGENTS.md for repo conventions.`, - `2) Run "bun tools/github/refresh-worldview.ts" to get current state.`, - `3) Read active trajectories at docs/trajectories/*/RESUME.md.`, - `4) Build gate: "dotnet build -c Release" must end with 0 warnings 0 errors.`, - `KEY RULES: TS over bash (Rule 0). Prefer F#/TS code over docs.`, - `Always re-decompose items during the build — assume decomposition has mistakes.`, - ].join(" "); - - prompt = executionPrompt.length > 0 - ? `${preamble} YOUR TASK:\n${executionPrompt}` - : `${preamble} No backlog items available. Run refresh-worldview, check for stale classifications, fix them, open a PR.`; - } else { - prompt = [ - `You are Rivens background worker in Lucent-Financial-Group/Zeta.`, - `Read CLAUDE.md first. Run "bun tools/github/refresh-worldview.ts".`, - `Build gate: "dotnet build -c Release" (0 warnings).`, - `TASK: ${prNum} open PRs. Run "bun tools/github/poll-pr-gate-batch.ts --all-open".`, - `For any PR where gate=BLOCKED and nextAction=resolve-threads:`, - `check out branch, read review comments, fix code issues, push,`, - `reply to threads, resolve via GraphQL, arm auto-merge`, - `(gh pr merge NUMBER --auto --squash). Own your PRs through merge.`, - ].join(" "); - } - - const gate = run("cursor-agent", [ - "-p", + const gate = run("agent", [ + "chat", + "--mode", "ask", "--model", "grok-4.3", - prompt, + [ + "You are Riven, trajectory manager and adversarial-truth-axis reviewer.", + "This is an autonomous 15-minute cycle.", + "Read broadcasts first from ~/.local/share/zeta-broadcasts/{otto,vera,lior,riven}.md.", + "Walk assigned trajectories. Decompose only what you hit mid-stride.", + "Produce at least one concrete, actionable claim or small PR scope.", + "When blocked, create a specific research child the next pickup cannot dodge.", + "Write your status to ~/.local/share/zeta-broadcasts/riven.md at the end.", + "GitHub PR state and actual file contents are authoritative.", + ].join(" "), ], agentTimeoutMs); agentStatus = gate.status === 0 ? "ok" : `exit-${gate.status}`; - log(`riven work cycle end run_id=${runId} mode=${workMode} status=${gate.status}`); + log(`riven agent gate end run_id=${runId} status=${gate.status}`); writeFileSync(agentStateFile, JSON.stringify({ run_id: runId, @@ -260,10 +243,16 @@ function heartbeat(): void { }, null, 2)); if (gate.stdout.trim().length > 0) { - appendFileSync(join(logDir, "ticks.log"), `\n--- ${runId} riven gate ---\n${gate.stdout}\n`); + appendFileSync(join(logDir, "ticks.log"), ` +--- ${runId} riven gate --- +${gate.stdout} +`); } if (gate.stderr.trim().length > 0) { - appendFileSync(join(logDir, "ticks.err"), `\n--- ${runId} riven gate ---\n${gate.stderr}\n`); + appendFileSync(join(logDir, "ticks.err"), ` +--- ${runId} riven gate --- +${gate.stderr} +`); } } } else { @@ -316,4 +305,3 @@ try { } finally { releaseLock(); } -