@loops-adk/core 0.2.0 → 0.3.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/README.md CHANGED
@@ -143,7 +143,7 @@ A loop is easy to start and hard to keep honest. Four parts decide whether it ea
143
143
  | **The gate.** Knowing the work is actually done, not just that the agent stopped. | A deterministic check (`commandSucceeds`) and a separate judge (`agentCheck`) in its own context, hardened with a k-of-n `quorum` and a geometric-mean rubric so one weak dimension sinks the verdict. The model that did the work never grades it. |
144
144
  | **Memory.** Carrying what was learned across a run without dragging a transcript along. | The git commit log is the memory: a structured handoff per milestone, read back before the next turn. No `STATE.md` the model is trusted to keep tidy, no vector store to sync. |
145
145
  | **Parallelism.** Running several agents without collisions on the same files. | `isolation: 'worktree'` gives each writer its own branch and worktree, landed back on pass with a `--no-ff` merge. |
146
- | **Hard stops.** Bounding a loop so it cannot run forever or empty your account. | `max` caps iterations and `budget` caps tokens, a non-retryable stop the engine calls refuse to cross. |
146
+ | **Hard stops.** Bounding a loop so it cannot run forever or empty your account. | `max` caps iterations, `budget` caps tokens (a non-retryable stop the engine calls refuse to cross), and `noProgress` stalls out a loop whose iterations reach no new state, with the evidence on the outcome. |
147
147
 
148
148
  Three things `loops` does that most loop libraries do not:
149
149
 
