{"id":50116940,"url":"https://github.com/karolswdev/guildr","last_synced_at":"2026-05-23T15:33:40.924Z","repository":{"id":352531563,"uuid":"1215458451","full_name":"karolswdev/guildr","owner":"karolswdev","description":"Self-hosted, single-model SDLC orchestrator. One local LLM (Qwen3 via llama.cpp) plays five roles — Architect, Coder, Tester, Reviewer, Deployer — to drive a project from idea to deployed code, with human-approval gates and a LAN-only PWA.","archived":false,"fork":false,"pushed_at":"2026-04-20T02:27:56.000Z","size":5903,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T03:39:00.392Z","etag":null,"topics":["agent-orchestration","ai-agents","ai-coding-assistant","ai-orchestration","autonomous-agents","code-generation","developer-tools","dogfooding","fastapi","llama-cpp","llm","local-llm","multi-agent","pwa","python","qwen","sdlc-automation","self-hosted"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/karolswdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-19T23:48:48.000Z","updated_at":"2026-04-20T02:28:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/karolswdev/guildr","commit_stats":null,"previous_names":["karolswdev/guildr"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/karolswdev/guildr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karolswdev%2Fguildr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karolswdev%2Fguildr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karolswdev%2Fguildr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karolswdev%2Fguildr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karolswdev","download_url":"https://codeload.github.com/karolswdev/guildr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karolswdev%2Fguildr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33402165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-orchestration","ai-agents","ai-coding-assistant","ai-orchestration","autonomous-agents","code-generation","developer-tools","dogfooding","fastapi","llama-cpp","llm","local-llm","multi-agent","pwa","python","qwen","sdlc-automation","self-hosted"],"created_at":"2026-05-23T15:33:39.570Z","updated_at":"2026-05-23T15:33:40.917Z","avatar_url":"https://github.com/karolswdev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# guildr\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/screenshots/demo.gif\" alt=\"guildr PWA — create a project on iPhone-sized screen\" width=\"320\"\u003e\n\u003c/p\u003e\n\n\u003e **Status: alpha.** Dry-run pipeline is verified end-to-end (438 tests, 90% coverage).\n\u003e Live llama-server path runs but hasn't been battle-tested. Point it at a\n\u003e throwaway side project first.\n\n**What it is.** A self-hosted SDLC pipeline that turns a one-paragraph idea\n(`qwendea.md`) into a reviewed, tested, deploy-documented project — using\n**one local LLM** across five specialised roles, with human approval gates at\nthe points that actually matter.\n\n**Why you'd use it.**\n\n- **No API bills, no vendor lock.** Your GPU, your tokens, your filesystem.\n  Qwen3 on llama.cpp does all the work.\n- **Evidence over vibes.** Every task ships with a declared verification\n  command. The Tester re-runs it independently of the Coder — \"I wrote it\"\n  never implies \"I tested it.\"\n- **You stay in the loop.** Pipeline halts before implementation and before\n  deployment. Approve, reject, or edit in the PWA from your phone.\n- **Auditable by default.** Every phase writes a markdown artifact\n  (`sprint-plan.md`, `TEST_REPORT.md`, `REVIEW.md`, `DEPLOY.md`) plus a\n  JSONL event log. You can read every decision the model made.\n- **LAN-only out of the box.** Backend rejects non-RFC1918 source IPs unless\n  you explicitly opt in.\n\n---\n\n## How a project breaks up\n\nYou write `qwendea.md` — one paragraph describing what you want. Everything\nelse is produced by the pipeline:\n\n```mermaid\nflowchart LR\n    Q[qwendea.md\u003cbr/\u003eyour one-paragraph idea] --\u003e A[1. Architect]\n    A --\u003e SP[sprint-plan.md\u003cbr/\u003etasks + evidence reqs]\n    SP --\u003e G1{Gate:\u003cbr/\u003eapprove plan?}\n    G1 --\u003e|approve| C[2. Coder]\n    G1 -.-\u003e|reject / edit| A\n    C --\u003e Src[source + tests\u003cbr/\u003ewritten to project dir]\n    Src --\u003e T[3. Tester]\n    T --\u003e TR[TEST_REPORT.md\u003cbr/\u003eper-task PASS/FAIL]\n    TR --\u003e|any FAIL| C\n    TR --\u003e|all PASS| R[4. Reviewer]\n    R --\u003e RV[REVIEW.md\u003cbr/\u003eAPPROVED / REJECTED\u003cbr/\u003e+ criterion checklist]\n    RV --\u003e G2{Gate:\u003cbr/\u003eship it?}\n    G2 --\u003e|approve| D[5. Deployer]\n    G2 -.-\u003e|reject| C\n    D --\u003e DP[DEPLOY.md\u003cbr/\u003etarget + env\u003cbr/\u003e+ smoke tests]\n\n    style A fill:#2a4d6e,color:#fff\n    style C fill:#2a4d6e,color:#fff\n    style T fill:#2a4d6e,color:#fff\n    style R fill:#2a4d6e,color:#fff\n    style D fill:#2a4d6e,color:#fff\n    style G1 fill:#6e4d2a,color:#fff\n    style G2 fill:#6e4d2a,color:#fff\n```\n\nWhat each role is responsible for:\n\n| # | Role | Input | Output | What it actually does |\n|---|---|---|---|---|\n| 1 | **Architect** | `qwendea.md` | `sprint-plan.md` | Breaks the idea into numbered tasks; each task declares a verification command the Tester will later re-run. |\n| 2 | **Coder** | Approved sprint plan | Source files + tests | Implements tasks one at a time. Writes the test alongside the code, not after. |\n| 3 | **Tester** | Source tree | `TEST_REPORT.md` | Re-runs each task's declared evidence command from a clean shell. Looping back to the Coder if anything fails — up to `ORCHESTRATOR_MAX_RETRIES`. |\n| 4 | **Reviewer** | Source + test report | `REVIEW.md` | Checks against the sprint plan's acceptance criteria, flags scope creep, demands fixes. Not a rubber stamp — can reject and kick back to Coder. |\n| 5 | **Deployer** | Approved review | `DEPLOY.md` | Writes the runbook: target, env vars, manual steps, smoke tests. Does not push anything — that's yours. |\n\n**Retries are contextual, not blind.** When a phase fails, the harness feeds\nthe diff + failure tail back into the *next* attempt, and can optionally ask\na second \"Coach\" model for a diagnostic. The primary never sees the Coach's\noutput directly — it only sees the *advice* the Coach produced, so the main\ncontext stays clean.\n\n**Gates are strict.** Without `--no-gates`, the pipeline *stops* after the\nArchitect and after the Reviewer. You approve in the PWA (or CLI); rejecting\nkicks the phase back with your feedback appended to the context.\n\n---\n\n## Architecture\n\n```mermaid\nflowchart TB\n    User([👤 You])\n    PWA[PWA / CLI\u003cbr/\u003eguildr run]\n    API[FastAPI backend\u003cbr/\u003eLAN-only middleware]\n    ORCH[Orchestrator engine\u003cbr/\u003ephase state machine\u003cbr/\u003eretry + validate]\n    Pool[Async upstream pool]\n    LLM[llama-server\u003cbr/\u003eQwen3.6-35B-A3B]\n    Gate{Human gate}\n    FS[(project-dir/\u003cbr/\u003esprint-plan.md\u003cbr/\u003eTEST_REPORT.md\u003cbr/\u003eREVIEW.md\u003cbr/\u003eDEPLOY.md)]\n\n    User --\u003e|HTTP / SSE| PWA\n    PWA --\u003e API\n    API --\u003e ORCH\n    ORCH --\u003e Pool\n    Pool --\u003e LLM\n    LLM --\u003e Pool\n    Pool --\u003e ORCH\n    ORCH --\u003e Gate\n    Gate --\u003e|approve| ORCH\n    Gate --\u003e|reject| User\n    ORCH --\u003e FS\n```\n\n### The models doing the work\n\nEverything runs locally on consumer-ish hardware behind a LAN, served by\n[llama.cpp](https://github.com/ggerganov/llama.cpp):\n\n| Role | Model | Quant | Job |\n|---|---|---|---|\n| **Primary** | Qwen3.6-35B-A3B (MoE, 3B active) | Q5\\_K\\_M | All five orchestrator roles |\n| **Coach** | Qwen3.6-35B-A3B | Q6\\_K | Second-opinion diagnostic on failed phase retries |\n\nOne model, five hats. The Coach is just the same model on a second box,\nasked a different question — its output informs the next retry's prompt but\nnever reaches the Primary's context window directly.\n\n---\n\n## Quickstart\n\n### Install\n\n```bash\ngit clone https://github.com/karolswdev/guildr.git\ncd guildr\n./install.sh        # uses uv tool / pipx / pip --user, in that order\nguildr --help\n```\n\nPrereqs: Python 3.12+, Node 18+ (for the PWA bundle), and a llama.cpp server\nfor live runs. Dry-run works with no LLM at all.\n\n### Dry-run (no LLM required)\n\n```bash\nmkdir -p /tmp/demo \u0026\u0026 echo \"# A tiny CLI that prints hello.\" \u003e /tmp/demo/qwendea.md\nguildr run --from-env --dry-run --no-gates --project /tmp/demo\nls /tmp/demo/   # sprint-plan.md, TEST_REPORT.md, REVIEW.md, DEPLOY.md\n```\n\n### Live run\n\n```bash\nllama-server -m path/to/Qwen3.6-35B-A3B.gguf -np 1 --host 127.0.0.1 --port 8080\n```\n\n```bash\nexport LLAMA_SERVER_URL=http://127.0.0.1:8080\nexport PROJECT_DIR=/path/to/your/project   # must contain qwendea.md\nguildr run --from-env\n```\n\nOr with a config file (see `config.example.yaml`):\n\n```bash\nguildr run --config config.yaml\n```\n\n### Inspect a run\n\n```bash\nguildr inspect /path/to/your/project              # phase + retry summary\nguildr inspect /path/to/your/project --phase architect\nguildr inspect /path/to/your/project --tokens\n```\n\n### Web UI (PWA)\n\n```bash\nuvicorn web.backend.app:app --host 0.0.0.0 --port 8000\n```\n\nOpen `http://\u003cyour-lan-ip\u003e:8000` from any device on the same LAN. The\nfrontend bundle is built by `web/frontend/build.sh` (called automatically by\n`install.sh`).\n\n---\n\n## Configuration\n\n| Variable | Default | Description |\n|---|---|---|\n| `LLAMA_SERVER_URL` | (required for live) | llama.cpp endpoint (e.g. `http://127.0.0.1:8080`) |\n| `PROJECT_DIR` | `.` | Project working directory |\n| `ORCHESTRATOR_MAX_RETRIES` | `3` | Max retries per phase |\n| `ORCHESTRATOR_PROJECTS_DIR` | `/tmp/orchestrator-projects` | Root for PWA-created projects |\n| `ORCHESTRATOR_EXPOSE_PUBLIC` | `0` | Set to `1` to allow non-RFC1918 web access (logs a WARNING) |\n\nCLI flags override env vars; env vars override `--config` YAML.\n\n## Project layout produced by a run\n\n```\n\u003cproject-dir\u003e/\n├── qwendea.md              # your one-paragraph idea (source of truth)\n├── sprint-plan.md          # Architect output\n├── TEST_REPORT.md          # Tester output\n├── REVIEW.md               # Reviewer output\n├── DEPLOY.md               # Deployer output\n└── .orchestrator/\n    ├── state.json          # phase, retries, gate decisions\n    ├── sessions/           # exported session transcripts\n    └── logs/               # per-phase structured logs (.jsonl)\n```\n\n---\n\n## Where this came from\n\nguildr started as a one-screen bash loop. The loop poked a local opencode\nsession at Qwen3, fed it a phase plan, watched for idleness, ran a verifier.\nWhen the verifier failed, the loop stuffed the diff + failure tail into the\nnext prompt. That was the whole trick — and it worked well enough that the\nbash scaffold kept growing features (watchdogs, a retry coach, structured\nhandoff docs) until it was clearly trying to become a real framework.\n\nSo we let it. The harness wrote the orchestrator. The orchestrator is what\nthe harness wishes it were when it grows up.\n\n```mermaid\nflowchart LR\n    subgraph harness[\"bash harness (the scaffold)\"]\n        BL[build-phase.sh\u003cbr/\u003ewatchdogs + verifier gate\u003cbr/\u003eretry-context composer]\n    end\n\n    subgraph models[\"local llama.cpp\"]\n        P[Qwen3 PRIMARY\u003cbr/\u003ewrites the code]\n        C[Qwen3 COACH\u003cbr/\u003ediagnoses failures]\n    end\n\n    subgraph product[\"this repo (guildr)\"]\n        OR[Orchestrator engine\u003cbr/\u003e5 role prompts\u003cbr/\u003eretry + gate logic\u003cbr/\u003eweb PWA]\n    end\n\n    BL --\u003e|phase plan + retries| P\n    BL -.-\u003e|failure context| C\n    C -.-\u003e|hypothesis + next-attempt advice| BL\n    P --\u003e|writes / edits| OR\n    OR -.-\u003e|future: replaces| BL\n\n    style harness fill:#2d2d44,color:#fff\n    style models fill:#1a3d2e,color:#fff\n    style product fill:#3d1a2e,color:#fff\n```\n\nThe dotted arrow is the punchline: the artifact built by the harness is\nitself a more polished, testable, web-driven version of the harness. The\nretry-coach module in `bootstrap/lib/coach.sh` was itself proposed and added\nby the harness during one of its own retries.\n\n\u003e 📜 **Receipts.** The exact phase plans and end-of-phase handoffs the model\n\u003e worked from are checked in under [`docs/methodology/`](docs/methodology/).\n\u003e Read those for the unfiltered version of what got fed to the LLM.\n\n---\n\n## Development\n\n```bash\npython -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install -e \".[dev]\"\n\npytest -q                                          # full suite (~20s, 438 tests)\npytest tests/test_integration_dry_run.py -v        # full pipeline e2e (dry-run)\npytest --cov=orchestrator --cov=web --cov-report=term-missing\n```\n\n## Security\n\nguildr is designed for self-hosted, single-user use on a trusted LAN. The\nweb backend rejects non-RFC1918 source IPs by default; the llama-server\nupstream has no authentication. Do not expose this to the internet without\nadding your own auth layer.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarolswdev%2Fguildr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarolswdev%2Fguildr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarolswdev%2Fguildr/lists"}