Skip to main content

Closed-loop automation across semcod/* repositories.

Project description

koru

koru

AI Cost Tracking

PyPI Version Python License AI Cost Human Time Model

  • ๐Ÿค– LLM usage: $1.7887 (37 commits)
  • ๐Ÿ‘ค Human dev: ~$1130 (11.3h @ $100/h, 30min dedup)

Generated on 2026-05-11 using openrouter/qwen/qwen3-coder-next


Python package for closed-loop refactor automation across multi-repo workspaces (validated on semcod/*, maskservice/c2004, and other monorepos).

The name refers to Koru (Mฤori spiral), matching the "spiraling loop" refactor flow: detect โ†’ plan โ†’ execute โ†’ verify โ†’ heal โ†’ repeat.

What koru is

A meta-orchestrator that coordinates LLM-augmented refactor tools with ticket-driven workflow and regression-free verification:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                          KORU                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ DETECT   โ”‚ PLAN     โ”‚ EXECUTE  โ”‚ VERIFY   โ”‚ HEAL    โ”‚ LEARN    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ redup    โ”‚ planfile โ”‚ Windsurf โ”‚ regix    โ”‚ healing โ”‚ pyqual   โ”‚
โ”‚ regix    โ”‚ tickets  โ”‚ Cursor   โ”‚ pytest   โ”‚ webhook โ”‚ metrics  โ”‚
โ”‚ TestQL   โ”‚ Promet.  โ”‚ aider    โ”‚ TestQL   โ”‚ retry   โ”‚dashboardsโ”‚
โ”‚ Probe    โ”‚ Alertmgr โ”‚ vallm    โ”‚ vallm    โ”‚         โ”‚          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ†‘                                                  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ closed-loop feedback โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Quick start โ€” start an LLM session in 3 commands

cd /path/to/your/project
pip install koru
koru --init                # 1. set up .planfile/ + .koru/ + .gitignore
koru                       # 2. print the LLM brief (paste into Cascade/Cursor/aider)
koru --queue --loop        # 3. drain the queue (the agent works on each ticket)

That is the entire onboarding. koru (no args) is the command an LLM agent runs at the start of every session โ€” the markdown brief it prints contains the active ticket, the policy gates, and the exact planfile ticket โ€ฆ commands the agent is allowed to use. Nothing else needs to be memorised.

If the project is not initialised yet, koru (no args) detects this and prints a โš  Setup required section with the exact koru --init command to run โ€” the LLM never has to guess.

Diagnostics โ€” koru --doctor

When something feels off (LLM stuck, queue runner refusing, policy not taking effect), run:

koru --doctor                 # human-readable PASS/WARN/FAIL list
koru --doctor --format json   # machine-readable for the LLM itself

The doctor probes 8 things and never writes anything: git_repo, planfile_binary, planfile_config, planfile_sprints, runtime_dir, policy_yaml, gitignore, ci_command. Exit code is 1 if any check fails, 0 if only warnings (warnings are advisory). Use it after koru --init and whenever a session starts mis-behaving.

Natural-language intake and housekeeping are built in:

koru task "Dodaj feature importu raportรณw"
koru agent --list          # show Windsurf/Cursor/Claude Code/aider/OpenRouter lanes
koru agent                 # print and save the current LLM handoff prompt
koru agent --launch        # launch the best available CLI agent when possible
koru scan                  # auto-generate tickets from repo signals (TODOs, pytest errors)
koru scan --apply          # create the proposed tickets in planfile
koru gc                    # preview stale tickets eligible for cleanup
koru gc --apply            # delete old done/failed/blocked tickets
koru gate authorize PLF-070 --mode advisory --reason "..."  # record a gate waiver

The no-args koru prompt includes detected project markers (pyproject.toml, package.json, Taskfile.yml, .windsurf/, .cursor/, .planfile/), available LLM/IDE lanes, the recommended agent, the active ticket, and the exact lifecycle commands the agent may use.

Two operational modes

Mode When What runs
Default: IDE-native normal ticket work, no external API Windsurf/Cursor LLM + task tickets:next + regix/pytest
Opt-in: OpenRouter automation lane infra smoke tests, headless auto-fix, scheduled runs redsl improve, llx fix, vallm validate --semantic (all use OpenRouter)

Install (editable)

pip install -e .

Multi-repo loop mode

Run one command across matching repositories and retry failures in a closed loop:

koru \
  --workspace /path/to/repos \
  --include "semcod/*" \
  --command "python -m pytest -q"

Or use Taskfile

task                          # list all tasks (40+)
task install                  # pip install -e .
task ci                       # local CI equivalent: lint + tests
task install:tools            # planfile, regix, redup, vallm, prefact, pfix
task tickets:next             # highest-priority open ticket
task queue:run                # execute one runnable planfile queue task
task queue:dry-run            # preview the next planfile queue task
task queue:watch              # watch planfile WebSocket queue events
task quality:regix            # regression metrics gate
task quality:redup            # duplicate detection
task template:install         # bootstrap configs in current dir
task webhook:run              # start healing-webhook on :8810

Full examples: docs/cli-examples.md

Planfile queue runner

koru can execute one runnable planfile ticket at a time, or drain the entire queue in a single call:

# Single tick (legacy, default):
koru --queue --project . --actor koru-shell

# Drain everything:
koru --queue --project . --loop --max-iterations 50

# Drain shell tickets AND answer humans interactively in one shot:
koru --queue --project . --loop --interactive --actor c2004-koru

# Preview without execution:
koru --queue --project . --dry-run

By default koru uses the current Python environment's planfile module when available, then falls back to the planfile executable in PATH. To pin a specific command:

KORU_PLANFILE_CMD="python -m planfile.cli" koru --queue --project .

Supported executor kinds:

  • executor.kind: shell โ€” claim, start, run inputs.script or executor.handler, then complete or fail the ticket.
  • executor.kind: api โ€” claim, start, call inputs.api_endpoint (or executor.handler) with inputs.api_method, inputs.api_headers, inputs.api_body, then complete or fail the ticket.
  • executor.kind: llm โ€” claim, start, POST inputs.prompt to an OpenAI-compatible chat-completion endpoint (default OpenRouter), capture the assistant's text as the ticket's stdout, and store llm_model + token usage in the result-json. Configure via OPENROUTER_API_KEY / OPENAI_API_KEY / KORU_LLM_ENDPOINT. See docs/cli-examples.md for the full schema.
  • executor.kind: human โ€” print the prompt and leave the task for an operator. With --interactive, koru collects the answer on stdin (multi-line, Ctrl-D submits, Ctrl-C cancels) and completes the ticket itself.

The remaining executor kind (mcp) is intentionally reported as unsupported until its adapter is wired (Phase 5).

Minimal API ticket:

tickets:
  PLF-010:
    name: "Notify deployment API"
    status: open
    priority: high
    executor:
      kind: api
      mode: automatic
    execution:
      queue: default
      state: ready
    inputs:
      api_endpoint: "http://localhost:8810/probe-failure"
      api_method: POST
      api_headers:
        content-type: application/json
      api_body:
        source: koru

To watch queue changes streamed by the planfile API:

uvicorn planfile.api.server:app --reload --port 8000
koru --watch --ws-url ws://localhost:8000/ws
task queue:watch

For transparent management-layer logs in a dashboard, point koru at the planfile event-ingest endpoint:

export KORU_EVENTS_URL="http://localhost:8000/events/ingest"
koru --queue --project . --dry-run

When configured, koru emits best-effort management.event entries for koru.bootstrap, koru.queue, koru.watch, and repository loop runs. This is intended for UI surfaces such as planfile's Live Events panel and does not change queue execution semantics.

watch support uses the optional websockets package. Install it with:

pip install "koru[watch]"

Queue garbage collection โ€” koru gc

Over time, completed and failed tickets accumulate in the sprint YAML. koru gc cleans them up:

koru gc                              # dry-run: preview what would be removed
koru gc --apply                      # actually delete stale tickets
koru gc --max-age 7                  # only keep tickets younger than 7 days
koru gc --keep-last 5                # always keep the 5 newest done tickets
koru gc --status done,failed         # only clean these statuses (default: done,failed,blocked)
koru gc --no-archive                 # skip JSONL archive before deletion
koru gc --format json                # machine-readable output

Before deletion, tickets are archived to .planfile/.koru/gc/gc-YYYYMMDD-HHMMSS.jsonl (disable with --no-archive). The --keep-last N flag protects the N most recently finished tickets per status even when they exceed --max-age.

Filesystem contract

koru never writes outside <project>/.planfile/. This is a hard rule for the production code path; any deviation is a bug.

<project>/.planfile/
โ”œโ”€โ”€ config.yaml                  # planfile-owned (project config)
โ”œโ”€โ”€ sprints/
โ”‚   โ””โ”€โ”€ current.yaml             # planfile-owned (source of truth)
โ””โ”€โ”€ .koru/                       # koru-owned, opt-in, gitignore-friendly
    โ”œโ”€โ”€ runs/                    # one log per `koru --queue` invocation
    โ”œโ”€โ”€ gc/                      # JSONL archives from `koru gc --apply`
    โ”œโ”€โ”€ prompts/                 # captured `--interactive` answers
    โ”œโ”€โ”€ llm-cache/               # opt-in LlmExecutor response cache
    โ””โ”€โ”€ README.md                # in-place explainer

The .koru/ subtree is non-authoritative โ€” planfile sprint YAML is always the source of truth. Anything in .koru/ can be deleted at any time without losing ticket state. Recommended .gitignore entry:

.planfile/.koru/

The path helpers exposed by koru.runtime (runtime_dir, runs_dir, new_run_id, ensure_runs_dir) are pure resolvers โ€” they only touch disk via ensure_runs_dir, so a --dry-run invocation leaves zero trace.

/tmp/ policy. Production code does not use /tmp/. Test fixtures (tests/ and tests/e2e/*.sh) are the only allowed /tmp/ users and MUST be PID-scoped (/tmp/koru-*-$$) with trap cleanup EXIT so a failed run leaves nothing behind. If you find koru artefacts elsewhere, please open an issue.

LLM agent contract โ€” koru as the gate

When an LLM agent (Cascade, Cursor, aider, claude-code, local model, โ€ฆ) drives a koru-managed project, it must read its instructions from koru, not from the human chat.

The agent's first command in every session is just koru โ€” the markdown brief that comes back is the entire contract. If the project has never been initialised, the brief leads with โš  Setup required and the exact koru --init command. The contract is delivered by:

koru --context --project .                     # JSON brief (machine-readable)
koru --context --project . --format markdown   # Markdown handoff (paste-to-IDE)
koru --context --project . --ticket PLF-074    # brief for a specific ticket

The brief contains everything an autonomous agent needs to act safely:

  • the next runnable ticket (or one named via --ticket) โ€” id, name, status, files in scope, prompt, executor kind;
  • the resolved policy โ€” explicit booleans for every git operation the agent might attempt;
  • environment fingerprint โ€” git branch, dirty state, remote, whether planfile is initialised in the project;
  • imperative rules โ€” copy-paste-able DO NOT โ€ฆ lines so even a weak model can compare any candidate command to a checklist;
  • self-service vocabulary โ€” concrete planfile ticket {claim,start, complete,fail,input} invocations with the active ticket id pre-filled.

Safe-by-default policy

The policy lives at <project>/.planfile/.koru/policy.yaml. All gates default to the most restrictive value. A missing or malformed file falls back to defaults โ€” corruption can never silently loosen the policy.

gate default meaning
allow_commit false the agent does NOT run git commit
allow_push false the agent does NOT run git push
allow_branch_create false no git checkout -b, git branch X, git switch -c
allow_branch_switch false no git checkout <ref>, git switch <branch>
allow_tag false no git tag
allow_destructive_shell false blocks rm -rf /, dd, mkfs, force-pushes, โ€ฆ
require_planfile_lifecycle true every state change goes through planfile ticket *
require_ci_pass_before_complete true the agent verifies CI exit 0 before ticket complete

The agent bounces off CI/CD and koru: it cannot commit, cannot push, cannot mutate planfile state outside the CLI vocabulary the brief gave it. To make a change that ships, the agent has exactly two exits: complete the ticket (humans/CI take it from there) or call planfile ticket input <id> --prompt "<question>" and stop.

Universal quality gates (built-in)

Every koru --init creates a universal CI command that automatically detects and runs quality tools when they're available:

# Runs on every ticket completion (if require_ci_pass_before_complete=true)
echo "=== Universal Quality Gates ==="

# 1. Project tests (auto-detects runner)
# - task test (Taskfile)
# - pytest -q (Python)
# - npm test (Node.js)
# - make test (Makefile)

# 2. TestQL E2E scenarios (when *.testql.toon.yaml files exist)
testql suite --pattern "*.testql.toon.yaml" --output console --fail-fast

# 3. WUP dependency analysis (when wup.yaml exists)
wup status

# 4. Regix quality gates (when regix.yaml exists)
regix gates

Tools are gracefully skipped if not installed or configured โ€” no manual setup required for basic quality control. The universal gates ensure:

  • Consistent quality across all koru projects
  • Automatic regression testing with testQL scenarios
  • Zero configuration for basic validation
  • Adaptive detection of project-specific tooling

Auto-promotion & auto-repair for blocking tickets

Koru automatically manages workflow priorities to prevent deadlocks:

Auto-promotion

  • Tickets that block others are automatically promoted to critical priority
  • This ensures blocking issues are resolved first
  • Promotion happens on every koru --context call

Auto-repair mode

  • Critical tickets receive special instructions for LLM agents:
    • "AUTO-REPAIR MODE: Fix this issue immediately to unblock the workflow"
    • "Do NOT ask for human input unless absolutely necessary"
    • "Use all available tools and knowledge to resolve the blocking issue"
    • "After fixing, immediately call planfile ticket complete"

Workflow

  1. Main task โ†’ encounters blocking issue
  2. Blocking ticket created โ†’ auto-promoted to critical
  3. LLM agent receives auto-repair instructions
  4. Issue resolved โ†’ main task unblocked
  5. Workflow continues without manual intervention

Bug-first priority system

Koru ensures bugs are always fixed before features when priorities are equal:

Automatic bug promotion

  • Bugs get priority boost within their category:
    • low โ†’ normal
    • normal โ†’ high
    • high โ†’ critical
    • critical stays critical
  • Promotion happens automatically on every koru --context call
  • Only tickets with bug label are promoted

Priority hierarchy

critical (blocking tickets + high-priority bugs)
โ”œโ”€โ”€ high bugs (promoted from normal)
โ”œโ”€โ”€ high features
โ”œโ”€โ”€ normal bugs (promoted from low)
โ”œโ”€โ”€ normal features
โ”œโ”€โ”€ low bugs
โ””โ”€โ”€ low features

Benefits

  • Bug-first workflow โ€” stability issues resolved before new features
  • Automatic triage โ€” no manual priority adjustments needed
  • Predictable execution โ€” bugs always jump ahead of same-priority features
  • Quality assurance โ€” prevents feature development while bugs exist

Integration with planfile

Koru's priority system is fully integrated with planfile:

Shared priority logic

  • Same promotion rules applied in both koru and planfile core
  • Consistent ticket ordering across all planfile commands
  • Unified bug-first workflow throughout the ecosystem

Planfile commands enhanced

  • planfile ticket next โ€” respects bug-first priorities
  • planfile ticket list โ€” shows promoted priorities
  • planfile queue โ€” processes bugs before features
  • All planfile operations use the same priority hierarchy

Seamless workflow

  1. Koru auto-promotes tickets on --context call
  2. Planfile respects promoted priorities natively
  3. Consistent execution whether using koru or planfile directly
  4. No conflicts โ€” both systems use identical priority logic

Loosening the policy

Editing <project>/.planfile/.koru/policy.yaml is the only way to relax a default. There is no CLI flag for it โ€” that is a deliberate choice so any loosening is reviewable in git history.

# .planfile/.koru/policy.yaml
llm:
  allow_commit: false       # never (recommended)
  allow_push: false         # never (recommended)
  allow_branch_create: true # opt-in: agent may create feature branches
ci:
  command: pytest -q        # override universal gates (optional)
  timeout_seconds: 300
notes:
  - "Always run `task lint` before `ticket complete`."
  - "Never edit migrations under alembic/versions/."

Run logs

koru --queue and koru --queue --loop write a JSON-Lines log per run to <project>/.planfile/.koru/runs/queue-<timestamp>-<pid>.jsonl:

{"type":"run.start","run_id":"queue-โ€ฆ","mode":"loop","actor":"koru","pid":12345,โ€ฆ}
{"type":"iteration","iteration":1,"ticket_id":"PLF-074","status":"completed",โ€ฆ}
{"type":"iteration","iteration":2,"ticket_id":"PLF-075","status":"failed",โ€ฆ}
{"type":"run.end","iterations":2,"completed":["PLF-074"],"failed":["PLF-075"],โ€ฆ}

--dry-run skips the writer (preserves "dry-run leaves zero trace"). --no-log opts out explicitly. Logs are non-authoritative โ€” planfile sprint YAML remains the source of truth.

Documentation

The full documentation lives in docs/:

  • docs/agent-guide.md โ€” full LLM agent workflow guide (originally written for maskservice/c2004 Windsurf agent, generalized for any koru-driven repo). Covers ticket workflow, validation gates, anti-patterns, troubleshooting.
  • docs/planfile-llm-guide.md โ€” ticket-driven development with planfile CLI.
  • docs/planfile-execution-gateway.md โ€” design for turning planfile.yaml into the execution gateway for shell, MCP, API, human, and LLM tasks.
  • docs/llm-tools/ โ€” per-tool docs and install scripts:
    • planfile/ โ€” ticket backlog
    • regix/ โ€” Python regression metrics
    • redup/ โ€” duplicate detection
    • redsl/ โ€” OpenRouter auto-refactor (opt-in)
    • vallm/ โ€” multi-tier patch validator
    • prefact/ โ€” proactive LLM-aware linter
    • pfix/ โ€” auto-fix imports
    • llx/ โ€” LLM CLI wrapper
    • sumd/ โ€” LLM refactor snapshots (SUMR.md)
    • redeploy/ โ€” multi-target deployment (markpact specs)
    • goal/ โ€” automated git push + smart commits + release workflow
    • doql/ โ€” declarative infrastructure-as-code (.doql files)
    • costs/ โ€” zero-config AI cost tracker per commit
    • op3/ โ€” layered infrastructure observation (multi-layer scan)
    • toonic/ โ€” universal TOON format platform (LLM-friendly compact files)
    • protogate/ โ€” migration tool dla legacy systems (bounded slices)
    • rebuild/ โ€” code evolution intelligence (git history walker)
    • mdflow/ โ€” markdown dependency analyzer
    • metrun/ โ€” execution intelligence + bottleneck detection
    • aider/ โ€” pair-programming agent
    • claude-code/ โ€” Anthropic agent
    • cursor/ โ€” Cursor IDE setup
    • testql/ โ€” declarative HTTP tests

Templates (config snippets)

Reference configurations from the c2004 reference deployment:

Reference deployment

maskservice/c2004 โ€” the original production-grade closed-loop refactor system that koru generalizes. Real metrics from c2004 (May 2026):

  • 88% size reduction in compatibility shim files (14640 โ†’ 1812 bytes)
  • 8 stale alerts auto-closed in single workflow run
  • 0 errors / 42 improvements per regix gate after refactor
  • 58/58 endpoint health probes post-migration

License

Licensed under Apache-2.0.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

koru-0.1.15.tar.gz (124.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

koru-0.1.15-py3-none-any.whl (95.3 kB view details)

Uploaded Python 3

File details

Details for the file koru-0.1.15.tar.gz.

File metadata

  • Download URL: koru-0.1.15.tar.gz
  • Upload date:
  • Size: 124.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for koru-0.1.15.tar.gz
Algorithm Hash digest
SHA256 746ec9685613f7bed01b5ccdc16651f752f0c23800f835fc257fb5394e97fed9
MD5 26a7a7ddfc0c64453249d4f90f22d551
BLAKE2b-256 c10f3aa63cb67eeb1a4840d3ded8ae277b6db4905cdd54ba34c5818111c3cb9f

See more details on using hashes here.

File details

Details for the file koru-0.1.15-py3-none-any.whl.

File metadata

  • Download URL: koru-0.1.15-py3-none-any.whl
  • Upload date:
  • Size: 95.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for koru-0.1.15-py3-none-any.whl
Algorithm Hash digest
SHA256 b0f15f388bc6aa794b215e8392658ba63480b30ab85dd5fd34c55279a35dbe3e
MD5 5393574237df03da3825add1739c3c0d
BLAKE2b-256 8e0c92269f44eddfd7016047f4157a63587a13fae2b32928b2a2d6c7c04b551b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page