AI News HubLIVE
サイト内リライト5 分で読了

翻訳待ち:Orchestration engine to drive autonomous AI coding agents in parallel

AI サービスが一時的に利用できないため、復旧後に翻訳を補完します。ソース概要:Notifications You must be signed in to change notification settings Fork 1 Star 33 BranchesTags Open more actions menu Latest commit History 656 Commits 656 Commits Folders and files NameName Last commit message Last co…

ソースHacker News AI著者: alexreysa

AI サービスが一時的に利用できないため、復旧後に翻訳を補完します。

Notifications You must be signed in to change notification settings Fork 1 Star 33 BranchesTags Open more actions menu Latest commit History 656 Commits 656 Commits Folders and files NameName Last commit message Last commit date claudedocs claudedocs cli cli docs docs engine engine migrations migrations plugin plugin schemas schemas singular-ext singular-ext templates templates tests tests tools tools .gitignore .gitignore .singular-version .singular-version CHANGELOG.md CHANGELOG.md CONTRIBUTING.md CONTRIBUTING.md LICENSE LICENSE README.md README.md SCHEMA_VERSION SCHEMA_VERSION SECURITY.md SECURITY.md VERSION VERSION install.sh install.sh singular.config.json singular.config.json Repository files navigation Autonomous multi-agent orchestration for software repos. One engine, many consumers. singular is a bash + Python orchestration engine that drives autonomous AI coding agents in parallel against a repository. It implements a three-tier scheduling model (L0 origin loop → L1 area planners → L2 worker agents) with durable leases, state packets, gate/audit pipelines, and git-worktree isolation. The engine is installed once per machine and pinned per consumer repo — improvements propagate by bumping a version pin, not by re-copying scripts. How it works Agent tiers Tier Role L0 origin The single scheduler. Runs the reconcile cycle: import → recover → integrate → dispatch → snapshot. Holds the origin lock only during control work. L1 area planners One planner per DAG node (area). Reads the node's context, plans a batch of L2 tasks, and stages them as proposals for L0 to import. L2 workers Execute a single task in an isolated git worktree on a per-task branch. Produce a state packet (owned files, changes, evidence). An auditor reviews the packet; the decider routes the outcome. Reconcile cycle Each singular reconcile --actuate runs: Import — pull staged L1 task proposals into the DAG under the origin lock. Recover — reclaim stale leases whose workers have exited or timed out. Integrate — merge completed worker branches into the target branch under the git-op lock. Dispatch — pre-lease frontier tasks and spawn L2 workers. Snapshot — write a human-readable project state snapshot. Leases and packets Every in-flight task holds a lease (a JSON file in .singular-state/leases/) that records ownership, retry count, and expiry. When a worker finishes it writes a state packet (state-packet.v0.schema.json) enumerating owned files, changed files, commands, tests, and evidence. The auditor validates the packet; the reaper attributes outcomes on later cycles. Gates and audits After each L2 worker run the host executes the configured gate command (e.g. npm test). A gate result (gate-result.v0.schema.json) feeds the auditor model, which returns an audit verdict (audit-verdict.v0.schema.json). The decider maps the (failure-class, retries-left) pair to a recovery action — retry, amend-scope, escalate, or park — using a deterministic fast-path table before falling back to a model round-trip. A bare command works: exit 0 passes, non-zero fails. The exit code cannot answer two questions the engine would use if it could, so a gate may optionally write a gate observation (gate-observation.v0.schema.json) to the path in SINGULAR_GATE_REPORT_FILE: failures[].signature — stable per-failure identifiers. Required for singular gate baseline to tell an acknowledged failure from a new one. infrastructureFailure / infrastructureReason — the gate could not run (missing dependencies, full disk, unreachable network). The engine reports that as inconclusive-infrastructure instead of spending a task's retry budget asking a model to fix code that was never broken. singular init scaffolds docs/orchestration/gates/gate.sh as a starting point. The sidecar is never required — including on schemaVersion: v2. Without one the engine falls back to the exit code plus a deliberately narrow set of log signatures (engine/infra-patterns.tsv) covering only environment failures that application code cannot plausibly produce. Dispatch model Detached dispatch is ON by default. When SINGULAR_DETACHED_DISPATCH=1 (the default), reconcile pre-leases each frontier task and spawns the worker in its own session via dispatch-wrap.sh, then returns within seconds. The origin lock is held only for the cycle's control work. A reaper (singular_reap_dispatches) runs at the top of every apply/actuate cycle and attributes completions, failures, and crashes by checking dispatch records + worker exit files (pid liveness defeats pid reuse; crash detection drops from the 60-min stale-lease window to ~one cycle). This is what keeps import, integrate, recover, STATUS, and STOP responsive while long workers run in the background. Set SINGULAR_DETACHED_DISPATCH=0 to restore the legacy synchronous batch path, where reconcile waits for every worker before returning. Install Prerequisites: Bash >= 4, python3, and git. At least one supported runner CLI on PATH (claude, codex, or another configured runner). macOS users may need brew install bash. Set SINGULAR_BASH_BIN=/opt/homebrew/bin/bash in the shell/service environment to select it without reordering PATH. When multiple Codex installations exist, set SINGULAR_CODEX_BIN=/absolute/path/to/codex. Doctor and the runner use that exact executable and do not fall back when it is broken. # Clone and install the engine to ~/.singular git clone https://github.com/alex-reysa/singular-lite /path/to/singular-lite cd /path/to/singular-lite bash install.sh # -> ~/.singular/versions// ~/.singular/current ~/.singular/bin/singular export PATH="$HOME/.singular/bin:$PATH" Singular's launch namespace is intentionally clean: SINGULAR_*, singular.config.json, .singular-version, .singular-state/, and the SINGULAR_HOME install root (default ~/.singular). It does not discover or import the pre-launch namespace replaced by this release. Start each consumer with singular setup and author a fresh DAG. In each consumer repo: singular setup # one idempotent path from "a repo" to a verified, STOPPED repo singular setup composes the individual lifecycle verbs and contributes the order, the evidence, and the contract. It checks interpreter/repo/git work tree, resolves the engine pin (naming the winner when .singular-version and singular.config.json engineVersion disagree), installs the pinned engine when it is absent — only from a matching engine checkout already on this machine, since there is no download mechanism — writes .singular-state/STOP as its first repo write, pins and scaffolds, hashes every gate result before printing and running the migration chain, verifies those historical verdicts survived, runs doctor, and records a supervised regression run. Prerequisites fail before anything is mutated. It reports a state ladder (installed → migrated → validated → stopped-ready), never actuates, and prints exactly one Next: line. Failures carry a stable code and one recovery instruction (singular.operator-failure.v0); evidence lands under .singular-state/setup/. singular setup --no-test # stop at validated, without the regression run singular setup --test-async # start the suite detached; attach with singular test --wait singular setup --json # one singular.setup-report.v0 object on stdout The composed steps are still available on their own: singular init # scaffold singular.config.json, docs/orchestration/, .singular-version singular doctor # check deps, engine resolution, repo config singular migrate # raise schemaVersion to the engine's (--dry-run prints the chain only) SINGULAR_BASH_BIN is bootstrap-only and is ignored in singular.config.json; set it before invoking singular. SINGULAR_CODEX_BIN may be supplied through the normal engine environment/config layers. For the standard Codex runner, singular doctor performs bounded --version and login status probes against the exact selected executable. Doctor is also the machine-readable preflight for unattended runs: singular doctor --json | jq '.summary, .checks[] | select(.status != "pass")' singular doctor --repair-model-cache # explicit: backup first, then regenerate later Every JSON check has a stable id, severity, requiredFor, remediation, and dedupeKey. Required capability failures block doctor; a missing optional capability produces one warning even when several roles share it. Doctor checks deployment credentials only while a deployment-capable DAG node is actually in the ready frontier. It never silently deletes or rewrites Codex model cache data: the repair flag moves the original to a timestamped, SHA-tagged backup. Role profiles are local-only by default. Repositories that need extra tools, MCP servers, or plugins can declare lazy profiles explicitly: { "capabilityProfiles": { "audit-core": { "startup": "lazy", "required": ["filesystem", "git", "schemas", "runner-contract"], "optional": ["mcp:browser"] } }, "roleProfiles": { "auditor": "audit-core", "decider": "audit-core" } } Capability IDs may use mcp:NAME, plugin:NAME, executable:NAME, or file:REPO_PATH. More specialized capabilities can be declared in the top-level capabilities registry with a type of builtin, executable, file, mcp, plugin, or environment. In strict profiles, external skills, MCP servers, and plugins are activated only by capabilityArgs.; unrelated providerArgs never claim a capability. Legacy SINGULAR_*_EXTRA_ARGS variables are rejected for strict runs because they are not capability-bound. Each repo pins its engine version in .singular-version (overrides singular.config.json engineVersion). The singular launcher resolves that version from ~/.singular/versions/, binds SINGULAR_ROOT to the current repo, loads its config, and execs the engine. Run singular update to repin. Use # Run one reconcile/actuate cycle (import → recover → integrate → dispatch → snapshot) singular reconcile --actuate # Drive a single task through L1 → L2 → audit singular drive TASK-0001 # Self-driving autonomy loop (wall-clock budget: SINGULAR_MAX_HOURS) singular auto # Create, approve, or inspect an owner- and artifact-hash-bound human gate singular human-gate request --help singular human-gate approve --help singular human-gate status --help # Report every contract violation in a gate-result at once. The frontier read # stops at the first breach (correctly — it must not act on an invalid gate), # which means a promoter under development learns about one violation per run. singular gate validate docs/orchestration/gates/.gate-result.json # The old promote-gate --operator route is schema-v2 legacy compatibility only # Block until all detached workers finish (useful in CI or clean shutdown) singular reconcile --drain # Context graph (behind SINGULAR_CTX_GRAPH): project the event log into # context-graph.v0 JSONL, sync incrementally, and query it singular graph rebuild singular graph sync singular graph query neighbors # Experiment tooling (behind SINGULAR_CTX_EXPERIMENT): per-arm metrics, # treatment-vs-control delta, and rendered report tables singular experiment-report summary singular experiment-report delta singular experiment-report tables Configuration All per-repo variation lives in the consumer repo, never in engine files: singular.config.json — declarative: targetBranch, gateCommand, runner, areas{}, areaPrefix, prewarm, worktreeCopyPaths[], modules[], identity{}, env{}, provisionFiles[], envAllowlist[], capabilityProfiles{}, roleProfiles{}, evidence{}, bootstrap{}, resources{}, promoter, controlState{}, and legacyCompatibility{}. promoter is the one most consumers need and miss. It names the script that decides when a DAG node's gate may be promoted — a bare name resolves to /singular-ext/.sh, a path is used as-is (repo-relative); SI [truncated for AI cost control]