@@ -241,6 +241,7 @@ loop({
241
241
  stopOn, // hard early-exit each iteration; met ⇒ aborted
242
242
  review, // runs when until is met; non-pass re-enters the loop (folds back as ctx.lastReview)
243
243
  max, // iteration cap; reached without passing ⇒ exhausted
244
+ noProgress, // stall out after n consecutive iterations with no observable progress
244
245
  maxReviewRestarts, // cap the worker/reviewer standoff independently of max
245
246
  delayMs, // delay between iterations (polling); interruptible by abort
246
247
  retry, // { onError: 'continue' | 'fail', maxConsecutive?, backoffMs? }
@@ -279,6 +280,30 @@ agentCheck({
279
280
 
280
281
  **Builders:** `predicate`, `bodyPassed`, `minConfidence`, `commandSucceeds` (a shell command exits 0), `all`, `any`, `not`, `quorum` (k-of-n), `agentCheck` (small-model judge), `always`, `never`, and `gateJob` (lift a condition into a `Job`, e.g. a reviewer).
281
282
 
283
+ ## No progress: the third hard stop
284
+
285
+ The gate detects success; nothing above detects a loop that is failing to converge. `max` bounds the attempt count and `budget` bounds the cost, but both fire only after the waste, and neither can tell slow-but-real convergence from the same failure five turns running. `noProgress` is that sensor: the loop ends `exhausted` once `n` consecutive iterations reach no state the run has not already seen.
286
+
287
+ ```ts
288
+ loop({
289
+ name: 'build',
290
+ body: agentJob({ prompt: '…', ground: true }),
291
+ until: commandSucceeds('npm', ['test']),
292
+ max: 50, // generous runway for hard work…
293
+ noProgress: 3, // …because the doomed case exits after 3 flat iterations
294
+ });
295
+ ```
296
+
297
+ Progress means **novelty**, not change. An iteration counts as progress when any evidence channel reaches something new:
298
+
299
+ - **the workspace fingerprint** (HEAD, pending diff, untracked content) is a state this run has never visited, so an agent oscillating A→B→A gets no credit for the return trip;
300
+ - **the gate confidence** beats its previous best by `minConfidenceDelta` (default 0.02), a high-water mark, so judge jitter is not progress but slow steady improvement accumulates until it clears the bar;
301
+ - **a custom `signal`** returns a value not already seen, the escape hatch for progress the worktree cannot show (a queue length, a passing-test count): `noProgress: { window: 3, signal: (ctx) => queueDepth() }`.
302
+
303
+ The default is conservative: one channel showing novelty keeps the loop alive, so real-but-slow work is never cut short. And the exit is a diagnosis, not just a stop: the outcome carries `Outcome.stall` (the flat iterations, the repeated gate reason, the per-channel evidence) and a `loop:stall` event fires for supervisors, so "stalled since iteration 5 on the same scope error" replaces "reached max iterations" and a fleet watcher can re-brief the loop instead of shrugging at it. This is also what makes a generous `max` safe to grant: the safety net and the runway stop being the same number.
304
+
305
+ Off by default, like `commit`: a polling loop legitimately makes no progress until the outside world changes. Flags mode: `--stall-after <n>`. Offline demo: `npm run example:stall`.
306
+
282
307
  ## Ledger: memory built on git
283
308
 
284
309
  Fresh context kills _rot_; on its own it would cause _amnesia_. **Ledger** is the core that closes the gap: the loop writes its reasoning to git as it works and reads it back before the next turn. No parallel database, no vector store; git _is_ the index: nothing to build, embed, sync, or let go stale (the commit log can't drift out of sync with the code; it _is_ the code's history). (`Ledger` is the engine; the **commit log** is the durable memory it reads and writes; `.loops/ledger.md` and `.loops/prompt.md` are the live scratch files for work in flight.)
@@ -573,7 +598,7 @@ It deliberately does **not** do durable mid-run replay (re-running a half-finish
573
598
  - [x] Supervision: a file-based run registry with `loops list` / `status` / `tail`
574
599
  - [ ] Out-of-process control: `pause` / `abort` / `kickback` a running loop from outside
575
600
  - [ ] Optional `wip:` autosave tier (per-iteration recovery, squashed on convergence)
576
- - [ ] No-progress / stall detection: the third hard stop, alongside `max` and `budget`
601
+ - [x] No-progress / stall detection (`noProgress`): the third hard stop, alongside `max` and `budget`
577
602
  - [ ] `cost per accepted change` as a first-class reported metric
578
603
  - [ ] Calibration helpers for agent judges
579
604
  - [ ] More engine adapters (OpenAI, local models)
package/dist/api.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ConditionInput, J as Job, R as RevisionRerun, F as FeedbackFinding, a as FeedbackDecision, O as Outcome, G as GraphPosition, b as FeedbackSeverity, c as FeedbackActionSeverity, d as JobContext, e as RevisionRequest, L as LoopConfig, D as DagConfig, f as JobMeta, g as EngineRef, W as Workspace, A as AgentDef, h as Condition, i as EngineOptions, j as Engine, k as EngineName, l as AgentRequest, U as Usage, m as EngineEventSink, n as AgentResult, E as Environment, o as EnvHandle, p as LoopEvent, q as Forge, B as BudgetConfig, r as LimitPolicy } from './types-Cv_3ymr9.js';
2
- export { s as AgentContractSummary, t as AgentFailureMode, u as AgentHumanGate, v as AgentJobConfig, w as AgentOutputContract, x as AgentSkillRef, y as AgentTier, z as Budget, H as CommitJobConfig, I as ConditionResult, K as DagNode, M as EngineStreamEvent, N as ForgeOpts, P as GhForge, Q as GroundConfig, S as LogLevel, T as LoopError, V as LoopErrorCode, X as MergeOptions, Y as MockForge, Z as MockForgeOptions, _ as OutcomeStatus, $ as PrInput, a0 as PrPatch, a1 as PrRef, a2 as RawPredicate, a3 as RetryPolicy, a4 as SUBAGENT_TOOLS, a5 as Skill, a6 as agentContract, a7 as agentJob, a8 as buildChecksArgs, a9 as buildCreateArgs, aa as buildEditArgs, ab as buildMergeArgs, ac as buildViewArgs, ad as commitJob, ae as defineAgent, af as defineSkill, ag as fnJob, ah as fromFile, ai as isEngine, aj as isEnvironment, ak as isForge, al as resolveSystem } from './types-Cv_3ymr9.js';
1
+ import { C as ConditionInput, J as Job, R as RevisionRerun, F as FeedbackFinding, a as FeedbackDecision, O as Outcome, G as GraphPosition, b as FeedbackSeverity, c as FeedbackActionSeverity, d as JobContext, e as RevisionRequest, L as LoopConfig, D as DagConfig, f as JobMeta, g as EngineRef, W as Workspace, A as AgentDef, h as Condition, i as EngineOptions, j as Engine, k as EngineName, l as AgentRequest, U as Usage, m as EngineEventSink, n as AgentResult, E as Environment, o as EnvHandle, p as LoopEvent, q as Forge, B as BudgetConfig, r as LimitPolicy } from './types-CpB03Jj4.js';
2
+ export { s as AgentContractSummary, t as AgentFailureMode, u as AgentHumanGate, v as AgentJobConfig, w as AgentOutputContract, x as AgentSkillRef, y as AgentTier, z as Budget, H as CommitJobConfig, I as ConditionResult, K as DagNode, M as EngineStreamEvent, N as ForgeOpts, P as GhForge, Q as GroundConfig, S as LogLevel, T as LoopError, V as LoopErrorCode, X as MergeOptions, Y as MockForge, Z as MockForgeOptions, _ as NoProgressConfig, $ as NoProgressInput, a0 as OutcomeStatus, a1 as PrInput, a2 as PrPatch, a3 as PrRef, a4 as ProgressSample, a5 as ProgressTracker, a6 as RawPredicate, a7 as RetryPolicy, a8 as SUBAGENT_TOOLS, a9 as Skill, aa as StallReport, ab as agentContract, ac as agentJob, ad as buildChecksArgs, ae as buildCreateArgs, af as buildEditArgs, ag as buildMergeArgs, ah as buildViewArgs, ai as commitJob, aj as defineAgent, ak as defineSkill, al as fnJob, am as fromFile, an as isEngine, ao as isEnvironment, ap as isForge, aq as resolveNoProgress, ar as resolveSystem } from './types-CpB03Jj4.js';
3
3
 
4
4
  interface RevisionRequestInput {
5
5
  target?: string;
@@ -185,6 +185,17 @@ declare function stageAll(opts: GitOpts): Promise<void>;
185
185
  declare function hasStagedChanges(opts: GitOpts): Promise<boolean>;
186
186
  /** True when the work tree (staged or unstaged) has any change. */
187
187
  declare function isDirty(opts: GitOpts): Promise<boolean>;
188
+ /**
189
+ * A content hash of the workspace's observable state: HEAD, every pending
190
+ * tracked change (staged + unstaged, with content), the porcelain status, and
191
+ * the CONTENT of untracked non-ignored files (hashed by git itself, so a
192
+ * revisit to a byte-identical tree fingerprints identically). This is the
193
+ * deterministic evidence channel behind `noProgress`: two iterations with the
194
+ * same fingerprint left the workspace in the same state. Returns undefined
195
+ * outside a git work tree — the caller treats that channel as absent, never as
196
+ * "unchanged". Never throws.
197
+ */
198
+ declare function workspaceFingerprint(opts: GitOpts): Promise<string | undefined>;
188
199
  interface CommitInput {
189
200
  subject: string;
190
201
  /** The structured body — the "way". Joined to the subject with a blank line. */
@@ -1120,4 +1131,4 @@ declare function semanticRecordsFromEvent(event: LoopEvent): SemanticRunRecord[]
1120
1131
  /** Identity helper that pins the type of a default export to `Job`. */
1121
1132
  declare function defineJob(job: Job): Job;
1122
1133
 
1123
- export { type AgentCheckConfig, AgentDef, AgentRequest, AgentResult, BudgetConfig, type CommitInput, type CommitRecord, type CompactOptions, Condition, ConditionInput, type ConsolidateJobConfig, type ConsolidateOptions, DagConfig, EXIT_PAUSED, Engine, type EngineFactory, EngineName, EngineOptions, EngineRef, EngineRegistry, EnvHandle, Environment, FeedbackActionSeverity, FeedbackDecision, FeedbackFinding, FeedbackSeverity, Forge, GraphPosition, type GroundOptions, type IsolatedOptions, Job, JobContext, JobMeta, type LedgerEntry, LimitPolicy, type LogQuery, LoopConfig, LoopEvent, type MergeJobConfig, type MergeResult, type MergeSynthesisConfig, type MergeSynthesisResult, MockEngine, type MockEnvOptions, MockEnvironment, type MockResponder, Outcome, type PromptNote, type PullRequestJobConfig, type PushJobConfig, type PushOptions, type PushResult, type RetrieveOptions, type ReviewContextConfig, type ReviewPanelConfig, RevisionRequest, type RevisionRequestInput, RevisionRerun, type RunLive, type RunOptions, type RunResult, type RunStatus, type SemanticDecision, type SemanticOutcome, type SemanticRunRecord, Stats, type StatsSnapshot, type TournamentConfig, Usage, Workspace, type WorktreeHandle, addWorktree, agentCheck, all, always, any, appendLedger, appendPrompt, bodyPassed, commandSucceeds, commit, compactLedger, composeCommitBody, conflictedFiles, consolidate, consolidateJob, currentBranch, dag, defineJob, deleteBranch, describeConditions, ensureIgnored, exitCodeFor, feedbackBlock, forgeChecks, formatEvent, gateJob, graphPositionBlock, groundingText, hasStagedChanges, headSha, isDirty, isRepo, isRequiredFeedbackSeverity, isolated, jobMeta, kickback, ledgerPath, listRuns, log, loop, mergeAbort, mergeBranch, mergeJob, mergeNoCommit, mergeSynthesis, minConfidence, mockVerdict, never, normalizeFeedbackSeverity, not, parallel, predicate, promptPath, pullRequestJob, push, pushJob, quorum, readLedger, readPrompt, readRunStatus, removeWorktree, renderPlan, resetLedger, resetPrompt, retrieveLedger, reviewContext, reviewPanel, revisionFromOutcome, revisionRequest, run, runEventsPath, runSemanticRecordsPath, runsHome, semanticRecordsFromEvent, sequence, stageAll, toCondition, tournament };
1134
+ export { type AgentCheckConfig, AgentDef, AgentRequest, AgentResult, BudgetConfig, type CommitInput, type CommitRecord, type CompactOptions, Condition, ConditionInput, type ConsolidateJobConfig, type ConsolidateOptions, DagConfig, EXIT_PAUSED, Engine, type EngineFactory, EngineName, EngineOptions, EngineRef, EngineRegistry, EnvHandle, Environment, FeedbackActionSeverity, FeedbackDecision, FeedbackFinding, FeedbackSeverity, Forge, GraphPosition, type GroundOptions, type IsolatedOptions, Job, JobContext, JobMeta, type LedgerEntry, LimitPolicy, type LogQuery, LoopConfig, LoopEvent, type MergeJobConfig, type MergeResult, type MergeSynthesisConfig, type MergeSynthesisResult, MockEngine, type MockEnvOptions, MockEnvironment, type MockResponder, Outcome, type PromptNote, type PullRequestJobConfig, type PushJobConfig, type PushOptions, type PushResult, type RetrieveOptions, type ReviewContextConfig, type ReviewPanelConfig, RevisionRequest, type RevisionRequestInput, RevisionRerun, type RunLive, type RunOptions, type RunResult, type RunStatus, type SemanticDecision, type SemanticOutcome, type SemanticRunRecord, Stats, type StatsSnapshot, type TournamentConfig, Usage, Workspace, type WorktreeHandle, addWorktree, agentCheck, all, always, any, appendLedger, appendPrompt, bodyPassed, commandSucceeds, commit, compactLedger, composeCommitBody, conflictedFiles, consolidate, consolidateJob, currentBranch, dag, defineJob, deleteBranch, describeConditions, ensureIgnored, exitCodeFor, feedbackBlock, forgeChecks, formatEvent, gateJob, graphPositionBlock, groundingText, hasStagedChanges, headSha, isDirty, isRepo, isRequiredFeedbackSeverity, isolated, jobMeta, kickback, ledgerPath, listRuns, log, loop, mergeAbort, mergeBranch, mergeJob, mergeNoCommit, mergeSynthesis, minConfidence, mockVerdict, never, normalizeFeedbackSeverity, not, parallel, predicate, promptPath, pullRequestJob, push, pushJob, quorum, readLedger, readPrompt, readRunStatus, removeWorktree, renderPlan, resetLedger, resetPrompt, retrieveLedger, reviewContext, reviewPanel, revisionFromOutcome, revisionRequest, run, runEventsPath, runSemanticRecordsPath, runsHome, semanticRecordsFromEvent, sequence, stageAll, toCondition, tournament, workspaceFingerprint };
package/dist/api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { mergeNoCommit, stageAll, commit, mergeAbort, log, setMeta, jobMeta, isRepo, addWorktree, childContext, composeCommitBody, mergeBranch, removeWorktree, deleteBranch, push, consolidate, toCondition, revisionFromOutcome, GhForge } from './chunk-WM5QVHM2.js';
2
- export { Budget, EXIT_PAUSED, EngineRegistry, GhForge, MockForge, Stats, addWorktree, agentCheck, agentContract, agentJob, all, always, any, appendLedger, appendPrompt, bodyPassed, buildChecksArgs, buildCreateArgs, buildEditArgs, buildMergeArgs, buildViewArgs, commandSucceeds, commit, commitJob, compactLedger, composeCommitBody, conflictedFiles, consolidate, consolidateJob, currentBranch, defineAgent, defineSkill, deleteBranch, describeConditions, ensureIgnored, exitCodeFor, feedbackBlock, fnJob, forgeChecks, formatEvent, fromFile, gateJob, graphPositionBlock, groundingText, hasStagedChanges, headSha, isDirty, isForge, isRepo, isRequiredFeedbackSeverity, jobMeta, kickback, ledgerPath, listRuns, log, loop, mergeAbort, mergeBranch, mergeNoCommit, minConfidence, never, normalizeFeedbackSeverity, not, predicate, promptPath, push, quorum, readLedger, readPrompt, readRunStatus, removeWorktree, renderPlan, resetLedger, resetPrompt, resolveSystem, retrieveLedger, reviewContext, reviewPanel, revisionFromOutcome, revisionRequest, run, runEventsPath, runSemanticRecordsPath, runsHome, semanticRecordsFromEvent, stageAll, toCondition } from './chunk-WM5QVHM2.js';
1
+ import { mergeNoCommit, stageAll, commit, mergeAbort, log, setMeta, jobMeta, isRepo, addWorktree, childContext, composeCommitBody, mergeBranch, removeWorktree, deleteBranch, push, consolidate, toCondition, revisionFromOutcome, GhForge } from './chunk-3PMVII43.js';
2
+ export { Budget, EXIT_PAUSED, EngineRegistry, GhForge, MockForge, ProgressTracker, Stats, addWorktree, agentCheck, agentContract, agentJob, all, always, any, appendLedger, appendPrompt, bodyPassed, buildChecksArgs, buildCreateArgs, buildEditArgs, buildMergeArgs, buildViewArgs, commandSucceeds, commit, commitJob, compactLedger, composeCommitBody, conflictedFiles, consolidate, consolidateJob, currentBranch, defineAgent, defineSkill, deleteBranch, describeConditions, ensureIgnored, exitCodeFor, feedbackBlock, fnJob, forgeChecks, formatEvent, fromFile, gateJob, graphPositionBlock, groundingText, hasStagedChanges, headSha, isDirty, isForge, isRepo, isRequiredFeedbackSeverity, jobMeta, kickback, ledgerPath, listRuns, log, loop, mergeAbort, mergeBranch, mergeNoCommit, minConfidence, never, normalizeFeedbackSeverity, not, predicate, promptPath, push, quorum, readLedger, readPrompt, readRunStatus, removeWorktree, renderPlan, resetLedger, resetPrompt, resolveNoProgress, resolveSystem, retrieveLedger, reviewContext, reviewPanel, revisionFromOutcome, revisionRequest, run, runEventsPath, runSemanticRecordsPath, runsHome, semanticRecordsFromEvent, stageAll, toCondition, workspaceFingerprint } from './chunk-3PMVII43.js';
3
3
  import './chunk-JFTXJ7I2.js';
4
4
  export { SUBAGENT_TOOLS, isEngine } from './chunk-MA6NDQMO.js';
5
5
  import './chunk-Y2SD7GBL.js';
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/merge.ts","../src/core/dag.ts","../src/core/tournament.ts","../src/core/pr.ts","../src/core/isolated.ts","../src/engines/mock.ts","../src/env/environment.ts","../src/env/mock.ts","../src/api.ts"],"names":["forkSeq","isolated","outcome","run","slug","pLimit"],"mappings":"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","file":"api.js","sourcesContent":["/**\n * Merge as synthesis (GCC's `MERGE`). A raw `git merge` either applies cleanly or\n * fails on conflict. `mergeSynthesis` does the thing a teammate does: when two\n * lines of work collide, an agent RESOLVES each conflicted file coherently\n * (preserving both intents), and the merge commit body is a SYNTHESIS of what the\n * two branches were each trying to do — not \"merge branch X\".\n *\n * It is text-in/text-out, so it works through any `Engine` (no tool-use needed):\n * the conflicted file content goes in, the resolved content comes back. Light: a\n * call per conflicted file plus one for the synthesis body, and nothing when the\n * merge is already clean. The merge is aborted if resolution throws, so the target\n * is never left half-merged.\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport type { JobContext } from './types.ts';\nimport type { EngineRef } from '../engines/engine.ts';\nimport {\n mergeNoCommit,\n mergeAbort,\n stageAll,\n commit,\n log,\n} from './git.ts';\nimport { LoopError } from './errors.ts';\n\nexport interface MergeSynthesisConfig {\n /** The branch to land into the current workspace. */\n branch: string;\n /** Conventional subject for the merge commit. */\n message?: string;\n engine?: EngineRef;\n model?: string;\n}\n\nexport interface MergeSynthesisResult {\n ok: boolean;\n /** Whether a conflict had to be resolved. */\n conflict: boolean;\n sha?: string;\n}\n\n/** Strip a single wrapping code fence a model sometimes adds around file output. */\nfunction stripFence(s: string): string {\n const m = /^```[^\\n]*\\n([\\s\\S]*?)\\n```$/.exec(s.trim());\n return `${(m ? m[1]! : s).replace(/\\s+$/, '')}\\n`;\n}\n\nfunction firstLine(s: string): string {\n return s.split('\\n').find((l) => l.trim()) ?? '';\n}\n\nexport async function mergeSynthesis(\n ctx: JobContext,\n config: MergeSynthesisConfig,\n): Promise<MergeSynthesisResult> {\n const cwd = ctx.workspace.dir;\n const engine = config.engine ? ctx.resolveEngine(config.engine) : ctx.engine;\n const merge = await mergeNoCommit(cwd, config.branch, { signal: ctx.signal });\n\n try {\n if (!merge.clean) {\n for (const file of merge.conflicted) {\n const conflicted = readFileSync(join(cwd, file), 'utf8');\n const out = await engine.run(\n {\n prompt:\n `Resolve this git merge conflict in \\`${file}\\`. Combine both sides ` +\n `coherently, preserving the intent of each. Output ONLY the fully ` +\n `resolved file content — no conflict markers, no commentary, no code ` +\n `fence.\\n\\n${conflicted}`,\n model: config.model,\n maxTokens: 4000,\n },\n () => {},\n ctx.signal,\n );\n writeFileSync(join(cwd, file), stripFence(out.text));\n }\n await stageAll({ cwd, signal: ctx.signal });\n }\n\n const body = await synthesiseBody(ctx, engine, config);\n const sha = await commit(\n {\n subject: config.message ?? `merge: ${config.branch} (synthesis)`,\n body,\n allowEmpty: true, // a merge commit may have an empty diff after resolution\n },\n { cwd, signal: ctx.signal },\n );\n return { ok: true, conflict: !merge.clean, sha };\n } catch (e) {\n await mergeAbort(cwd, { signal: ctx.signal }).catch(() => {});\n throw LoopError.from(e, { code: 'BODY', path: ctx.path });\n }\n}\n\n/** Compose the merge body from the merged branch's own \"ways\". */\nasync function synthesiseBody(\n ctx: JobContext,\n engine: ReturnType<JobContext['resolveEngine']>,\n config: MergeSynthesisConfig,\n): Promise<string> {\n const ways = await log({\n cwd: ctx.workspace.dir,\n ref: config.branch,\n max: 8,\n signal: ctx.signal,\n });\n const summary = ways\n .map((w) => `- ${w.subject}${w.body ? `: ${firstLine(w.body)}` : ''}`)\n .join('\\n');\n const out = await engine.run(\n {\n prompt:\n `A branch is being merged. Its commits:\\n${summary || '(none)'}\\n\\n` +\n `Write a concise MERGE SYNTHESIS for the commit body: what this line of ` +\n `work accomplished, how it integrates, and any tradeoff reconciled. A few ` +\n `sentences, no preamble.`,\n system: 'You write merge synthesis commit bodies that capture intent.',\n model: config.model,\n maxTokens: 600,\n },\n () => {},\n ctx.signal,\n );\n return out.text.trim();\n}\n","/**\n * The DAG / stages layer. `dag(config)` returns a `Job`, so it nests with\n * `loop()` both ways. Nodes declare `needs` (dependencies); each node waits on\n * its dependencies' promises, then runs under a shared `p-limit` concurrency\n * gate. Cycle/missing-dep detection is delegated to `toposort` and happens\n * before any work runs.\n *\n * Failure policy (ours, not the libs'):\n * - a required node failing blocks its dependents (they don't run);\n * - with `stopOnError` (default) the first required failure stops scheduling\n * anything not already in flight;\n * - `optional` nodes never fail the DAG nor block dependents;\n * - an unmet `when` gate *skips* the node, which counts as green.\n */\n\nimport pLimit from 'p-limit';\nimport toposort from 'toposort';\n\nimport type {\n DagConfig,\n DagNode,\n Job,\n JobContext,\n Outcome,\n Workspace,\n} from './types.ts';\nimport { childContext } from './context.ts';\nimport { toCondition } from './condition.ts';\nimport { setMeta, jobMeta } from './describe.ts';\nimport {\n isRepo,\n stageAll,\n commit,\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n} from './git.ts';\nimport { composeCommitBody } from './consolidate.ts';\nimport { mergeSynthesis } from './merge.ts';\nimport type { EnvHandle } from '../env/environment.ts';\nimport { LoopError } from './errors.ts';\nimport { revisionFromOutcome } from './feedback.ts';\n\n/** Sanitise a name into a git-ref-safe slug. */\nfunction slug(s: string): string {\n return s.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/(^-+|-+$)/g, '') || 'node';\n}\n\nfunction normalize(node: DagNode | Job): DagNode {\n return typeof node === 'function' ? { job: node } : node;\n}\n\nexport function dag(config: DagConfig): Job {\n if (!config.name)\n throw new LoopError({\n code: 'CONFIG',\n message: 'dag() requires a non-empty name',\n });\n const names = Object.keys(config.nodes);\n const nodes = new Map<string, DagNode>(\n names.map((n) => [n, normalize(config.nodes[n]!)]),\n );\n\n // Fail fast on a bad graph, before the Job is ever run.\n const edges: [string, string][] = [];\n for (const [name, node] of nodes) {\n for (const dep of node.needs ?? []) {\n if (!nodes.has(dep)) {\n throw new LoopError({\n code: 'CONFIG',\n message: `dag \"${config.name}\": node \"${name}\" needs unknown node \"${dep}\"`,\n });\n }\n edges.push([dep, name]); // dep must precede name\n }\n }\n let order: string[];\n try {\n order = toposort.array(names, edges);\n } catch (e) {\n throw new LoopError({\n code: 'CONFIG',\n message: `dag \"${config.name}\": dependency cycle detected`,\n cause: e,\n });\n }\n\n const stopOnError = config.stopOnError ?? true;\n const maxKickbacks = config.maxKickbacks ?? 0;\n\n // Static graph relations for routing cross-stage feedback (kickback). All pure\n // functions of the declared `needs` edges, computed once. `dependents` is the\n // forward adjacency (who needs me); a kickback to a target re-runs the target\n // plus everything reachable from it, and the target must be an ancestor.\n const dependents = new Map<string, string[]>(names.map((n) => [n, []]));\n for (const [dep, name] of edges) dependents.get(dep)!.push(name);\n const ancestorsOf = (name: string): Set<string> => {\n const seen = new Set<string>();\n const stack = [...(nodes.get(name)!.needs ?? [])];\n while (stack.length) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n stack.push(...(nodes.get(n)!.needs ?? []));\n }\n return seen;\n };\n const dirtyFrom = (target: string): Set<string> => {\n const seen = new Set<string>([target]);\n const stack = [target];\n while (stack.length) {\n const n = stack.pop()!;\n for (const d of dependents.get(n)!)\n if (!seen.has(d)) {\n seen.add(d);\n stack.push(d);\n }\n }\n return seen;\n };\n const limitN =\n config.concurrency && config.concurrency > 0\n ? config.concurrency\n : names.length || 1;\n\n const job: Job = async (parent: JobContext): Promise<Outcome> => {\n const path = [...parent.path, config.name];\n const depth = parent.depth + 1;\n const ts = () => Date.now();\n parent.emit({ kind: 'dag:start', ts: ts(), path, depth, nodes: names });\n\n const limit = pLimit(limitN);\n const results = new Map<string, Outcome>();\n const memo = new Map<string, Promise<Outcome>>();\n // How many times each node has run (1 on the first pass, +1 per kickback\n // re-run). Stamped onto its dag:node events so records can tell rounds apart.\n const attempts = new Map<string, number>();\n let stopped = false;\n // When a node is kicked back to, the reason rides into its next run as\n // `lastReview` — the same channel a loop's failed `review` uses, so grounding\n // renders it as \"## Next\". Empty in the common (no-kickback) case.\n const pendingKickback = new Map<string, Outcome>();\n\n // Each node runs under its own name in the path, so a nested job (e.g. a\n // loop) is uniquely addressable for stats/logs even across same-named siblings.\n const nodeCtx = (\n name: string,\n workspace?: Workspace,\n environment?: EnvHandle,\n ): JobContext =>\n childContext(parent, {\n depth,\n path: [...path, name],\n workspace,\n environment,\n lastReview: pendingKickback.get(name),\n graph: {\n dag: config.name,\n node: name,\n path: [...path, name],\n needs: nodes.get(name)!.needs ?? [],\n dependents: dependents.get(name) ?? [],\n },\n });\n\n // Land-back merges are serialised: concurrent nodes finishing at once must\n // not race on the parent branch's index/HEAD.\n const mergeLimit = pLimit(1);\n let forkSeq = 0;\n\n /**\n * Run a node, in its own worktree when isolated. On pass the node's work is\n * captured (any uncommitted remainder is committed in the worktree) and\n * landed back into the parent branch (`--no-ff`, serialised). A merge\n * conflict fails the node honestly — loops does not auto-resolve. The\n * worktree is always removed; a cleanly-merged fork branch is deleted.\n */\n const runNodeJob = async (\n name: string,\n node: DagNode,\n ): Promise<Outcome> => {\n const isolated = node.isolate ?? config.isolation === 'worktree';\n if (!isolated) return node.job(nodeCtx(name));\n\n const base = parent.workspace;\n if (!(await isRepo({ cwd: base.dir, signal: parent.signal }))) {\n parent.log(\n `node \"${name}\" requested worktree isolation but ${base.dir} is not a git repo; running in the shared workspace`,\n 'warn',\n );\n return node.job(nodeCtx(name));\n }\n\n const branch = `loops/${slug(config.name)}-${slug(name)}-${(forkSeq += 1)}`;\n const wt = await addWorktree(base.dir, {\n branch,\n base: 'HEAD',\n signal: parent.signal,\n });\n const wtWs: Workspace = { dir: wt.dir, branch };\n // Each team gets its own environment, named after its branch — born with\n // the worktree, torn down with it. A failed start propagates and the node\n // is recorded as failed; the worktree is still cleaned up in `finally`.\n let envHandle: EnvHandle | undefined;\n try {\n if (config.environment)\n envHandle = await config.environment.up(wtWs, parent.signal);\n const outcome = await node.job(nodeCtx(name, wtWs, envHandle));\n if (outcome.status === 'pass') {\n // Capture anything the node left uncommitted, so nothing is stranded\n // in the worktree, then land it back.\n await stageAll({ cwd: wt.dir, signal: parent.signal });\n await commit(\n {\n subject: `chore(${slug(name)}): worktree changes`,\n body: await composeCommitBody(parent, wtWs),\n },\n { cwd: wt.dir, signal: parent.signal },\n );\n const merged = await mergeLimit(() =>\n mergeBranch(base.dir, branch, {\n signal: parent.signal,\n message: `merge ${branch} (node ${name})`,\n }),\n );\n if (!merged.ok) {\n // Conflict. Either fail honestly, or synthesise the merge (an agent\n // resolves it and writes a synthesised body).\n if (config.onConflict !== 'synthesize') {\n return {\n status: 'fail',\n summary: `node \"${name}\" landed with a merge conflict; needs resolution`,\n error: new LoopError({\n code: 'BODY',\n message: `merge conflict landing node \"${name}\"`,\n path: [...path, name],\n }),\n };\n }\n try {\n await mergeLimit(() =>\n mergeSynthesis(parent, {\n branch,\n message: `merge: ${branch} (node ${name}, synthesis)`,\n }),\n );\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n path: [...path, name],\n });\n return {\n status: 'fail',\n summary: `node \"${name}\" merge synthesis failed: ${error.message}`,\n error,\n };\n }\n }\n await deleteBranch(base.dir, branch, { signal: parent.signal }).catch(\n () => {},\n );\n }\n return outcome;\n } finally {\n if (envHandle)\n await envHandle.down(parent.signal).catch(() => {});\n await removeWorktree(base.dir, wt.dir, {\n signal: parent.signal,\n }).catch(() => {});\n }\n };\n\n const record = (\n name: string,\n outcome: Outcome,\n phase: 'done' | 'skip',\n ): Outcome => {\n results.set(name, outcome);\n parent.emit({\n kind: 'dag:node',\n ts: ts(),\n path,\n node: name,\n phase,\n outcome,\n attempt: attempts.get(name),\n });\n if (\n phase === 'done' &&\n outcome.status !== 'pass' &&\n nodes.get(name)!.optional !== true &&\n stopOnError &&\n // A node requesting a kickback is going to be re-run — don't let its\n // (provisional) non-pass abort siblings before the feedback is resolved.\n !(maxKickbacks > 0 && revisionFromOutcome(outcome)?.target)\n ) {\n stopped = true;\n }\n return outcome;\n };\n\n const run = (name: string): Promise<Outcome> => {\n const existing = memo.get(name);\n if (existing) return existing;\n const node = nodes.get(name)!;\n const promise = (async (): Promise<Outcome> => {\n // This node's run count: 1 the first time, +1 each kickback re-run (the\n // memo/results were cleared for the dirty subgraph, so run() re-enters).\n attempts.set(name, (attempts.get(name) ?? 0) + 1);\n // Whole node is guarded: a throw anywhere (dep resolution, `when`, the\n // job) becomes a recorded outcome, so the DAG always reaches `dag:end`.\n try {\n const needs = node.needs ?? [];\n const deps = await Promise.all(needs.map(run));\n // A non-pass dependency blocks this node — a declared `needs` is a real\n // data dependency, so even a failed *optional* producer blocks a\n // consumer (skipped deps come back with status 'pass', so they're green).\n const blocked = needs.some((_, i) => deps[i]!.status !== 'pass');\n if (blocked)\n return record(\n name,\n { status: 'aborted', summary: 'blocked by a failed dependency' },\n 'done',\n );\n if (parent.signal.aborted || stopped)\n return record(\n name,\n { status: 'aborted', summary: 'aborted before start' },\n 'done',\n );\n\n // `when` + the job both run inside the concurrency limit, so an\n // agentCheck gate counts against the cap (it's real backend load).\n const result = await limit(\n async (): Promise<{ outcome: Outcome; phase: 'done' | 'skip' }> => {\n if (parent.signal.aborted || stopped)\n return {\n outcome: {\n status: 'aborted',\n summary: 'aborted before start',\n },\n phase: 'done',\n };\n if (node.when) {\n const r = await toCondition(node.when)(\n nodeCtx(name),\n undefined,\n );\n if (!r.met)\n return {\n outcome: {\n status: 'pass',\n summary: `skipped: ${r.reason}`,\n data: { skipped: true },\n },\n phase: 'skip',\n };\n }\n parent.emit({\n kind: 'dag:node',\n ts: ts(),\n path,\n node: name,\n phase: 'start',\n attempt: attempts.get(name),\n });\n return { outcome: await runNodeJob(name, node), phase: 'done' };\n },\n );\n return record(name, result.outcome, result.phase);\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n phase: 'body',\n path: [...path, name],\n });\n parent.emit({\n kind: 'error',\n ts: ts(),\n path: [...path, name],\n message: error.message,\n code: error.code,\n });\n return record(\n name,\n { status: 'fail', summary: error.message, error },\n 'done',\n );\n }\n })();\n memo.set(name, promise);\n return promise;\n };\n\n await Promise.all(names.map(run));\n\n // Cross-stage feedback: a node may return a `kickback` asking an earlier\n // node to redo work. We re-run the target + its dependents (the cycle lives\n // in execution, the graph stays acyclic), bounded by `maxKickbacks` so it\n // provably terminates. The whole block is inert when `maxKickbacks` is 0, so\n // the default path is exactly the single pass above.\n if (maxKickbacks > 0) {\n let used = 0;\n const rejected = new Set<string>();\n const emitKickback = (\n from: string,\n to: string,\n reason: string,\n accepted: boolean,\n note?: string,\n ) =>\n parent.emit({\n kind: 'dag:kickback',\n ts: ts(),\n path,\n from,\n to,\n reason,\n accepted,\n note,\n });\n for (;;) {\n // Honour kickbacks in topological order, skipping any already rejected.\n const from = order.find(\n (n) => {\n const result = results.get(n);\n return (\n result !== undefined &&\n revisionFromOutcome(result)?.target !== undefined &&\n !rejected.has(n)\n );\n },\n );\n if (!from) break;\n const request = revisionFromOutcome(results.get(from)!)!;\n const to = request.target!;\n const { reason } = request;\n\n // Validate the target: it must exist, be an ancestor, and (if the node\n // declares `acceptsKickbackTo`) be an allowed target. An invalid target\n // is rejected once and never reconsidered unless the node itself re-runs.\n const allow = nodes.get(from)!.acceptsKickbackTo;\n const note = !nodes.has(to)\n ? `unknown node \"${to}\"`\n : !ancestorsOf(from).has(to)\n ? `\"${to}\" is not an ancestor of \"${from}\"`\n : allow && !allow.includes(to)\n ? `\"${from}\" does not accept kickback to \"${to}\"`\n : undefined;\n if (note) {\n rejected.add(from);\n emitKickback(from, to, reason, false, note);\n continue;\n }\n\n if (used >= maxKickbacks) {\n // Budget spent. Reject and stop — the unresolved kickback leaves the\n // kicking node's own outcome to stand (a fail keeps the dag honest).\n emitKickback(\n from,\n to,\n reason,\n false,\n `kickback budget (${maxKickbacks}) exhausted`,\n );\n break;\n }\n\n used += 1;\n emitKickback(from, to, reason, true);\n const dirty = dirtyFrom(to);\n for (const d of dirty) {\n memo.delete(d); // force re-run\n results.delete(d);\n rejected.delete(d); // a re-run earns a fresh verdict\n }\n pendingKickback.set(to, {\n status: 'fail',\n summary: `Kicked back from \"${from}\": ${reason}`,\n revision: { ...request, source: request.source ?? from },\n });\n stopped = false; // a prior stopOnError must not block the re-run\n await Promise.all(names.map(run));\n }\n }\n\n const requiredFailed = names.filter(\n (n) =>\n results.get(n)?.status === 'fail' && nodes.get(n)!.optional !== true,\n );\n const requiredAborted = names.filter(\n (n) =>\n results.get(n)?.status === 'aborted' && nodes.get(n)!.optional !== true,\n );\n const data = Object.fromEntries(results);\n let outcome: Outcome;\n if (parent.signal.aborted) {\n // a genuine user/signal cancellation\n outcome = {\n status: 'aborted',\n summary: `dag \"${config.name}\" aborted`,\n data,\n };\n } else if (requiredFailed.length > 0 || requiredAborted.length > 0) {\n // a real failure (direct, or a required node left undone by an upstream\n // failure) is a fail (exit 1), distinct from a cancellation (exit 130).\n outcome = {\n status: 'fail',\n summary: `dag \"${config.name}\": ${requiredFailed.length + requiredAborted.length} required node(s) did not complete`,\n data,\n };\n } else {\n outcome = {\n status: 'pass',\n summary: `dag \"${config.name}\": all ${names.length} node(s) green`,\n data,\n };\n }\n parent.emit({ kind: 'dag:end', ts: ts(), path, outcome });\n return outcome;\n };\n\n return setMeta(job, {\n kind: 'dag',\n name: config.name,\n nodes: Object.entries(config.nodes).map(([name, v]) => {\n const node = typeof v === 'function' ? undefined : v;\n const nodeJob = node ? node.job : (v as Job);\n return {\n name,\n needs: node?.needs ?? [],\n isolate: node?.isolate ?? false,\n job: jobMeta(nodeJob),\n };\n }),\n });\n}\n\n/** Run jobs strictly in order; stop at the first non-pass. Sugar over `dag`. */\nexport function sequence(name: string, ...jobs: Job[]): Job {\n const nodes: Record<string, DagNode> = {};\n jobs.forEach((job, i) => {\n nodes[`step-${i}`] = { job, needs: i > 0 ? [`step-${i - 1}`] : [] };\n });\n return dag({ name, nodes, concurrency: 1, stopOnError: true });\n}\n\n/** Run jobs concurrently (optionally capped); all run regardless of failures. */\nexport function parallel(\n name: string,\n jobs: Record<string, Job> | Job[],\n concurrency?: number,\n): Job {\n const record = Array.isArray(jobs)\n ? Object.fromEntries(jobs.map((j, i) => [`task-${i}`, j] as const))\n : jobs;\n return dag({ name, nodes: record, concurrency, stopOnError: false });\n}\n","/**\n * Tournament — branch-and-select (GCC's `BRANCH` + pick-the-winner). Where a DAG\n * fans out DISJOINT work and lands all of it, a tournament explores ALTERNATIVE\n * approaches to the SAME task: run N candidates, each in its own isolated\n * worktree, judge them, land only the winner and discard the rest.\n *\n * It is a thin composition over the worktree primitives — no new machinery. Only\n * one branch is ever merged (the winner, off an unchanged HEAD), so there is no\n * conflict to resolve. Small on purpose.\n */\n\nimport pLimit from 'p-limit';\n\nimport type { Job, JobContext, Outcome, Workspace } from './types.ts';\nimport { childContext } from './context.ts';\nimport {\n isRepo,\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n stageAll,\n commit,\n} from './git.ts';\nimport { composeCommitBody } from './consolidate.ts';\nimport { LoopError } from './errors.ts';\n\nfunction slug(s: string): string {\n return s.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/(^-+|-+$)/g, '') || 'x';\n}\n\nexport interface TournamentConfig {\n name: string;\n /** Candidates to run. */\n n: number;\n /** Build the candidate job for attempt `i` (0-based) — same task, varied angle. */\n candidate: (i: number) => Job;\n /**\n * Score a finished candidate (higher wins). Run against the candidate's own\n * context, so it can read the candidate's workspace. The highest-scoring\n * passing candidate lands back; ties break to the earliest.\n */\n judge: (outcome: Outcome, ctx: JobContext) => number | Promise<number>;\n /** Max candidates running at once. Default `n`. */\n concurrency?: number;\n}\n\ninterface Attempt {\n i: number;\n branch: string;\n dir: string;\n outcome: Outcome;\n score: number;\n}\n\nexport function tournament(config: TournamentConfig): Job {\n if (!config.name)\n throw new LoopError({\n code: 'CONFIG',\n message: 'tournament() requires a non-empty name',\n });\n if (config.n < 1)\n throw new LoopError({ code: 'CONFIG', message: 'tournament() needs n >= 1' });\n\n return async (parent: JobContext): Promise<Outcome> => {\n const path = [...parent.path, config.name];\n const base = parent.workspace;\n parent.emit({\n kind: 'job:start',\n ts: Date.now(),\n path,\n label: config.name,\n });\n\n if (!(await isRepo({ cwd: base.dir, signal: parent.signal }))) {\n const error = new LoopError({\n code: 'CONFIG',\n message: `tournament \"${config.name}\" requires a git repository (cwd: ${base.dir})`,\n });\n return { status: 'fail', summary: error.message, error };\n }\n\n const limit = pLimit(config.concurrency ?? config.n);\n const attempts = await Promise.all(\n Array.from({ length: config.n }, (_, i) =>\n limit(async (): Promise<Attempt> => {\n const branch = `loops/${slug(config.name)}-cand-${i}`;\n const wt = await addWorktree(base.dir, {\n branch,\n base: 'HEAD',\n signal: parent.signal,\n });\n const ws: Workspace = { dir: wt.dir, branch };\n try {\n const ctx = childContext(parent, {\n depth: parent.depth + 1,\n path: [...path, `#${i}`],\n workspace: ws,\n });\n const outcome = await config.candidate(i)(ctx);\n // Capture the candidate's work onto its branch so the winner can land.\n await stageAll({ cwd: wt.dir, signal: parent.signal });\n await commit(\n {\n subject: `${config.name}: candidate ${i}`,\n body: await composeCommitBody(ctx, ws),\n },\n { cwd: wt.dir, signal: parent.signal },\n );\n const score =\n outcome.status === 'pass' ? await config.judge(outcome, ctx) : -1;\n parent.log(`${config.name} candidate ${i}: score ${score}`);\n return { i, branch, dir: wt.dir, outcome, score };\n } catch (e) {\n const error = LoopError.from(e, { code: 'BODY', path });\n return {\n i,\n branch,\n dir: wt.dir,\n outcome: { status: 'fail', summary: error.message, error },\n score: -1,\n };\n }\n }),\n ),\n );\n\n // Winner: highest score among passing candidates; ties to the earliest.\n const winner = [...attempts]\n .filter((a) => a.outcome.status === 'pass' && a.score >= 0)\n .sort((a, b) => b.score - a.score || a.i - b.i)[0];\n\n let landed = false;\n if (winner) {\n const merged = await mergeBranch(base.dir, winner.branch, {\n signal: parent.signal,\n message: `${config.name}: land candidate ${winner.i} (score ${winner.score})`,\n });\n landed = merged.ok;\n }\n\n // Tear down every worktree; delete loser branches and the merged winner.\n for (const a of attempts) {\n await removeWorktree(base.dir, a.dir, { signal: parent.signal }).catch(\n () => {},\n );\n if (a !== winner || landed)\n await deleteBranch(base.dir, a.branch, {\n signal: parent.signal,\n }).catch(() => {});\n }\n\n const outcome: Outcome = winner\n ? {\n status: landed ? 'pass' : 'fail',\n confidence: winner.outcome.confidence,\n summary: landed\n ? `tournament \"${config.name}\": landed candidate ${winner.i} (score ${winner.score}) of ${config.n}`\n : `tournament \"${config.name}\": winner ${winner.i} failed to land`,\n data: {\n winner: winner.i,\n score: winner.score,\n scores: attempts.map((a) => ({ i: a.i, score: a.score })),\n },\n }\n : {\n status: 'fail',\n summary: `tournament \"${config.name}\": no candidate passed`,\n data: { scores: attempts.map((a) => ({ i: a.i, score: a.score })) },\n };\n parent.emit({ kind: 'job:end', ts: Date.now(), path, label: config.name, outcome });\n return outcome;\n };\n}\n","/**\n * Pull-request jobs — how a converged branch becomes a PR whose body stays a\n * faithful synthesis of the work, so the commit-log memory survives a squash merge.\n *\n * The squash-merge problem: a branch carries N milestone commits, each with a rich\n * structured \"way\" (the Ledger). A squash merge collapses them into one commit whose\n * body GitHub defaults to a list of subject lines — the reasoning is lost from the\n * base branch's history. The fix is small because loops already folds many commit\n * bodies into one: `pullRequestJob` sets the PR body to `consolidate(since: base)` —\n * the same decision-preserving fold, scoped to this branch — and keeps it current.\n * `mergeJob` can then squash with that synthesis as the commit body directly.\n *\n * Engine-agnostic and host-agnostic: the host is the injectable `Forge` seam\n * (default `GhForge`), so these jobs run offline against a `MockForge` in tests.\n */\n\nimport type { Job, JobContext, Outcome, ConditionInput } from './types.ts';\nimport { LoopError } from './errors.ts';\nimport { push } from './git.ts';\nimport { consolidate } from './consolidate.ts';\nimport { GhForge, type Forge, type PrRef } from './forge.ts';\nimport { toCondition } from './condition.ts';\n\n/** Resolve the host: the run's `forge`, else the GitHub CLI adapter. */\nfunction resolveForge(ctx: JobContext): Forge {\n return ctx.forge ?? new GhForge();\n}\n\ntype Derive<T> =\n | T\n | ((ctx: JobContext, last: Outcome | undefined) => T | Promise<T>);\n\nasync function derive<T>(\n value: Derive<T> | undefined,\n ctx: JobContext,\n last: Outcome | undefined,\n): Promise<T | undefined> {\n if (value === undefined) return undefined;\n return typeof value === 'function'\n ? await (value as (c: JobContext, l: Outcome | undefined) => T | Promise<T>)(\n ctx,\n last,\n )\n : value;\n}\n\nexport interface PushJobConfig {\n label?: string;\n /** Remote to push to. Default `origin`. */\n remote?: string;\n /** Branch to push. Default the workspace branch. */\n branch?: string;\n /** Set upstream tracking. Default true. */\n setUpstream?: boolean;\n /** Force-with-lease. Default false. */\n force?: boolean;\n}\n\n/** Push the work branch to its remote. Idempotent; a rejected push fails honestly. */\nexport function pushJob(config: PushJobConfig = {}): Job {\n return async (ctx) => {\n const label = config.label ?? 'push';\n const path = [...ctx.path];\n ctx.emit({ kind: 'job:start', ts: Date.now(), path, label });\n const branch = config.branch ?? ctx.workspace.branch;\n const res = await push({\n cwd: ctx.workspace.dir,\n signal: ctx.signal,\n remote: config.remote,\n branch,\n setUpstream: config.setUpstream,\n force: config.force,\n });\n const outcome: Outcome = res.ok\n ? { status: 'pass', summary: `pushed ${branch ?? 'HEAD'}` }\n : {\n status: 'fail',\n summary: `push failed: ${res.output}`,\n error: new LoopError({ code: 'BODY', message: res.output }),\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n };\n}\n\nexport interface PullRequestJobConfig {\n label?: string;\n /** PR title, or a function of context. Default: the converged outcome summary. */\n title?: Derive<string>;\n /** Base branch to merge into, and the `since` bound for the body fold. Default `main`. */\n base?: string;\n /** Push the branch first (idempotent). Default true; pass a config to tune. */\n push?: boolean | PushJobConfig;\n /** Open as a draft when first created. */\n draft?: boolean;\n /** Model for the body consolidation call. */\n model?: string;\n /** Max milestones to fold into the body. Default 50. */\n max?: number;\n /** Override the synthesized body (else: consolidate the branch's commit bodies). */\n body?: Derive<string>;\n}\n\n/**\n * Raise the PR, or update it if it already exists, with a body synthesized from the\n * branch's commit bodies. Idempotent create-or-update: run it after each milestone\n * (or at convergence) and the PR description stays current — that is what keeps the\n * eventual squash body honest. Returns the `PrRef` in `outcome.data.pr`.\n */\nexport function pullRequestJob(config: PullRequestJobConfig = {}): Job {\n return async (ctx) => {\n const label = config.label ?? 'pull-request';\n const path = [...ctx.path];\n ctx.emit({ kind: 'job:start', ts: Date.now(), path, label });\n try {\n const branch = ctx.workspace.branch;\n if (!branch)\n throw new LoopError({\n code: 'CONFIG',\n message: `pullRequestJob \"${label}\" needs a branch checked out (detached HEAD or non-repo)`,\n });\n const base = config.base ?? 'main';\n const last = ctx.lastOutcome;\n\n if (config.push !== false) {\n const res = await push({\n cwd: ctx.workspace.dir,\n signal: ctx.signal,\n branch,\n ...(typeof config.push === 'object' ? config.push : {}),\n });\n if (!res.ok)\n throw new LoopError({\n code: 'BODY',\n message: `push failed: ${res.output}`,\n });\n }\n\n const body =\n (await derive(config.body, ctx, last)) ??\n (await consolidate(ctx, {\n since: base,\n max: config.max ?? 50,\n model: config.model,\n }));\n const title = (await derive(config.title, ctx, last)) ?? last?.summary ?? branch;\n\n const forge = resolveForge(ctx);\n const fopts = { cwd: ctx.workspace.dir, signal: ctx.signal };\n const existing = await forge.viewPr(branch, fopts);\n let pr: PrRef;\n if (existing) {\n await forge.editPr(existing, { body }, fopts);\n pr = existing;\n } else {\n pr = await forge.createPr(\n { title, body, base, branch, draft: config.draft },\n fopts,\n );\n }\n const outcome: Outcome = {\n status: 'pass',\n summary: `${existing ? 'updated' : 'opened'} PR #${pr.number}`,\n data: { pr },\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n phase: 'body',\n path: ctx.path,\n });\n ctx.emit({\n kind: 'error',\n ts: Date.now(),\n path,\n message: error.message,\n code: error.code,\n });\n const outcome: Outcome = { status: 'fail', summary: error.message, error };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n }\n };\n}\n\nexport interface MergeJobConfig {\n label?: string;\n /** Base branch — the `since` bound for re-synthesizing the squash body. Default `main`. */\n base?: string;\n /** Squash merge (default true) — the whole reason this exists. */\n squash?: boolean;\n /**\n * Hand the merge to GitHub auto-merge (`gh pr merge --auto`): it lands once the\n * required checks pass. The recommended \"merge when CI is green\" path — non-blocking.\n */\n auto?: boolean;\n /** Delete the head branch after merge. */\n deleteBranch?: boolean;\n /** Squash commit subject. */\n subject?: Derive<string>;\n /** Squash commit body. Default: re-consolidate the branch (the up-to-date synthesis). */\n body?: Derive<string>;\n model?: string;\n max?: number;\n /**\n * A gate that must hold before loops issues the merge — e.g. `forgeChecks()` for a\n * synchronous \"CI is green\" check, or any `Condition`. Unmet → the job fails without\n * merging. (For the non-blocking path, prefer `auto: true` and let GitHub gate.)\n */\n when?: ConditionInput;\n}\n\n/**\n * Squash-merge the branch's PR with a body synthesized from its commit bodies — so the\n * one commit that lands on the base branch carries the whole \"way\", not a list of\n * subjects. Opt-in (loops performing an outward merge is high-stakes): gate it with\n * `auto: true` (GitHub merges when checks pass) and/or a `when` condition.\n */\nexport function mergeJob(config: MergeJobConfig = {}): Job {\n return async (ctx) => {\n const label = config.label ?? 'merge';\n const path = [...ctx.path];\n ctx.emit({ kind: 'job:start', ts: Date.now(), path, label });\n try {\n const branch = ctx.workspace.branch;\n if (!branch)\n throw new LoopError({\n code: 'CONFIG',\n message: `mergeJob \"${label}\" needs a branch checked out`,\n });\n const forge = resolveForge(ctx);\n const fopts = { cwd: ctx.workspace.dir, signal: ctx.signal };\n const pr = await forge.viewPr(branch, fopts);\n if (!pr)\n throw new LoopError({\n code: 'CONFIG',\n message: `mergeJob \"${label}\": no open PR for branch \"${branch}\" — run pullRequestJob first`,\n });\n\n if (config.when) {\n const r = await toCondition(config.when)(ctx, ctx.lastOutcome);\n if (!r.met) {\n const outcome: Outcome = {\n status: 'fail',\n summary: `merge gate not met: ${r.reason}`,\n data: { pr },\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n }\n }\n\n const last = ctx.lastOutcome;\n const base = config.base ?? 'main';\n // Re-synthesize at merge time so the squash body reflects the final branch.\n const body =\n (await derive(config.body, ctx, last)) ??\n (await consolidate(ctx, {\n since: base,\n max: config.max ?? 50,\n model: config.model,\n }));\n const subject = await derive(config.subject, ctx, last);\n\n await forge.mergePr(pr, {\n ...fopts,\n squash: config.squash,\n auto: config.auto,\n subject,\n body,\n deleteBranch: config.deleteBranch,\n });\n const outcome: Outcome = {\n status: 'pass',\n summary: `${config.auto ? 'enqueued' : 'merged'} PR #${pr.number}`,\n data: { pr },\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n phase: 'body',\n path: ctx.path,\n });\n ctx.emit({\n kind: 'error',\n ts: Date.now(),\n path,\n message: error.message,\n code: error.code,\n });\n const outcome: Outcome = { status: 'fail', summary: error.message, error };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n }\n };\n}\n","/**\n * `isolated(job)` — run any Job in its own git worktree on a fork branch, and land\n * its work back into the parent branch on pass. The concurrency boundary as a Job\n * WRAPPER, not a node type.\n *\n * dag nodes can already fork a worktree (`isolation: 'worktree'`), but that only\n * works for predeclared nodes. A Tend loop dispatches DYNAMICALLY — it discovers\n * each ticket at runtime and routes it to the right shape of sub-loop — and each\n * dispatch wants its own isolated worktree so parallel tickets never collide on\n * files or the index. `isolated()` makes that composable: wrap the dispatched Job.\n *\n * On pass: any uncommitted remainder is committed in the worktree, then the fork\n * branch merges back (`--no-ff`). Land-back merges are serialised across all\n * `isolated()` jobs in the process, so concurrent dispatch cannot race the parent\n * index/HEAD. A conflict fails honestly, or is synthesised when asked. The worktree\n * is always removed; a cleanly-merged fork branch is deleted. A non-repo workspace\n * degrades to running in place (a warning, no isolation).\n *\n * NOTE: dag's own runNodeJob holds parallel worktree/land-back logic (plus per-team\n * environments). The two should be unified — dag delegating to `isolated()` — once\n * `isolated()` grows environment support; until then the land-back logic lives in\n * both deliberately, to avoid destabilising the dag path.\n */\n\nimport pLimit from 'p-limit';\n\nimport type { Job, Workspace } from './types.ts';\nimport { childContext } from './context.ts';\nimport { LoopError } from './errors.ts';\nimport {\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n stageAll,\n commit,\n isRepo,\n} from './git.ts';\nimport { mergeSynthesis } from './merge.ts';\nimport { composeCommitBody } from './consolidate.ts';\n\nconst slug = (s: string) =>\n s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'job';\n\n/** Serialise land-back merges process-wide so concurrent dispatch can't race. */\nconst mergeLock = pLimit(1);\nlet forkSeq = 0;\n\nexport interface IsolatedOptions {\n /** Label for the fork branch and the child path. Default 'isolated'. */\n label?: string;\n /** On a land-back conflict: 'fail' (default) or 'synthesize'. */\n onConflict?: 'fail' | 'synthesize';\n}\n\n/** Wrap a Job so it runs in an isolated worktree and lands back on pass. */\nexport function isolated(job: Job, opts: IsolatedOptions = {}): Job {\n const label = opts.label ?? 'isolated';\n return async (parent) => {\n const base = parent.workspace;\n if (!(await isRepo({ cwd: base.dir, signal: parent.signal }))) {\n parent.log(\n `isolated(\"${label}\") requested a worktree but ${base.dir} is not a git repo; running in the shared workspace`,\n 'warn',\n );\n return job(parent);\n }\n\n const branch = `loops/${slug(label)}-${(forkSeq += 1)}`;\n const wt = await addWorktree(base.dir, {\n branch,\n base: 'HEAD',\n signal: parent.signal,\n });\n const wtWs: Workspace = { dir: wt.dir, branch };\n try {\n const ctx = childContext(parent, {\n workspace: wtWs,\n depth: parent.depth + 1,\n path: [...parent.path, label],\n });\n const outcome = await job(ctx);\n if (outcome.status === 'pass') {\n // Capture anything the job left uncommitted, then land it back.\n await stageAll({ cwd: wt.dir, signal: parent.signal });\n await commit(\n {\n subject: `chore(${slug(label)}): worktree changes`,\n body: await composeCommitBody(ctx, wtWs),\n },\n { cwd: wt.dir, signal: parent.signal },\n );\n const merged = await mergeLock(() =>\n mergeBranch(base.dir, branch, {\n signal: parent.signal,\n message: `merge ${branch}`,\n }),\n );\n if (!merged.ok) {\n if (opts.onConflict !== 'synthesize') {\n return {\n status: 'fail',\n summary: `isolated(\"${label}\") landed with a merge conflict; needs resolution`,\n error: new LoopError({\n code: 'BODY',\n message: `merge conflict landing isolated(\"${label}\")`,\n path: [...parent.path, label],\n }),\n };\n }\n try {\n await mergeLock(() =>\n mergeSynthesis(parent, {\n branch,\n message: `merge: ${branch} (synthesis)`,\n }),\n );\n } catch (e) {\n const error = LoopError.from(e, { code: 'BODY', path: [...parent.path, label] });\n return {\n status: 'fail',\n summary: `isolated(\"${label}\") merge synthesis failed: ${error.message}`,\n error,\n };\n }\n }\n await deleteBranch(base.dir, branch, { signal: parent.signal }).catch(() => {});\n }\n return outcome;\n } finally {\n await removeWorktree(base.dir, wt.dir, { signal: parent.signal }).catch(() => {});\n }\n };\n}\n","/**\n * A scripted, offline engine — the reference \"drop-in\". It implements the same\n * `Engine` interface as the real backends, so tests and examples run the exact\n * same loop/dag/condition code paths with zero network. Writing one of these is\n * all it takes to add a provider: implement `run`, register a name.\n */\n\nimport type {\n AgentRequest,\n AgentResult,\n Engine,\n EngineEventSink,\n Usage,\n} from './engine.ts';\n\nexport type MockResponder = (\n req: AgentRequest,\n) => string | { text: string; usage?: Usage; model?: string };\n\nexport class MockEngine implements Engine {\n readonly name = 'mock';\n constructor(private readonly responder: MockResponder) {}\n\n async run(\n req: AgentRequest,\n onEvent: EngineEventSink,\n signal: AbortSignal,\n ): Promise<AgentResult> {\n if (signal.aborted) {\n throw Object.assign(new Error('aborted'), { name: 'AbortError' });\n }\n const raw = this.responder(req);\n const out = typeof raw === 'string' ? { text: raw } : raw;\n const model = out.model ?? 'mock';\n const usage = out.usage ?? { inputTokens: 10, outputTokens: 5 };\n if (out.text) onEvent({ type: 'text', delta: out.text });\n onEvent({ type: 'usage', usage, model });\n return { text: out.text, usage, model, stopReason: 'end_turn' };\n }\n}\n\n/** Convenience: always reply with a verdict JSON (handy for validator tests). */\nexport function mockVerdict(\n verdict: 'yes' | 'no',\n confidence: number,\n reason = 'mock',\n): MockEngine {\n return new MockEngine(() => JSON.stringify({ verdict, confidence, reason }));\n}\n","/**\n * The Environment provider — the third axis, after Engine (where the agent\n * thinks) and Workspace (where the code lives). Environment is where the code\n * RUNS: local services, or a per-branch cloud preview. It is what lets the gate\n * be fully honest — \"done\" can mean \"the e2e suite passes against the running\n * preview\", not just \"unit tests pass against static files on disk\".\n *\n * Like `Engine`, this is only an interface. loops owns the seam and the\n * lifecycle binding; the actual adapter (sst, Vercel, Docker, …) is\n * provider-specific and lives in the CONSUMER's loop definition, next to the\n * deploy config it wraps. loops never takes a dependency on a deploy tool. Bring\n * your own in a few lines: implement `up`, return a handle.\n *\n * const sstEnv: Environment = {\n * name: 'sst',\n * async up(ws) {\n * const stage = slug(ws.branch); // per-branch stage\n * const out = await sh('sst', ['deploy', '--stage', stage], ws.dir);\n * return {\n * url: out.url,\n * env: { BASE_URL: out.url },\n * down: () => sh('sst', ['remove', '--stage', stage], ws.dir),\n * };\n * },\n * };\n */\n\nimport type { Workspace } from '../core/types.ts';\n\n/** A running environment for one workspace. Returned by `Environment.up`. */\nexport interface EnvHandle {\n /** Addressable base URL (a preview deployment, or a local server), if any. */\n readonly url?: string;\n /**\n * Variables injected into gate commands (and, later, agent turns) — e.g.\n * `BASE_URL`, `DATABASE_URL`. This is how `commandSucceeds('playwright', …)`\n * reaches the running preview.\n */\n readonly env: Record<string, string>;\n /**\n * Redeploy when the branch advances (a cloud preview that tracks commits).\n * Optional: a local-services env has nothing to sync.\n */\n sync?(commit: string, signal: AbortSignal): Promise<void>;\n /** Tear the environment down. */\n down(signal: AbortSignal): Promise<void>;\n}\n\n/** Brings a workspace's code up so the gate can test the running thing. */\nexport interface Environment {\n readonly name: string;\n up(workspace: Workspace, signal: AbortSignal): Promise<EnvHandle>;\n}\n\n/** Duck-type guard: a ready-made `Environment` rather than something else. */\nexport function isEnvironment(value: unknown): value is Environment {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Environment).name === 'string' &&\n typeof (value as Environment).up === 'function'\n );\n}\n","/**\n * A scripted, offline environment — the reference Environment \"drop-in\", mirror\n * of `MockEngine`. It simulates a deploy (hands back a URL + env vars, counts\n * up/down) with zero network, so the lifecycle binding and gate integration run\n * the exact same code paths in tests as a real sst/Vercel adapter would.\n */\n\nimport type { Workspace } from '../core/types.ts';\nimport type { Environment, EnvHandle } from './environment.ts';\n\nexport interface MockEnvOptions {\n /** The URL to hand back. A function derives it from the workspace (branch). */\n url?: string | ((ws: Workspace) => string);\n /** Extra env vars to inject alongside `BASE_URL`. */\n env?: Record<string, string>;\n onUp?: (ws: Workspace) => void;\n onDown?: () => void;\n}\n\nexport class MockEnvironment implements Environment {\n readonly name = 'mock-env';\n upCount = 0;\n downCount = 0;\n\n constructor(private readonly opts: MockEnvOptions = {}) {}\n\n async up(workspace: Workspace): Promise<EnvHandle> {\n this.upCount += 1;\n const url =\n typeof this.opts.url === 'function'\n ? this.opts.url(workspace)\n : (this.opts.url ?? `http://localhost/${workspace.branch ?? 'main'}`);\n this.opts.onUp?.(workspace);\n const onDown = this.opts.onDown;\n return {\n url,\n env: { BASE_URL: url, ...this.opts.env },\n down: async () => {\n this.downCount += 1;\n onDown?.();\n },\n };\n }\n}\n","/**\n * Public API. A loop-definition file imports from here and `export default`s a\n * `Job` (usually a `loop(...)` or `dag(...)`). The CLI runs that default export.\n *\n * import { loop, agentJob, agentCheck, defineJob } from 'loops';\n * export default defineJob(loop({ ... }));\n */\n\n// Core types\nexport type {\n Job,\n JobMeta,\n JobContext,\n Outcome,\n OutcomeStatus,\n FeedbackActionSeverity,\n FeedbackDecision,\n FeedbackFinding,\n FeedbackSeverity,\n RevisionRequest,\n RevisionRerun,\n GraphPosition,\n LimitPolicy,\n Condition,\n ConditionInput,\n ConditionResult,\n RawPredicate,\n LoopConfig,\n RetryPolicy,\n DagConfig,\n DagNode,\n LoopEvent,\n LogLevel,\n Workspace,\n} from './core/types.ts';\n\n// Primitives\nexport { loop } from './core/loop.ts';\nexport { dag, sequence, parallel } from './core/dag.ts';\nexport { tournament, type TournamentConfig } from './core/tournament.ts';\nexport {\n agentJob,\n fnJob,\n commitJob,\n kickback,\n revisionRequest,\n type AgentJobConfig,\n type CommitJobConfig,\n type GroundConfig,\n} from './core/job.ts';\nexport {\n reviewPanel,\n reviewContext,\n feedbackBlock,\n graphPositionBlock,\n normalizeFeedbackSeverity,\n isRequiredFeedbackSeverity,\n revisionFromOutcome,\n type ReviewPanelConfig,\n type ReviewContextConfig,\n type RevisionRequestInput,\n} from './core/feedback.ts';\n\n// Job introspection — read a loop's shape without running it (powers `loops\n// validate` / `loops describe`, and lets an agent inspect what it authored)\nexport { jobMeta, renderPlan, describeConditions } from './core/describe.ts';\n\n// Agent definitions — job-specific agents (persona in markdown, structure in TS)\nexport {\n agentContract,\n defineAgent,\n defineSkill,\n fromFile,\n resolveSystem,\n type AgentContractSummary,\n type AgentDef,\n type AgentFailureMode,\n type AgentHumanGate,\n type AgentOutputContract,\n type AgentSkillRef,\n type AgentTier,\n type Skill,\n} from './core/agent.ts';\n\n// Git substrate (the convergence ledger)\nexport {\n isRepo,\n currentBranch,\n headSha,\n stageAll,\n hasStagedChanges,\n isDirty,\n commit,\n log,\n push,\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n mergeNoCommit,\n conflictedFiles,\n mergeAbort,\n type CommitRecord,\n type CommitInput,\n type LogQuery,\n type PushOptions,\n type PushResult,\n type WorktreeHandle,\n type MergeResult,\n} from './core/git.ts';\n\n// Merge as synthesis (an agent resolves the conflict + writes a unified \"way\")\nexport {\n mergeSynthesis,\n type MergeSynthesisConfig,\n type MergeSynthesisResult,\n} from './core/merge.ts';\n\n// The Forge — the PR host seam (gh-backed by default), and PR jobs that keep a\n// PR body a faithful synthesis of the branch so the Ledger survives a squash merge\nexport {\n isForge,\n GhForge,\n MockForge,\n buildViewArgs,\n buildCreateArgs,\n buildEditArgs,\n buildMergeArgs,\n buildChecksArgs,\n type Forge,\n type PrRef,\n type PrInput,\n type PrPatch,\n type MergeOptions,\n type ForgeOpts,\n type MockForgeOptions,\n} from './core/forge.ts';\nexport {\n pushJob,\n pullRequestJob,\n mergeJob,\n type PushJobConfig,\n type PullRequestJobConfig,\n type MergeJobConfig,\n} from './core/pr.ts';\n\n// Worktree isolation as a composable Job wrapper (for dynamic dispatch)\nexport { isolated, type IsolatedOptions } from './core/isolated.ts';\n\n// The scratch files — two write-ahead buffers: the handoff (`prompt.md`, the\n// staged commit body) and working memory (`ledger.md`, the auto-captured turn log)\nexport {\n appendPrompt,\n readPrompt,\n resetPrompt,\n promptPath,\n appendLedger,\n readLedger,\n resetLedger,\n ledgerPath,\n ensureIgnored,\n type PromptNote,\n type LedgerEntry,\n} from './core/draft.ts';\n\n// The read side — grounding the next fresh context in the branch-local commit log\nexport {\n groundingText,\n retrieveLedger,\n type GroundOptions,\n type RetrieveOptions,\n} from './core/ground.ts';\n\n// Consolidation — fold the commit log into a consolidated ledger (the coarse memory),\n// and the one-scale-down fold of a run's working log into the commit body\nexport {\n consolidate,\n consolidateJob,\n compactLedger,\n composeCommitBody,\n type ConsolidateOptions,\n type ConsolidateJobConfig,\n type CompactOptions,\n} from './core/consolidate.ts';\nexport {\n toCondition,\n predicate,\n bodyPassed,\n minConfidence,\n commandSucceeds,\n all,\n any,\n not,\n quorum,\n always,\n never,\n forgeChecks,\n agentCheck,\n gateJob,\n type AgentCheckConfig,\n} from './core/condition.ts';\nexport { LoopError, type LoopErrorCode } from './core/errors.ts';\nexport { Budget, type BudgetConfig } from './core/budget.ts';\n\n// Engines (the drop-in seam)\nexport type {\n Engine,\n EngineRef,\n EngineName,\n EngineOptions,\n AgentRequest,\n AgentResult,\n EngineStreamEvent,\n Usage,\n} from './engines/engine.ts';\nexport { isEngine, SUBAGENT_TOOLS } from './engines/engine.ts';\nexport { EngineRegistry, type EngineFactory } from './engines/registry.ts';\nexport { MockEngine, mockVerdict, type MockResponder } from './engines/mock.ts';\n\n// Environments (where the code runs — the third provider axis)\nexport {\n isEnvironment,\n type Environment,\n type EnvHandle,\n} from './env/environment.ts';\nexport { MockEnvironment, type MockEnvOptions } from './env/mock.ts';\n\n// Runtime\nexport {\n run,\n exitCodeFor,\n EXIT_PAUSED,\n type RunOptions,\n type RunResult,\n} from './runtime/runner.ts';\nexport { Stats, type StatsSnapshot } from './core/stats.ts';\n\n// Supervision — observe a supervised run from another process. The registry is\n// files (~/.loops/runs), so these are the read side a `loops list`/`status`/`tail`\n// (or an MCP server) builds on. A run opts in with `RunOptions.supervise`.\nexport {\n listRuns,\n readRunStatus,\n runEventsPath,\n runSemanticRecordsPath,\n runsHome,\n formatEvent,\n type RunStatus,\n type RunLive,\n} from './runtime/supervisor.ts';\nexport {\n semanticRecordsFromEvent,\n type SemanticDecision,\n type SemanticOutcome,\n type SemanticRunRecord,\n} from './runtime/semantic.ts';\n\nimport type { Job } from './core/types.ts';\n\n/** Identity helper that pins the type of a default export to `Job`. */\nexport function defineJob(job: Job): Job {\n return job;\n}\n"]}
1
+ {"version":3,"sources":["../src/core/merge.ts","../src/core/dag.ts","../src/core/tournament.ts","../src/core/pr.ts","../src/core/isolated.ts","../src/engines/mock.ts","../src/env/environment.ts","../src/env/mock.ts","../src/api.ts"],"names":["forkSeq","isolated","outcome","run","slug","pLimit"],"mappings":"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","file":"api.js","sourcesContent":["/**\n * Merge as synthesis (GCC's `MERGE`). A raw `git merge` either applies cleanly or\n * fails on conflict. `mergeSynthesis` does the thing a teammate does: when two\n * lines of work collide, an agent RESOLVES each conflicted file coherently\n * (preserving both intents), and the merge commit body is a SYNTHESIS of what the\n * two branches were each trying to do — not \"merge branch X\".\n *\n * It is text-in/text-out, so it works through any `Engine` (no tool-use needed):\n * the conflicted file content goes in, the resolved content comes back. Light: a\n * call per conflicted file plus one for the synthesis body, and nothing when the\n * merge is already clean. The merge is aborted if resolution throws, so the target\n * is never left half-merged.\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport type { JobContext } from './types.ts';\nimport type { EngineRef } from '../engines/engine.ts';\nimport {\n mergeNoCommit,\n mergeAbort,\n stageAll,\n commit,\n log,\n} from './git.ts';\nimport { LoopError } from './errors.ts';\n\nexport interface MergeSynthesisConfig {\n /** The branch to land into the current workspace. */\n branch: string;\n /** Conventional subject for the merge commit. */\n message?: string;\n engine?: EngineRef;\n model?: string;\n}\n\nexport interface MergeSynthesisResult {\n ok: boolean;\n /** Whether a conflict had to be resolved. */\n conflict: boolean;\n sha?: string;\n}\n\n/** Strip a single wrapping code fence a model sometimes adds around file output. */\nfunction stripFence(s: string): string {\n const m = /^```[^\\n]*\\n([\\s\\S]*?)\\n```$/.exec(s.trim());\n return `${(m ? m[1]! : s).replace(/\\s+$/, '')}\\n`;\n}\n\nfunction firstLine(s: string): string {\n return s.split('\\n').find((l) => l.trim()) ?? '';\n}\n\nexport async function mergeSynthesis(\n ctx: JobContext,\n config: MergeSynthesisConfig,\n): Promise<MergeSynthesisResult> {\n const cwd = ctx.workspace.dir;\n const engine = config.engine ? ctx.resolveEngine(config.engine) : ctx.engine;\n const merge = await mergeNoCommit(cwd, config.branch, { signal: ctx.signal });\n\n try {\n if (!merge.clean) {\n for (const file of merge.conflicted) {\n const conflicted = readFileSync(join(cwd, file), 'utf8');\n const out = await engine.run(\n {\n prompt:\n `Resolve this git merge conflict in \\`${file}\\`. Combine both sides ` +\n `coherently, preserving the intent of each. Output ONLY the fully ` +\n `resolved file content — no conflict markers, no commentary, no code ` +\n `fence.\\n\\n${conflicted}`,\n model: config.model,\n maxTokens: 4000,\n },\n () => {},\n ctx.signal,\n );\n writeFileSync(join(cwd, file), stripFence(out.text));\n }\n await stageAll({ cwd, signal: ctx.signal });\n }\n\n const body = await synthesiseBody(ctx, engine, config);\n const sha = await commit(\n {\n subject: config.message ?? `merge: ${config.branch} (synthesis)`,\n body,\n allowEmpty: true, // a merge commit may have an empty diff after resolution\n },\n { cwd, signal: ctx.signal },\n );\n return { ok: true, conflict: !merge.clean, sha };\n } catch (e) {\n await mergeAbort(cwd, { signal: ctx.signal }).catch(() => {});\n throw LoopError.from(e, { code: 'BODY', path: ctx.path });\n }\n}\n\n/** Compose the merge body from the merged branch's own \"ways\". */\nasync function synthesiseBody(\n ctx: JobContext,\n engine: ReturnType<JobContext['resolveEngine']>,\n config: MergeSynthesisConfig,\n): Promise<string> {\n const ways = await log({\n cwd: ctx.workspace.dir,\n ref: config.branch,\n max: 8,\n signal: ctx.signal,\n });\n const summary = ways\n .map((w) => `- ${w.subject}${w.body ? `: ${firstLine(w.body)}` : ''}`)\n .join('\\n');\n const out = await engine.run(\n {\n prompt:\n `A branch is being merged. Its commits:\\n${summary || '(none)'}\\n\\n` +\n `Write a concise MERGE SYNTHESIS for the commit body: what this line of ` +\n `work accomplished, how it integrates, and any tradeoff reconciled. A few ` +\n `sentences, no preamble.`,\n system: 'You write merge synthesis commit bodies that capture intent.',\n model: config.model,\n maxTokens: 600,\n },\n () => {},\n ctx.signal,\n );\n return out.text.trim();\n}\n","/**\n * The DAG / stages layer. `dag(config)` returns a `Job`, so it nests with\n * `loop()` both ways. Nodes declare `needs` (dependencies); each node waits on\n * its dependencies' promises, then runs under a shared `p-limit` concurrency\n * gate. Cycle/missing-dep detection is delegated to `toposort` and happens\n * before any work runs.\n *\n * Failure policy (ours, not the libs'):\n * - a required node failing blocks its dependents (they don't run);\n * - with `stopOnError` (default) the first required failure stops scheduling\n * anything not already in flight;\n * - `optional` nodes never fail the DAG nor block dependents;\n * - an unmet `when` gate *skips* the node, which counts as green.\n */\n\nimport pLimit from 'p-limit';\nimport toposort from 'toposort';\n\nimport type {\n DagConfig,\n DagNode,\n Job,\n JobContext,\n Outcome,\n Workspace,\n} from './types.ts';\nimport { childContext } from './context.ts';\nimport { toCondition } from './condition.ts';\nimport { setMeta, jobMeta } from './describe.ts';\nimport {\n isRepo,\n stageAll,\n commit,\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n} from './git.ts';\nimport { composeCommitBody } from './consolidate.ts';\nimport { mergeSynthesis } from './merge.ts';\nimport type { EnvHandle } from '../env/environment.ts';\nimport { LoopError } from './errors.ts';\nimport { revisionFromOutcome } from './feedback.ts';\n\n/** Sanitise a name into a git-ref-safe slug. */\nfunction slug(s: string): string {\n return s.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/(^-+|-+$)/g, '') || 'node';\n}\n\nfunction normalize(node: DagNode | Job): DagNode {\n return typeof node === 'function' ? { job: node } : node;\n}\n\nexport function dag(config: DagConfig): Job {\n if (!config.name)\n throw new LoopError({\n code: 'CONFIG',\n message: 'dag() requires a non-empty name',\n });\n const names = Object.keys(config.nodes);\n const nodes = new Map<string, DagNode>(\n names.map((n) => [n, normalize(config.nodes[n]!)]),\n );\n\n // Fail fast on a bad graph, before the Job is ever run.\n const edges: [string, string][] = [];\n for (const [name, node] of nodes) {\n for (const dep of node.needs ?? []) {\n if (!nodes.has(dep)) {\n throw new LoopError({\n code: 'CONFIG',\n message: `dag \"${config.name}\": node \"${name}\" needs unknown node \"${dep}\"`,\n });\n }\n edges.push([dep, name]); // dep must precede name\n }\n }\n let order: string[];\n try {\n order = toposort.array(names, edges);\n } catch (e) {\n throw new LoopError({\n code: 'CONFIG',\n message: `dag \"${config.name}\": dependency cycle detected`,\n cause: e,\n });\n }\n\n const stopOnError = config.stopOnError ?? true;\n const maxKickbacks = config.maxKickbacks ?? 0;\n\n // Static graph relations for routing cross-stage feedback (kickback). All pure\n // functions of the declared `needs` edges, computed once. `dependents` is the\n // forward adjacency (who needs me); a kickback to a target re-runs the target\n // plus everything reachable from it, and the target must be an ancestor.\n const dependents = new Map<string, string[]>(names.map((n) => [n, []]));\n for (const [dep, name] of edges) dependents.get(dep)!.push(name);\n const ancestorsOf = (name: string): Set<string> => {\n const seen = new Set<string>();\n const stack = [...(nodes.get(name)!.needs ?? [])];\n while (stack.length) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n stack.push(...(nodes.get(n)!.needs ?? []));\n }\n return seen;\n };\n const dirtyFrom = (target: string): Set<string> => {\n const seen = new Set<string>([target]);\n const stack = [target];\n while (stack.length) {\n const n = stack.pop()!;\n for (const d of dependents.get(n)!)\n if (!seen.has(d)) {\n seen.add(d);\n stack.push(d);\n }\n }\n return seen;\n };\n const limitN =\n config.concurrency && config.concurrency > 0\n ? config.concurrency\n : names.length || 1;\n\n const job: Job = async (parent: JobContext): Promise<Outcome> => {\n const path = [...parent.path, config.name];\n const depth = parent.depth + 1;\n const ts = () => Date.now();\n parent.emit({ kind: 'dag:start', ts: ts(), path, depth, nodes: names });\n\n const limit = pLimit(limitN);\n const results = new Map<string, Outcome>();\n const memo = new Map<string, Promise<Outcome>>();\n // How many times each node has run (1 on the first pass, +1 per kickback\n // re-run). Stamped onto its dag:node events so records can tell rounds apart.\n const attempts = new Map<string, number>();\n let stopped = false;\n // When a node is kicked back to, the reason rides into its next run as\n // `lastReview` — the same channel a loop's failed `review` uses, so grounding\n // renders it as \"## Next\". Empty in the common (no-kickback) case.\n const pendingKickback = new Map<string, Outcome>();\n\n // Each node runs under its own name in the path, so a nested job (e.g. a\n // loop) is uniquely addressable for stats/logs even across same-named siblings.\n const nodeCtx = (\n name: string,\n workspace?: Workspace,\n environment?: EnvHandle,\n ): JobContext =>\n childContext(parent, {\n depth,\n path: [...path, name],\n workspace,\n environment,\n lastReview: pendingKickback.get(name),\n graph: {\n dag: config.name,\n node: name,\n path: [...path, name],\n needs: nodes.get(name)!.needs ?? [],\n dependents: dependents.get(name) ?? [],\n },\n });\n\n // Land-back merges are serialised: concurrent nodes finishing at once must\n // not race on the parent branch's index/HEAD.\n const mergeLimit = pLimit(1);\n let forkSeq = 0;\n\n /**\n * Run a node, in its own worktree when isolated. On pass the node's work is\n * captured (any uncommitted remainder is committed in the worktree) and\n * landed back into the parent branch (`--no-ff`, serialised). A merge\n * conflict fails the node honestly — loops does not auto-resolve. The\n * worktree is always removed; a cleanly-merged fork branch is deleted.\n */\n const runNodeJob = async (\n name: string,\n node: DagNode,\n ): Promise<Outcome> => {\n const isolated = node.isolate ?? config.isolation === 'worktree';\n if (!isolated) return node.job(nodeCtx(name));\n\n const base = parent.workspace;\n if (!(await isRepo({ cwd: base.dir, signal: parent.signal }))) {\n parent.log(\n `node \"${name}\" requested worktree isolation but ${base.dir} is not a git repo; running in the shared workspace`,\n 'warn',\n );\n return node.job(nodeCtx(name));\n }\n\n const branch = `loops/${slug(config.name)}-${slug(name)}-${(forkSeq += 1)}`;\n const wt = await addWorktree(base.dir, {\n branch,\n base: 'HEAD',\n signal: parent.signal,\n });\n const wtWs: Workspace = { dir: wt.dir, branch };\n // Each team gets its own environment, named after its branch — born with\n // the worktree, torn down with it. A failed start propagates and the node\n // is recorded as failed; the worktree is still cleaned up in `finally`.\n let envHandle: EnvHandle | undefined;\n try {\n if (config.environment)\n envHandle = await config.environment.up(wtWs, parent.signal);\n const outcome = await node.job(nodeCtx(name, wtWs, envHandle));\n if (outcome.status === 'pass') {\n // Capture anything the node left uncommitted, so nothing is stranded\n // in the worktree, then land it back.\n await stageAll({ cwd: wt.dir, signal: parent.signal });\n await commit(\n {\n subject: `chore(${slug(name)}): worktree changes`,\n body: await composeCommitBody(parent, wtWs),\n },\n { cwd: wt.dir, signal: parent.signal },\n );\n const merged = await mergeLimit(() =>\n mergeBranch(base.dir, branch, {\n signal: parent.signal,\n message: `merge ${branch} (node ${name})`,\n }),\n );\n if (!merged.ok) {\n // Conflict. Either fail honestly, or synthesise the merge (an agent\n // resolves it and writes a synthesised body).\n if (config.onConflict !== 'synthesize') {\n return {\n status: 'fail',\n summary: `node \"${name}\" landed with a merge conflict; needs resolution`,\n error: new LoopError({\n code: 'BODY',\n message: `merge conflict landing node \"${name}\"`,\n path: [...path, name],\n }),\n };\n }\n try {\n await mergeLimit(() =>\n mergeSynthesis(parent, {\n branch,\n message: `merge: ${branch} (node ${name}, synthesis)`,\n }),\n );\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n path: [...path, name],\n });\n return {\n status: 'fail',\n summary: `node \"${name}\" merge synthesis failed: ${error.message}`,\n error,\n };\n }\n }\n await deleteBranch(base.dir, branch, { signal: parent.signal }).catch(\n () => {},\n );\n }\n return outcome;\n } finally {\n if (envHandle)\n await envHandle.down(parent.signal).catch(() => {});\n await removeWorktree(base.dir, wt.dir, {\n signal: parent.signal,\n }).catch(() => {});\n }\n };\n\n const record = (\n name: string,\n outcome: Outcome,\n phase: 'done' | 'skip',\n ): Outcome => {\n results.set(name, outcome);\n parent.emit({\n kind: 'dag:node',\n ts: ts(),\n path,\n node: name,\n phase,\n outcome,\n attempt: attempts.get(name),\n });\n if (\n phase === 'done' &&\n outcome.status !== 'pass' &&\n nodes.get(name)!.optional !== true &&\n stopOnError &&\n // A node requesting a kickback is going to be re-run — don't let its\n // (provisional) non-pass abort siblings before the feedback is resolved.\n !(maxKickbacks > 0 && revisionFromOutcome(outcome)?.target)\n ) {\n stopped = true;\n }\n return outcome;\n };\n\n const run = (name: string): Promise<Outcome> => {\n const existing = memo.get(name);\n if (existing) return existing;\n const node = nodes.get(name)!;\n const promise = (async (): Promise<Outcome> => {\n // This node's run count: 1 the first time, +1 each kickback re-run (the\n // memo/results were cleared for the dirty subgraph, so run() re-enters).\n attempts.set(name, (attempts.get(name) ?? 0) + 1);\n // Whole node is guarded: a throw anywhere (dep resolution, `when`, the\n // job) becomes a recorded outcome, so the DAG always reaches `dag:end`.\n try {\n const needs = node.needs ?? [];\n const deps = await Promise.all(needs.map(run));\n // A non-pass dependency blocks this node — a declared `needs` is a real\n // data dependency, so even a failed *optional* producer blocks a\n // consumer (skipped deps come back with status 'pass', so they're green).\n const blocked = needs.some((_, i) => deps[i]!.status !== 'pass');\n if (blocked)\n return record(\n name,\n { status: 'aborted', summary: 'blocked by a failed dependency' },\n 'done',\n );\n if (parent.signal.aborted || stopped)\n return record(\n name,\n { status: 'aborted', summary: 'aborted before start' },\n 'done',\n );\n\n // `when` + the job both run inside the concurrency limit, so an\n // agentCheck gate counts against the cap (it's real backend load).\n const result = await limit(\n async (): Promise<{ outcome: Outcome; phase: 'done' | 'skip' }> => {\n if (parent.signal.aborted || stopped)\n return {\n outcome: {\n status: 'aborted',\n summary: 'aborted before start',\n },\n phase: 'done',\n };\n if (node.when) {\n const r = await toCondition(node.when)(\n nodeCtx(name),\n undefined,\n );\n if (!r.met)\n return {\n outcome: {\n status: 'pass',\n summary: `skipped: ${r.reason}`,\n data: { skipped: true },\n },\n phase: 'skip',\n };\n }\n parent.emit({\n kind: 'dag:node',\n ts: ts(),\n path,\n node: name,\n phase: 'start',\n attempt: attempts.get(name),\n });\n return { outcome: await runNodeJob(name, node), phase: 'done' };\n },\n );\n return record(name, result.outcome, result.phase);\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n phase: 'body',\n path: [...path, name],\n });\n parent.emit({\n kind: 'error',\n ts: ts(),\n path: [...path, name],\n message: error.message,\n code: error.code,\n });\n return record(\n name,\n { status: 'fail', summary: error.message, error },\n 'done',\n );\n }\n })();\n memo.set(name, promise);\n return promise;\n };\n\n await Promise.all(names.map(run));\n\n // Cross-stage feedback: a node may return a `kickback` asking an earlier\n // node to redo work. We re-run the target + its dependents (the cycle lives\n // in execution, the graph stays acyclic), bounded by `maxKickbacks` so it\n // provably terminates. The whole block is inert when `maxKickbacks` is 0, so\n // the default path is exactly the single pass above.\n if (maxKickbacks > 0) {\n let used = 0;\n const rejected = new Set<string>();\n const emitKickback = (\n from: string,\n to: string,\n reason: string,\n accepted: boolean,\n note?: string,\n ) =>\n parent.emit({\n kind: 'dag:kickback',\n ts: ts(),\n path,\n from,\n to,\n reason,\n accepted,\n note,\n });\n for (;;) {\n // Honour kickbacks in topological order, skipping any already rejected.\n const from = order.find(\n (n) => {\n const result = results.get(n);\n return (\n result !== undefined &&\n revisionFromOutcome(result)?.target !== undefined &&\n !rejected.has(n)\n );\n },\n );\n if (!from) break;\n const request = revisionFromOutcome(results.get(from)!)!;\n const to = request.target!;\n const { reason } = request;\n\n // Validate the target: it must exist, be an ancestor, and (if the node\n // declares `acceptsKickbackTo`) be an allowed target. An invalid target\n // is rejected once and never reconsidered unless the node itself re-runs.\n const allow = nodes.get(from)!.acceptsKickbackTo;\n const note = !nodes.has(to)\n ? `unknown node \"${to}\"`\n : !ancestorsOf(from).has(to)\n ? `\"${to}\" is not an ancestor of \"${from}\"`\n : allow && !allow.includes(to)\n ? `\"${from}\" does not accept kickback to \"${to}\"`\n : undefined;\n if (note) {\n rejected.add(from);\n emitKickback(from, to, reason, false, note);\n continue;\n }\n\n if (used >= maxKickbacks) {\n // Budget spent. Reject and stop — the unresolved kickback leaves the\n // kicking node's own outcome to stand (a fail keeps the dag honest).\n emitKickback(\n from,\n to,\n reason,\n false,\n `kickback budget (${maxKickbacks}) exhausted`,\n );\n break;\n }\n\n used += 1;\n emitKickback(from, to, reason, true);\n const dirty = dirtyFrom(to);\n for (const d of dirty) {\n memo.delete(d); // force re-run\n results.delete(d);\n rejected.delete(d); // a re-run earns a fresh verdict\n }\n pendingKickback.set(to, {\n status: 'fail',\n summary: `Kicked back from \"${from}\": ${reason}`,\n revision: { ...request, source: request.source ?? from },\n });\n stopped = false; // a prior stopOnError must not block the re-run\n await Promise.all(names.map(run));\n }\n }\n\n const requiredFailed = names.filter(\n (n) =>\n results.get(n)?.status === 'fail' && nodes.get(n)!.optional !== true,\n );\n const requiredAborted = names.filter(\n (n) =>\n results.get(n)?.status === 'aborted' && nodes.get(n)!.optional !== true,\n );\n const data = Object.fromEntries(results);\n let outcome: Outcome;\n if (parent.signal.aborted) {\n // a genuine user/signal cancellation\n outcome = {\n status: 'aborted',\n summary: `dag \"${config.name}\" aborted`,\n data,\n };\n } else if (requiredFailed.length > 0 || requiredAborted.length > 0) {\n // a real failure (direct, or a required node left undone by an upstream\n // failure) is a fail (exit 1), distinct from a cancellation (exit 130).\n outcome = {\n status: 'fail',\n summary: `dag \"${config.name}\": ${requiredFailed.length + requiredAborted.length} required node(s) did not complete`,\n data,\n };\n } else {\n outcome = {\n status: 'pass',\n summary: `dag \"${config.name}\": all ${names.length} node(s) green`,\n data,\n };\n }\n parent.emit({ kind: 'dag:end', ts: ts(), path, outcome });\n return outcome;\n };\n\n return setMeta(job, {\n kind: 'dag',\n name: config.name,\n nodes: Object.entries(config.nodes).map(([name, v]) => {\n const node = typeof v === 'function' ? undefined : v;\n const nodeJob = node ? node.job : (v as Job);\n return {\n name,\n needs: node?.needs ?? [],\n isolate: node?.isolate ?? false,\n job: jobMeta(nodeJob),\n };\n }),\n });\n}\n\n/** Run jobs strictly in order; stop at the first non-pass. Sugar over `dag`. */\nexport function sequence(name: string, ...jobs: Job[]): Job {\n const nodes: Record<string, DagNode> = {};\n jobs.forEach((job, i) => {\n nodes[`step-${i}`] = { job, needs: i > 0 ? [`step-${i - 1}`] : [] };\n });\n return dag({ name, nodes, concurrency: 1, stopOnError: true });\n}\n\n/** Run jobs concurrently (optionally capped); all run regardless of failures. */\nexport function parallel(\n name: string,\n jobs: Record<string, Job> | Job[],\n concurrency?: number,\n): Job {\n const record = Array.isArray(jobs)\n ? Object.fromEntries(jobs.map((j, i) => [`task-${i}`, j] as const))\n : jobs;\n return dag({ name, nodes: record, concurrency, stopOnError: false });\n}\n","/**\n * Tournament — branch-and-select (GCC's `BRANCH` + pick-the-winner). Where a DAG\n * fans out DISJOINT work and lands all of it, a tournament explores ALTERNATIVE\n * approaches to the SAME task: run N candidates, each in its own isolated\n * worktree, judge them, land only the winner and discard the rest.\n *\n * It is a thin composition over the worktree primitives — no new machinery. Only\n * one branch is ever merged (the winner, off an unchanged HEAD), so there is no\n * conflict to resolve. Small on purpose.\n */\n\nimport pLimit from 'p-limit';\n\nimport type { Job, JobContext, Outcome, Workspace } from './types.ts';\nimport { childContext } from './context.ts';\nimport {\n isRepo,\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n stageAll,\n commit,\n} from './git.ts';\nimport { composeCommitBody } from './consolidate.ts';\nimport { LoopError } from './errors.ts';\n\nfunction slug(s: string): string {\n return s.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/(^-+|-+$)/g, '') || 'x';\n}\n\nexport interface TournamentConfig {\n name: string;\n /** Candidates to run. */\n n: number;\n /** Build the candidate job for attempt `i` (0-based) — same task, varied angle. */\n candidate: (i: number) => Job;\n /**\n * Score a finished candidate (higher wins). Run against the candidate's own\n * context, so it can read the candidate's workspace. The highest-scoring\n * passing candidate lands back; ties break to the earliest.\n */\n judge: (outcome: Outcome, ctx: JobContext) => number | Promise<number>;\n /** Max candidates running at once. Default `n`. */\n concurrency?: number;\n}\n\ninterface Attempt {\n i: number;\n branch: string;\n dir: string;\n outcome: Outcome;\n score: number;\n}\n\nexport function tournament(config: TournamentConfig): Job {\n if (!config.name)\n throw new LoopError({\n code: 'CONFIG',\n message: 'tournament() requires a non-empty name',\n });\n if (config.n < 1)\n throw new LoopError({ code: 'CONFIG', message: 'tournament() needs n >= 1' });\n\n return async (parent: JobContext): Promise<Outcome> => {\n const path = [...parent.path, config.name];\n const base = parent.workspace;\n parent.emit({\n kind: 'job:start',\n ts: Date.now(),\n path,\n label: config.name,\n });\n\n if (!(await isRepo({ cwd: base.dir, signal: parent.signal }))) {\n const error = new LoopError({\n code: 'CONFIG',\n message: `tournament \"${config.name}\" requires a git repository (cwd: ${base.dir})`,\n });\n return { status: 'fail', summary: error.message, error };\n }\n\n const limit = pLimit(config.concurrency ?? config.n);\n const attempts = await Promise.all(\n Array.from({ length: config.n }, (_, i) =>\n limit(async (): Promise<Attempt> => {\n const branch = `loops/${slug(config.name)}-cand-${i}`;\n const wt = await addWorktree(base.dir, {\n branch,\n base: 'HEAD',\n signal: parent.signal,\n });\n const ws: Workspace = { dir: wt.dir, branch };\n try {\n const ctx = childContext(parent, {\n depth: parent.depth + 1,\n path: [...path, `#${i}`],\n workspace: ws,\n });\n const outcome = await config.candidate(i)(ctx);\n // Capture the candidate's work onto its branch so the winner can land.\n await stageAll({ cwd: wt.dir, signal: parent.signal });\n await commit(\n {\n subject: `${config.name}: candidate ${i}`,\n body: await composeCommitBody(ctx, ws),\n },\n { cwd: wt.dir, signal: parent.signal },\n );\n const score =\n outcome.status === 'pass' ? await config.judge(outcome, ctx) : -1;\n parent.log(`${config.name} candidate ${i}: score ${score}`);\n return { i, branch, dir: wt.dir, outcome, score };\n } catch (e) {\n const error = LoopError.from(e, { code: 'BODY', path });\n return {\n i,\n branch,\n dir: wt.dir,\n outcome: { status: 'fail', summary: error.message, error },\n score: -1,\n };\n }\n }),\n ),\n );\n\n // Winner: highest score among passing candidates; ties to the earliest.\n const winner = [...attempts]\n .filter((a) => a.outcome.status === 'pass' && a.score >= 0)\n .sort((a, b) => b.score - a.score || a.i - b.i)[0];\n\n let landed = false;\n if (winner) {\n const merged = await mergeBranch(base.dir, winner.branch, {\n signal: parent.signal,\n message: `${config.name}: land candidate ${winner.i} (score ${winner.score})`,\n });\n landed = merged.ok;\n }\n\n // Tear down every worktree; delete loser branches and the merged winner.\n for (const a of attempts) {\n await removeWorktree(base.dir, a.dir, { signal: parent.signal }).catch(\n () => {},\n );\n if (a !== winner || landed)\n await deleteBranch(base.dir, a.branch, {\n signal: parent.signal,\n }).catch(() => {});\n }\n\n const outcome: Outcome = winner\n ? {\n status: landed ? 'pass' : 'fail',\n confidence: winner.outcome.confidence,\n summary: landed\n ? `tournament \"${config.name}\": landed candidate ${winner.i} (score ${winner.score}) of ${config.n}`\n : `tournament \"${config.name}\": winner ${winner.i} failed to land`,\n data: {\n winner: winner.i,\n score: winner.score,\n scores: attempts.map((a) => ({ i: a.i, score: a.score })),\n },\n }\n : {\n status: 'fail',\n summary: `tournament \"${config.name}\": no candidate passed`,\n data: { scores: attempts.map((a) => ({ i: a.i, score: a.score })) },\n };\n parent.emit({ kind: 'job:end', ts: Date.now(), path, label: config.name, outcome });\n return outcome;\n };\n}\n","/**\n * Pull-request jobs — how a converged branch becomes a PR whose body stays a\n * faithful synthesis of the work, so the commit-log memory survives a squash merge.\n *\n * The squash-merge problem: a branch carries N milestone commits, each with a rich\n * structured \"way\" (the Ledger). A squash merge collapses them into one commit whose\n * body GitHub defaults to a list of subject lines — the reasoning is lost from the\n * base branch's history. The fix is small because loops already folds many commit\n * bodies into one: `pullRequestJob` sets the PR body to `consolidate(since: base)` —\n * the same decision-preserving fold, scoped to this branch — and keeps it current.\n * `mergeJob` can then squash with that synthesis as the commit body directly.\n *\n * Engine-agnostic and host-agnostic: the host is the injectable `Forge` seam\n * (default `GhForge`), so these jobs run offline against a `MockForge` in tests.\n */\n\nimport type { Job, JobContext, Outcome, ConditionInput } from './types.ts';\nimport { LoopError } from './errors.ts';\nimport { push } from './git.ts';\nimport { consolidate } from './consolidate.ts';\nimport { GhForge, type Forge, type PrRef } from './forge.ts';\nimport { toCondition } from './condition.ts';\n\n/** Resolve the host: the run's `forge`, else the GitHub CLI adapter. */\nfunction resolveForge(ctx: JobContext): Forge {\n return ctx.forge ?? new GhForge();\n}\n\ntype Derive<T> =\n | T\n | ((ctx: JobContext, last: Outcome | undefined) => T | Promise<T>);\n\nasync function derive<T>(\n value: Derive<T> | undefined,\n ctx: JobContext,\n last: Outcome | undefined,\n): Promise<T | undefined> {\n if (value === undefined) return undefined;\n return typeof value === 'function'\n ? await (value as (c: JobContext, l: Outcome | undefined) => T | Promise<T>)(\n ctx,\n last,\n )\n : value;\n}\n\nexport interface PushJobConfig {\n label?: string;\n /** Remote to push to. Default `origin`. */\n remote?: string;\n /** Branch to push. Default the workspace branch. */\n branch?: string;\n /** Set upstream tracking. Default true. */\n setUpstream?: boolean;\n /** Force-with-lease. Default false. */\n force?: boolean;\n}\n\n/** Push the work branch to its remote. Idempotent; a rejected push fails honestly. */\nexport function pushJob(config: PushJobConfig = {}): Job {\n return async (ctx) => {\n const label = config.label ?? 'push';\n const path = [...ctx.path];\n ctx.emit({ kind: 'job:start', ts: Date.now(), path, label });\n const branch = config.branch ?? ctx.workspace.branch;\n const res = await push({\n cwd: ctx.workspace.dir,\n signal: ctx.signal,\n remote: config.remote,\n branch,\n setUpstream: config.setUpstream,\n force: config.force,\n });\n const outcome: Outcome = res.ok\n ? { status: 'pass', summary: `pushed ${branch ?? 'HEAD'}` }\n : {\n status: 'fail',\n summary: `push failed: ${res.output}`,\n error: new LoopError({ code: 'BODY', message: res.output }),\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n };\n}\n\nexport interface PullRequestJobConfig {\n label?: string;\n /** PR title, or a function of context. Default: the converged outcome summary. */\n title?: Derive<string>;\n /** Base branch to merge into, and the `since` bound for the body fold. Default `main`. */\n base?: string;\n /** Push the branch first (idempotent). Default true; pass a config to tune. */\n push?: boolean | PushJobConfig;\n /** Open as a draft when first created. */\n draft?: boolean;\n /** Model for the body consolidation call. */\n model?: string;\n /** Max milestones to fold into the body. Default 50. */\n max?: number;\n /** Override the synthesized body (else: consolidate the branch's commit bodies). */\n body?: Derive<string>;\n}\n\n/**\n * Raise the PR, or update it if it already exists, with a body synthesized from the\n * branch's commit bodies. Idempotent create-or-update: run it after each milestone\n * (or at convergence) and the PR description stays current — that is what keeps the\n * eventual squash body honest. Returns the `PrRef` in `outcome.data.pr`.\n */\nexport function pullRequestJob(config: PullRequestJobConfig = {}): Job {\n return async (ctx) => {\n const label = config.label ?? 'pull-request';\n const path = [...ctx.path];\n ctx.emit({ kind: 'job:start', ts: Date.now(), path, label });\n try {\n const branch = ctx.workspace.branch;\n if (!branch)\n throw new LoopError({\n code: 'CONFIG',\n message: `pullRequestJob \"${label}\" needs a branch checked out (detached HEAD or non-repo)`,\n });\n const base = config.base ?? 'main';\n const last = ctx.lastOutcome;\n\n if (config.push !== false) {\n const res = await push({\n cwd: ctx.workspace.dir,\n signal: ctx.signal,\n branch,\n ...(typeof config.push === 'object' ? config.push : {}),\n });\n if (!res.ok)\n throw new LoopError({\n code: 'BODY',\n message: `push failed: ${res.output}`,\n });\n }\n\n const body =\n (await derive(config.body, ctx, last)) ??\n (await consolidate(ctx, {\n since: base,\n max: config.max ?? 50,\n model: config.model,\n }));\n const title = (await derive(config.title, ctx, last)) ?? last?.summary ?? branch;\n\n const forge = resolveForge(ctx);\n const fopts = { cwd: ctx.workspace.dir, signal: ctx.signal };\n const existing = await forge.viewPr(branch, fopts);\n let pr: PrRef;\n if (existing) {\n await forge.editPr(existing, { body }, fopts);\n pr = existing;\n } else {\n pr = await forge.createPr(\n { title, body, base, branch, draft: config.draft },\n fopts,\n );\n }\n const outcome: Outcome = {\n status: 'pass',\n summary: `${existing ? 'updated' : 'opened'} PR #${pr.number}`,\n data: { pr },\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n phase: 'body',\n path: ctx.path,\n });\n ctx.emit({\n kind: 'error',\n ts: Date.now(),\n path,\n message: error.message,\n code: error.code,\n });\n const outcome: Outcome = { status: 'fail', summary: error.message, error };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n }\n };\n}\n\nexport interface MergeJobConfig {\n label?: string;\n /** Base branch — the `since` bound for re-synthesizing the squash body. Default `main`. */\n base?: string;\n /** Squash merge (default true) — the whole reason this exists. */\n squash?: boolean;\n /**\n * Hand the merge to GitHub auto-merge (`gh pr merge --auto`): it lands once the\n * required checks pass. The recommended \"merge when CI is green\" path — non-blocking.\n */\n auto?: boolean;\n /** Delete the head branch after merge. */\n deleteBranch?: boolean;\n /** Squash commit subject. */\n subject?: Derive<string>;\n /** Squash commit body. Default: re-consolidate the branch (the up-to-date synthesis). */\n body?: Derive<string>;\n model?: string;\n max?: number;\n /**\n * A gate that must hold before loops issues the merge — e.g. `forgeChecks()` for a\n * synchronous \"CI is green\" check, or any `Condition`. Unmet → the job fails without\n * merging. (For the non-blocking path, prefer `auto: true` and let GitHub gate.)\n */\n when?: ConditionInput;\n}\n\n/**\n * Squash-merge the branch's PR with a body synthesized from its commit bodies — so the\n * one commit that lands on the base branch carries the whole \"way\", not a list of\n * subjects. Opt-in (loops performing an outward merge is high-stakes): gate it with\n * `auto: true` (GitHub merges when checks pass) and/or a `when` condition.\n */\nexport function mergeJob(config: MergeJobConfig = {}): Job {\n return async (ctx) => {\n const label = config.label ?? 'merge';\n const path = [...ctx.path];\n ctx.emit({ kind: 'job:start', ts: Date.now(), path, label });\n try {\n const branch = ctx.workspace.branch;\n if (!branch)\n throw new LoopError({\n code: 'CONFIG',\n message: `mergeJob \"${label}\" needs a branch checked out`,\n });\n const forge = resolveForge(ctx);\n const fopts = { cwd: ctx.workspace.dir, signal: ctx.signal };\n const pr = await forge.viewPr(branch, fopts);\n if (!pr)\n throw new LoopError({\n code: 'CONFIG',\n message: `mergeJob \"${label}\": no open PR for branch \"${branch}\" — run pullRequestJob first`,\n });\n\n if (config.when) {\n const r = await toCondition(config.when)(ctx, ctx.lastOutcome);\n if (!r.met) {\n const outcome: Outcome = {\n status: 'fail',\n summary: `merge gate not met: ${r.reason}`,\n data: { pr },\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n }\n }\n\n const last = ctx.lastOutcome;\n const base = config.base ?? 'main';\n // Re-synthesize at merge time so the squash body reflects the final branch.\n const body =\n (await derive(config.body, ctx, last)) ??\n (await consolidate(ctx, {\n since: base,\n max: config.max ?? 50,\n model: config.model,\n }));\n const subject = await derive(config.subject, ctx, last);\n\n await forge.mergePr(pr, {\n ...fopts,\n squash: config.squash,\n auto: config.auto,\n subject,\n body,\n deleteBranch: config.deleteBranch,\n });\n const outcome: Outcome = {\n status: 'pass',\n summary: `${config.auto ? 'enqueued' : 'merged'} PR #${pr.number}`,\n data: { pr },\n };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n } catch (e) {\n const error = LoopError.from(e, {\n code: 'BODY',\n phase: 'body',\n path: ctx.path,\n });\n ctx.emit({\n kind: 'error',\n ts: Date.now(),\n path,\n message: error.message,\n code: error.code,\n });\n const outcome: Outcome = { status: 'fail', summary: error.message, error };\n ctx.emit({ kind: 'job:end', ts: Date.now(), path, label, outcome });\n return outcome;\n }\n };\n}\n","/**\n * `isolated(job)` — run any Job in its own git worktree on a fork branch, and land\n * its work back into the parent branch on pass. The concurrency boundary as a Job\n * WRAPPER, not a node type.\n *\n * dag nodes can already fork a worktree (`isolation: 'worktree'`), but that only\n * works for predeclared nodes. A Tend loop dispatches DYNAMICALLY — it discovers\n * each ticket at runtime and routes it to the right shape of sub-loop — and each\n * dispatch wants its own isolated worktree so parallel tickets never collide on\n * files or the index. `isolated()` makes that composable: wrap the dispatched Job.\n *\n * On pass: any uncommitted remainder is committed in the worktree, then the fork\n * branch merges back (`--no-ff`). Land-back merges are serialised across all\n * `isolated()` jobs in the process, so concurrent dispatch cannot race the parent\n * index/HEAD. A conflict fails honestly, or is synthesised when asked. The worktree\n * is always removed; a cleanly-merged fork branch is deleted. A non-repo workspace\n * degrades to running in place (a warning, no isolation).\n *\n * NOTE: dag's own runNodeJob holds parallel worktree/land-back logic (plus per-team\n * environments). The two should be unified — dag delegating to `isolated()` — once\n * `isolated()` grows environment support; until then the land-back logic lives in\n * both deliberately, to avoid destabilising the dag path.\n */\n\nimport pLimit from 'p-limit';\n\nimport type { Job, Workspace } from './types.ts';\nimport { childContext } from './context.ts';\nimport { LoopError } from './errors.ts';\nimport {\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n stageAll,\n commit,\n isRepo,\n} from './git.ts';\nimport { mergeSynthesis } from './merge.ts';\nimport { composeCommitBody } from './consolidate.ts';\n\nconst slug = (s: string) =>\n s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'job';\n\n/** Serialise land-back merges process-wide so concurrent dispatch can't race. */\nconst mergeLock = pLimit(1);\nlet forkSeq = 0;\n\nexport interface IsolatedOptions {\n /** Label for the fork branch and the child path. Default 'isolated'. */\n label?: string;\n /** On a land-back conflict: 'fail' (default) or 'synthesize'. */\n onConflict?: 'fail' | 'synthesize';\n}\n\n/** Wrap a Job so it runs in an isolated worktree and lands back on pass. */\nexport function isolated(job: Job, opts: IsolatedOptions = {}): Job {\n const label = opts.label ?? 'isolated';\n return async (parent) => {\n const base = parent.workspace;\n if (!(await isRepo({ cwd: base.dir, signal: parent.signal }))) {\n parent.log(\n `isolated(\"${label}\") requested a worktree but ${base.dir} is not a git repo; running in the shared workspace`,\n 'warn',\n );\n return job(parent);\n }\n\n const branch = `loops/${slug(label)}-${(forkSeq += 1)}`;\n const wt = await addWorktree(base.dir, {\n branch,\n base: 'HEAD',\n signal: parent.signal,\n });\n const wtWs: Workspace = { dir: wt.dir, branch };\n try {\n const ctx = childContext(parent, {\n workspace: wtWs,\n depth: parent.depth + 1,\n path: [...parent.path, label],\n });\n const outcome = await job(ctx);\n if (outcome.status === 'pass') {\n // Capture anything the job left uncommitted, then land it back.\n await stageAll({ cwd: wt.dir, signal: parent.signal });\n await commit(\n {\n subject: `chore(${slug(label)}): worktree changes`,\n body: await composeCommitBody(ctx, wtWs),\n },\n { cwd: wt.dir, signal: parent.signal },\n );\n const merged = await mergeLock(() =>\n mergeBranch(base.dir, branch, {\n signal: parent.signal,\n message: `merge ${branch}`,\n }),\n );\n if (!merged.ok) {\n if (opts.onConflict !== 'synthesize') {\n return {\n status: 'fail',\n summary: `isolated(\"${label}\") landed with a merge conflict; needs resolution`,\n error: new LoopError({\n code: 'BODY',\n message: `merge conflict landing isolated(\"${label}\")`,\n path: [...parent.path, label],\n }),\n };\n }\n try {\n await mergeLock(() =>\n mergeSynthesis(parent, {\n branch,\n message: `merge: ${branch} (synthesis)`,\n }),\n );\n } catch (e) {\n const error = LoopError.from(e, { code: 'BODY', path: [...parent.path, label] });\n return {\n status: 'fail',\n summary: `isolated(\"${label}\") merge synthesis failed: ${error.message}`,\n error,\n };\n }\n }\n await deleteBranch(base.dir, branch, { signal: parent.signal }).catch(() => {});\n }\n return outcome;\n } finally {\n await removeWorktree(base.dir, wt.dir, { signal: parent.signal }).catch(() => {});\n }\n };\n}\n","/**\n * A scripted, offline engine — the reference \"drop-in\". It implements the same\n * `Engine` interface as the real backends, so tests and examples run the exact\n * same loop/dag/condition code paths with zero network. Writing one of these is\n * all it takes to add a provider: implement `run`, register a name.\n */\n\nimport type {\n AgentRequest,\n AgentResult,\n Engine,\n EngineEventSink,\n Usage,\n} from './engine.ts';\n\nexport type MockResponder = (\n req: AgentRequest,\n) => string | { text: string; usage?: Usage; model?: string };\n\nexport class MockEngine implements Engine {\n readonly name = 'mock';\n constructor(private readonly responder: MockResponder) {}\n\n async run(\n req: AgentRequest,\n onEvent: EngineEventSink,\n signal: AbortSignal,\n ): Promise<AgentResult> {\n if (signal.aborted) {\n throw Object.assign(new Error('aborted'), { name: 'AbortError' });\n }\n const raw = this.responder(req);\n const out = typeof raw === 'string' ? { text: raw } : raw;\n const model = out.model ?? 'mock';\n const usage = out.usage ?? { inputTokens: 10, outputTokens: 5 };\n if (out.text) onEvent({ type: 'text', delta: out.text });\n onEvent({ type: 'usage', usage, model });\n return { text: out.text, usage, model, stopReason: 'end_turn' };\n }\n}\n\n/** Convenience: always reply with a verdict JSON (handy for validator tests). */\nexport function mockVerdict(\n verdict: 'yes' | 'no',\n confidence: number,\n reason = 'mock',\n): MockEngine {\n return new MockEngine(() => JSON.stringify({ verdict, confidence, reason }));\n}\n","/**\n * The Environment provider — the third axis, after Engine (where the agent\n * thinks) and Workspace (where the code lives). Environment is where the code\n * RUNS: local services, or a per-branch cloud preview. It is what lets the gate\n * be fully honest — \"done\" can mean \"the e2e suite passes against the running\n * preview\", not just \"unit tests pass against static files on disk\".\n *\n * Like `Engine`, this is only an interface. loops owns the seam and the\n * lifecycle binding; the actual adapter (sst, Vercel, Docker, …) is\n * provider-specific and lives in the CONSUMER's loop definition, next to the\n * deploy config it wraps. loops never takes a dependency on a deploy tool. Bring\n * your own in a few lines: implement `up`, return a handle.\n *\n * const sstEnv: Environment = {\n * name: 'sst',\n * async up(ws) {\n * const stage = slug(ws.branch); // per-branch stage\n * const out = await sh('sst', ['deploy', '--stage', stage], ws.dir);\n * return {\n * url: out.url,\n * env: { BASE_URL: out.url },\n * down: () => sh('sst', ['remove', '--stage', stage], ws.dir),\n * };\n * },\n * };\n */\n\nimport type { Workspace } from '../core/types.ts';\n\n/** A running environment for one workspace. Returned by `Environment.up`. */\nexport interface EnvHandle {\n /** Addressable base URL (a preview deployment, or a local server), if any. */\n readonly url?: string;\n /**\n * Variables injected into gate commands (and, later, agent turns) — e.g.\n * `BASE_URL`, `DATABASE_URL`. This is how `commandSucceeds('playwright', …)`\n * reaches the running preview.\n */\n readonly env: Record<string, string>;\n /**\n * Redeploy when the branch advances (a cloud preview that tracks commits).\n * Optional: a local-services env has nothing to sync.\n */\n sync?(commit: string, signal: AbortSignal): Promise<void>;\n /** Tear the environment down. */\n down(signal: AbortSignal): Promise<void>;\n}\n\n/** Brings a workspace's code up so the gate can test the running thing. */\nexport interface Environment {\n readonly name: string;\n up(workspace: Workspace, signal: AbortSignal): Promise<EnvHandle>;\n}\n\n/** Duck-type guard: a ready-made `Environment` rather than something else. */\nexport function isEnvironment(value: unknown): value is Environment {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Environment).name === 'string' &&\n typeof (value as Environment).up === 'function'\n );\n}\n","/**\n * A scripted, offline environment — the reference Environment \"drop-in\", mirror\n * of `MockEngine`. It simulates a deploy (hands back a URL + env vars, counts\n * up/down) with zero network, so the lifecycle binding and gate integration run\n * the exact same code paths in tests as a real sst/Vercel adapter would.\n */\n\nimport type { Workspace } from '../core/types.ts';\nimport type { Environment, EnvHandle } from './environment.ts';\n\nexport interface MockEnvOptions {\n /** The URL to hand back. A function derives it from the workspace (branch). */\n url?: string | ((ws: Workspace) => string);\n /** Extra env vars to inject alongside `BASE_URL`. */\n env?: Record<string, string>;\n onUp?: (ws: Workspace) => void;\n onDown?: () => void;\n}\n\nexport class MockEnvironment implements Environment {\n readonly name = 'mock-env';\n upCount = 0;\n downCount = 0;\n\n constructor(private readonly opts: MockEnvOptions = {}) {}\n\n async up(workspace: Workspace): Promise<EnvHandle> {\n this.upCount += 1;\n const url =\n typeof this.opts.url === 'function'\n ? this.opts.url(workspace)\n : (this.opts.url ?? `http://localhost/${workspace.branch ?? 'main'}`);\n this.opts.onUp?.(workspace);\n const onDown = this.opts.onDown;\n return {\n url,\n env: { BASE_URL: url, ...this.opts.env },\n down: async () => {\n this.downCount += 1;\n onDown?.();\n },\n };\n }\n}\n","/**\n * Public API. A loop-definition file imports from here and `export default`s a\n * `Job` (usually a `loop(...)` or `dag(...)`). The CLI runs that default export.\n *\n * import { loop, agentJob, agentCheck, defineJob } from 'loops';\n * export default defineJob(loop({ ... }));\n */\n\n// Core types\nexport type {\n Job,\n JobMeta,\n JobContext,\n Outcome,\n OutcomeStatus,\n FeedbackActionSeverity,\n FeedbackDecision,\n FeedbackFinding,\n FeedbackSeverity,\n RevisionRequest,\n RevisionRerun,\n GraphPosition,\n LimitPolicy,\n Condition,\n ConditionInput,\n ConditionResult,\n RawPredicate,\n LoopConfig,\n RetryPolicy,\n DagConfig,\n DagNode,\n LoopEvent,\n LogLevel,\n Workspace,\n} from './core/types.ts';\n\n// Primitives\nexport { loop } from './core/loop.ts';\nexport { dag, sequence, parallel } from './core/dag.ts';\nexport { tournament, type TournamentConfig } from './core/tournament.ts';\nexport {\n agentJob,\n fnJob,\n commitJob,\n kickback,\n revisionRequest,\n type AgentJobConfig,\n type CommitJobConfig,\n type GroundConfig,\n} from './core/job.ts';\nexport {\n reviewPanel,\n reviewContext,\n feedbackBlock,\n graphPositionBlock,\n normalizeFeedbackSeverity,\n isRequiredFeedbackSeverity,\n revisionFromOutcome,\n type ReviewPanelConfig,\n type ReviewContextConfig,\n type RevisionRequestInput,\n} from './core/feedback.ts';\n\n// Job introspection — read a loop's shape without running it (powers `loops\n// validate` / `loops describe`, and lets an agent inspect what it authored)\nexport { jobMeta, renderPlan, describeConditions } from './core/describe.ts';\n\n// Agent definitions — job-specific agents (persona in markdown, structure in TS)\nexport {\n agentContract,\n defineAgent,\n defineSkill,\n fromFile,\n resolveSystem,\n type AgentContractSummary,\n type AgentDef,\n type AgentFailureMode,\n type AgentHumanGate,\n type AgentOutputContract,\n type AgentSkillRef,\n type AgentTier,\n type Skill,\n} from './core/agent.ts';\n\n// Git substrate (the convergence ledger)\nexport {\n isRepo,\n currentBranch,\n headSha,\n stageAll,\n hasStagedChanges,\n isDirty,\n commit,\n log,\n push,\n addWorktree,\n removeWorktree,\n deleteBranch,\n mergeBranch,\n mergeNoCommit,\n conflictedFiles,\n mergeAbort,\n workspaceFingerprint,\n type CommitRecord,\n type CommitInput,\n type LogQuery,\n type PushOptions,\n type PushResult,\n type WorktreeHandle,\n type MergeResult,\n} from './core/git.ts';\n\n// Merge as synthesis (an agent resolves the conflict + writes a unified \"way\")\nexport {\n mergeSynthesis,\n type MergeSynthesisConfig,\n type MergeSynthesisResult,\n} from './core/merge.ts';\n\n// The Forge — the PR host seam (gh-backed by default), and PR jobs that keep a\n// PR body a faithful synthesis of the branch so the Ledger survives a squash merge\nexport {\n isForge,\n GhForge,\n MockForge,\n buildViewArgs,\n buildCreateArgs,\n buildEditArgs,\n buildMergeArgs,\n buildChecksArgs,\n type Forge,\n type PrRef,\n type PrInput,\n type PrPatch,\n type MergeOptions,\n type ForgeOpts,\n type MockForgeOptions,\n} from './core/forge.ts';\nexport {\n pushJob,\n pullRequestJob,\n mergeJob,\n type PushJobConfig,\n type PullRequestJobConfig,\n type MergeJobConfig,\n} from './core/pr.ts';\n\n// Worktree isolation as a composable Job wrapper (for dynamic dispatch)\nexport { isolated, type IsolatedOptions } from './core/isolated.ts';\n\n// The scratch files — two write-ahead buffers: the handoff (`prompt.md`, the\n// staged commit body) and working memory (`ledger.md`, the auto-captured turn log)\nexport {\n appendPrompt,\n readPrompt,\n resetPrompt,\n promptPath,\n appendLedger,\n readLedger,\n resetLedger,\n ledgerPath,\n ensureIgnored,\n type PromptNote,\n type LedgerEntry,\n} from './core/draft.ts';\n\n// The read side — grounding the next fresh context in the branch-local commit log\nexport {\n groundingText,\n retrieveLedger,\n type GroundOptions,\n type RetrieveOptions,\n} from './core/ground.ts';\n\n// Consolidation — fold the commit log into a consolidated ledger (the coarse memory),\n// and the one-scale-down fold of a run's working log into the commit body\nexport {\n consolidate,\n consolidateJob,\n compactLedger,\n composeCommitBody,\n type ConsolidateOptions,\n type ConsolidateJobConfig,\n type CompactOptions,\n} from './core/consolidate.ts';\nexport {\n toCondition,\n predicate,\n bodyPassed,\n minConfidence,\n commandSucceeds,\n all,\n any,\n not,\n quorum,\n always,\n never,\n forgeChecks,\n agentCheck,\n gateJob,\n type AgentCheckConfig,\n} from './core/condition.ts';\n// No-progress (stall) detection — the third hard stop, alongside `max` and\n// `budget`. Configured per-loop via `LoopConfig.noProgress`; exported so a\n// custom harness can drive the same tracker.\nexport {\n ProgressTracker,\n resolveNoProgress,\n type NoProgressConfig,\n type NoProgressInput,\n type ProgressSample,\n type StallReport,\n} from './core/progress.ts';\nexport { LoopError, type LoopErrorCode } from './core/errors.ts';\nexport { Budget, type BudgetConfig } from './core/budget.ts';\n\n// Engines (the drop-in seam)\nexport type {\n Engine,\n EngineRef,\n EngineName,\n EngineOptions,\n AgentRequest,\n AgentResult,\n EngineStreamEvent,\n Usage,\n} from './engines/engine.ts';\nexport { isEngine, SUBAGENT_TOOLS } from './engines/engine.ts';\nexport { EngineRegistry, type EngineFactory } from './engines/registry.ts';\nexport { MockEngine, mockVerdict, type MockResponder } from './engines/mock.ts';\n\n// Environments (where the code runs — the third provider axis)\nexport {\n isEnvironment,\n type Environment,\n type EnvHandle,\n} from './env/environment.ts';\nexport { MockEnvironment, type MockEnvOptions } from './env/mock.ts';\n\n// Runtime\nexport {\n run,\n exitCodeFor,\n EXIT_PAUSED,\n type RunOptions,\n type RunResult,\n} from './runtime/runner.ts';\nexport { Stats, type StatsSnapshot } from './core/stats.ts';\n\n// Supervision — observe a supervised run from another process. The registry is\n// files (~/.loops/runs), so these are the read side a `loops list`/`status`/`tail`\n// (or an MCP server) builds on. A run opts in with `RunOptions.supervise`.\nexport {\n listRuns,\n readRunStatus,\n runEventsPath,\n runSemanticRecordsPath,\n runsHome,\n formatEvent,\n type RunStatus,\n type RunLive,\n} from './runtime/supervisor.ts';\nexport {\n semanticRecordsFromEvent,\n type SemanticDecision,\n type SemanticOutcome,\n type SemanticRunRecord,\n} from './runtime/semantic.ts';\n\nimport type { Job } from './core/types.ts';\n\n/** Identity helper that pins the type of a default export to `Job`. */\nexport function defineJob(job: Job): Job {\n return job;\n}\n"]}