rob thijssen 7b8308d34e
Some checks failed
deploy / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
feat(prompt): make the plan handoff a versioned, validated contract
helexa#179's application-owned system prompts let tireless shape both ends of
the cc->oc handoff, so the "will a 27B execute an Opus plan" risk becomes a
tunable rather than a hope.

Three prompts, versioned as one set: plan.cc.md tells Claude Code it is writing
for a literal, absent reader; implement.oc.md tells OpenCode to execute exactly
that and report rather than improvise; implement.cc.md covers unplanned issues.
PromptSet::load refuses a mismatched set, and tests assert the prompts mention
every section ChildSpec requires.

The middle is validated, not trusted. plan::validate rejects a plan before any
implementation job is enqueued unless every child carries a runnable acceptance
command (a stopping condition) and a non-empty out-of-scope list (a boundary) --
the two sections a small model needs and a human reader does not. Dangling and
cyclic dependencies are caught too, and implementation_order derives the start
order.

cc uses --append-system-prompt, never --system-prompt: replacing Claude Code's
default discards the tool-use scaffolding that makes it a coding agent. Pin
bumped to 2.1.220, the version this flag surface was verified against.

The oc path depends on helexa#179's passthrough guarantee, which is still open
and unverified for qwen3 arch templating. Stage 5 now opens with a PONG probe
rather than debugging it through a failed implementation run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHhHtohxcdk1PL3tfnYJdH
2026-08-02 15:26:05 +03:00

tireless

Watches labelled issues on Gitea (and GitHub, for legacy repos), claims them, and either decomposes them into an epic with child issues or implements them and opens a pull request. A human reviews everything; nothing merges itself.

Two coding agents do the work, each spawned as the vendor's own binary:

  • Claude Code — planning, and implementation of issues that need interpretation. Uses the operator's Claude subscription by default, or pay-as-you-go if an API key is supplied.
  • OpenCode — implementation of issues that a tireless plan already specified, against the self-hosted helexa fleet. Never Anthropic; enforced at startup.

The rule of thumb: Claude Code gets judgement, OpenCode gets specification.

Full design, constraints and the staged implementation plan: doc/plan/design.md.

Status

Stage 0 (foundations) is scaffolded. Ingestion, claiming and the agent lanes are not built yet — see §7 of the design document for what lands when.

Build

cargo test --workspace
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --all

cd dashboard && npm ci && npm run build

Run locally

cargo run -p tireless-api -- --config ./config.toml
cargo run -p tireless-worker -- --config ./config.toml poll
cargo run -p tireless-worker -- --config ./config.toml run

cd dashboard && npm run dev     # proxies /v1 to 127.0.0.1:23296

tireless preflight verifies configuration and credentials without starting a service: it reports which billing mode a Claude Code run would use and asserts the OpenCode lane is not pointed at Anthropic.

Deploy

CI-driven via Gitea Actions on merge to main (architecture/deployment-gitea-actions.md). One-time host provisioning — including the interactive Claude Code login and the Gitea bot account — is script/infra-setup.sh.

Host bob.hanzalova.internal
API port 23296 (registered in architecture/port-allocations.md)
Dashboard https://tireless.internal (mesh only)
Database magrathea.kosherinata.internal:5432, mTLS

Conventions

Follows lair/architecture; generic.md is the baseline. Two deliberate deviations:

  • tireless-agent crate beyond the standard entities/core/data split. Process orchestration is not data access, and it is shared by the runner and the CLI. (§1)
  • MemoryDenyWriteExecute=false on tireless-runner. Both agents are Node programs and V8's JIT needs write-then-execute pages. The API and poller keep the setting. (§8)
Description
Autonomous issue-to-PR development driver for Claude Code and OpenCode
Readme 618 KiB
Languages
Rust 83.5%
Shell 8.6%
TypeScript 7%
JavaScript 0.5%
CSS 0.3%
Other 0.1%