{"id":50727175,"url":"https://github.com/dsj7419/forge-gate","last_synced_at":"2026-06-10T05:01:39.086Z","repository":{"id":360072570,"uuid":"1248544640","full_name":"dsj7419/forge-gate","owner":"dsj7419","description":"Deterministic, human-gated orchestration for Claude Code one-ticket engineering workflows.","archived":false,"fork":false,"pushed_at":"2026-06-08T03:32:05.000Z","size":691,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T05:15:51.352Z","etag":null,"topics":["ai-agents","claude-code","cli","developer-tools","human-in-the-loop","typescript","workflow-automation"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/dsj7419.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-05-24T19:29:45.000Z","updated_at":"2026-06-08T03:32:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dsj7419/forge-gate","commit_stats":null,"previous_names":["dsj7419/forge-gate"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dsj7419/forge-gate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsj7419%2Fforge-gate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsj7419%2Fforge-gate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsj7419%2Fforge-gate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsj7419%2Fforge-gate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsj7419","download_url":"https://codeload.github.com/dsj7419/forge-gate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsj7419%2Fforge-gate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34137570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["ai-agents","claude-code","cli","developer-tools","human-in-the-loop","typescript","workflow-automation"],"created_at":"2026-06-10T05:01:38.052Z","updated_at":"2026-06-10T05:01:39.061Z","avatar_url":"https://github.com/dsj7419.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ForgeGate\n\n\u003e **A control system for Claude Code.** It lets AI help build software quickly, but with guardrails:\n\u003e one task at a time, clear boundaries, required tests, independent review, and human approval before\n\u003e anything important is committed or merged.\n\n[![CI](https://github.com/dsj7419/forge-gate/actions/workflows/ci.yml/badge.svg)](https://github.com/dsj7419/forge-gate/actions/workflows/ci.yml)\n![Node](https://img.shields.io/badge/node-%3E%3D22-brightgreen)\n![Tests](https://img.shields.io/badge/tests-624%20passing-brightgreen)\n![License](https://img.shields.io/badge/license-MIT-blue.svg)\n![Status](https://img.shields.io/badge/status-MVP%20%C2%B7%20human--gated-orange)\n\n---\n\n## What is ForgeGate?\n\nForgeGate is a **safety and project-management layer for Claude Code**. Instead of asking an AI to write\ncode and hoping it behaves, ForgeGate turns the work into a controlled process: **define the task, set the\nboundaries, have the AI do the work, then require independent review, testing, and human approval before\nanything important happens.**\n\nIt is built for people who want the speed of AI-assisted coding without losing control. ForgeGate keeps the\nAI focused on **one approved task at a time**, prevents it from wandering into unrelated files, records what\nhappened, runs the checks itself, and **stops at the right gates** before commits, pull requests, or merges.\n\nIn plain English: it makes Claude Code act less like a loose chatbot and more like a disciplined engineering\nteam — developer, reviewer, scope/safety officer, and project manager — with an approval process built in.\nThe goal is not just faster coding; it is **trustworthy AI-assisted software development**: clear scope, clean\nevidence, safer changes, fewer surprises, and a human still in charge of every major decision.\n\n### The two pieces\n\n| | |\n|---|---|\n| **Forge Core** | A deterministic, CLI-first, runtime-agnostic TypeScript engine (`forge-core` package, `forge` binary). It does all the deterministic work — contract validation, ticket selection, path fences, schema-validated agent I/O, decision provenance, run-report attestation, cross-run locking. **Zero LLM/prompt logic.** It runs from a plain terminal. |\n| **ForgeGate** | The Claude Code surface on top of Core: thin slash-command wrappers, the agent charters, and the interactive one-ticket orchestrators. The wrappers add no logic; the orchestrator is *mechanical* (it dispatches agents, runs Core, does git, pauses at gates) and makes no code judgments of its own. |\n\n\u003e **The contract is one-directional: Claude Code consumes Forge Core, never the reverse.** Core is the source\n\u003e of truth; the AI surface is a convenience layer over it.\n\n---\n\n## The governed loop\n\nOne ticket flows through a fixed pipeline and stops at the commit gate. Nothing is improvised, and the\norchestrator trusts Core's verdicts — never an agent's narrative.\n\n```mermaid\nflowchart TD\n    A[Preflight: validate + dry-run + clean-tree] --\u003e L{forge lock acquire\u003cbr/\u003eatomic, owner-keyed}\n    L -- LOCK_HELD / LOCK_MALFORMED --\u003e X[Stop before any mutation]\n    L -- acquired --\u003e B[Emit Core-owned active-ticket fence]\n    B --\u003e C[Branch + checkpoint]\n    C --\u003e D[Engineer: TDD, edits only allowed_paths]\n    D --\u003e E[Independent verify: run the ticket's verify_commands]\n    E --\u003e F[Scope guard: diff vs the path fence]\n    F --\u003e G[Semantic verifier + Scope verifier]\n    G --\u003e H[PM: PASS / CORRECT / ESCALATE\u003cbr/\u003eCore-pinned decision_id]\n    H -- CORRECT (cap 3, lock held) --\u003e D\n    H -- PASS --\u003e I[Ledger append -\u003e run-report -\u003e owner-checked release]\n    H -- ESCALATE --\u003e J[Evidence run-report -\u003e owner-checked release]\n    I --\u003e K[Commit gate: handoff + STOP. No commit.]\n    J --\u003e Y[Recovery brief + STOP. Evidence preserved.]\n```\n\nEvery agent output is **captured verbatim and validated by Core** (`forge parse-agent`) before the run\ncontinues — malformed output halts, it is never repaired. The PM's `decision_id` is **assigned by Core** from\na per-epic ledger and cross-checked, so it can't be invented or duplicated. On PASS the run produces a\nCore-owned, schema-validated `forge-run-report/v1` whose safety fields are typed `false`, then **stops for a\nhuman**.\n\n---\n\n## Architecture\n\n```mermaid\nflowchart LR\n    subgraph CC[Claude Code surface]\n      W1[/forge-run-ticket/]\n      WF[workflow-backed runner]\n      CMDS[thin wrappers:\u003cbr/\u003evalidate / status / import / dry-run]\n      HOOK[four-class permissions hook]\n    end\n    subgraph CORE[Forge Core — deterministic CLI]\n      SCHEMA[schema + validate]\n      ORCH[orchestrator: packets / dispatch / decision-id / lock / ledger]\n      AGENTS[agent-output validate + ingest]\n      GUARD[path-fence guard]\n      RR[run-report v1]\n    end\n    W1 --\u003e CORE\n    WF --\u003e CORE\n    CMDS --\u003e CORE\n    HOOK -. governs Bash git/gh .-\u003e W1\n    HOOK -. governs Bash git/gh .-\u003e WF\n```\n\n**Core vs. orchestrator** is the load-bearing split. Core (`src/`) is deterministic, typed, unit-tested\nTypeScript. The orchestrators (a Markdown command and a workflow script) are the only components that dispatch\nagents, run git, and pause at gates — and they own **no** governance logic: no gate computation, no\ndecision-id assignment, no schema validation, no path-fence decisions, no safety attestation. They call Core\nfor all of it.\n\n**Two repos, kept distinct.** `FORGE_REPO` locates the CLI; the **target repo** (the project being modified)\nis resolved from the Claude Code session's git root and pinned via `--repo-root`. They coincide only for\nForgeGate self-runs; for any other project they differ, which is what makes ForgeGate usable on external repos.\n\n---\n\n## What's shipped\n\nEverything below exists today, is unit-tested (**624 tests / 40 files, green in CI**), and has been exercised\nthrough the governed loop.\n\n### Governance engine (Forge Core)\n- **Contract model** — epic / sprint / ticket as YAML + Markdown, with strict Zod schemas at every boundary.\n- **`validate`** — read-only contract integrity + readiness + auto-escalation checks. A hard precondition for execution; modifies nothing.\n- **`run --dry-run`** — selects the next ready ticket and reports gate, branch, dependency reasoning, and escalation state. Read-only.\n- **`active-ticket`** — emits the Core-owned `forge-active-ticket/v1` fence (absolute repo_root, paths, branch) that the guard and run-report consume.\n- **`packets` / `dispatch`** — deterministic per-role dispatch context and specs for engineer, semantic verifier, scope verifier, and PM. Registered subagent type when available; verbatim injected-charter fallback otherwise — never an improvised prompt.\n- **`parse-agent`** — validates structured agent output (YAML *or* JSON) against the role schema. Malformed output is rejected, never repaired.\n- **Core-pinned `decision_id`** — assigned monotonically from a per-epic ledger; the PM echoes it verbatim and Core cross-checks. Duplication and renumbering are structurally impossible.\n- **`run-report write`** — Core-owned `forge-run-report/v1`. Safety fields (`committed`, `pushed`, `pr_opened`, `merged`, `status_write_back`, `journal_written`) are typed `z.literal(false)` — the v1 thesis lives in the type system, so it can't be flipped without a v2 bump.\n- **`importer`** — normalizes a legacy sprint folder into the canonical contract; writes `TODO` placeholders rather than inventing ambiguous fields (a human-completion draft).\n\n### Agent workflow\n- **One governed self-run** — engineer → independent verify → scope guard → semantic verifier → scope verifier → PM, stopping at the commit gate.\n- **Verbatim capture protocol** — one action per step: dispatch → wait → capture byte-for-byte → `parse-agent` → continue only on success. No pre-writing, summarizing, reconstructing, composing, or batching. Lock-tested so the discipline can't silently drift.\n- **Independent verification** — the orchestrator re-runs the ticket's `verify_commands` itself; it never trusts the engineer's claim.\n- **Anti-theater verifiers** — verdicts must cite concrete evidence; \"looks good\" is invalid; the PM may not PASS over a REJECT without a recorded override + human escalation.\n\n### Permissions substrate (the prevent layer)\n- **Four-class Claude Code permissions hook** (PreToolUse, Bash) — judges every git/gh command by intent:\n  - **Class 1 — read-only / local git** → allow (`status`, `diff`, `log`, `show`, `rev-parse`, branch list, `fetch`, `pull --ff-only`, `switch \u003cbranch\u003e`).\n  - **Class 2 — explicit-path staging** → allow (`git add \u003cpath\u003e`; `.`/`-A`/glob denied).\n  - **Class 3 — reversible PR workflow** → allow (`git push -u origin \u003cfeature-branch\u003e`, `gh pr create|view|checks`).\n  - **Class 4 — destructive / outward / approval-gated** → deny (force-push, push-to-main, `reset --hard`, branch delete, `merge`/`rebase`, `gh pr merge`, `gh api` mutation, `restore`/`checkout -- \u003cpath\u003e`, `clean`, and any complex/dynamic/obfuscated git/gh form). Non-git/gh commands pass through. **Fail-closed.**\n  - A `forge-*` runner agent is restricted to **read-only git only** (L3).\n- **Human bypass is explicit:** `!`-prefixed commands run in the human's own shell and bypass the agent hook — that *is* the human gate for commit / branch-create / merge.\n\n### Cross-run concurrency (epic locking)\n- **Core epic-lock primitive** — atomic exclusive-create (`O_EXCL` / `wx`): the create *is* the mutual exclusion, so there is no check-then-act TOCTOU. Typed `forge-lock/v1` record keyed by `run_id`.\n- **`forge lock acquire | release | status`** — real `defaultLockIo` filesystem binding; owner-checked release; report-only stale verdict (never clears or steals); malformed locks fail closed.\n- **Both orchestrators are wired to it** — the command runner (`/forge-run-ticket`) and the workflow-backed runner both acquire before any mutation, hold across correction cycles, and release owner-checked on PASS / terminal outcomes.\n- **Atomic / CAS decisions-ledger append** — defense-in-depth: ledger appends can't duplicate or clobber decisions under concurrent interleavings, even if the lock is bypassed.\n\n### Human-gated delivery\n- **Stops at the commit gate.** On PASS it prints the handoff (changed files, verification summary, PM decision, a *proposed* status transition, a suggested commit message and `git add`/`git commit`) and stops. It never commits.\n- **No auto push / PR / merge. No status write-back. No journal write.** All deliberately out of scope for v1.\n- **Failed runs preserve evidence** — write the run-report, leave branch + tree intact, produce a recovery brief with *suggested* (not executed) cleanup.\n\n### CI / green-tree protection\n- **GitHub Actions CI** on every PR and push to `main` — Node 22, pinned `pnpm@10.33.0`, frozen install → typecheck → test. The green-tree invariant is machine-backed.\n\n---\n\n## Quickstart\n\n```bash\npnpm install\npnpm build\nnode dist/cli.js validate docs/epics/forge-self-improvement      # read-only contract validation\nnode dist/cli.js run docs/epics/forge-self-improvement --dry-run  # preview the next ready ticket\n```\n\nThe CLI subcommands are read-only and safe from a plain terminal. For the full orchestration loop, run\n`/forge-run-ticket \u003cepic-path\u003e` **inside Claude Code** — the interactive entry point that dispatches the agents\nand pauses at the commit gate.\n\n---\n\n## Command reference\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eFull \u003ccode\u003eforge\u003c/code\u003e CLI surface\u003c/strong\u003e (click to expand)\u003c/summary\u003e\n\n```\nforge validate \u003cepic-path\u003e [--json]            Read-only contract validation. Default mode writes\n                                               .forge/validation-report.json; --json prints JSON, writes nothing.\n\nforge status \u003cepic-path\u003e                       Summarize epic id, sprint ids, ticket counts, finding totals.\n\nforge run \u003cepic-path\u003e --dry-run [--json]       Read-only execution preview: next ready ticket, dependency\n                                               reasoning, paths, verify commands, effective gate, proposed\n                                               branch, and the agent chain that WOULD run. (Live run is the\n                                               orchestrator's job, not a CLI subcommand.)\n\nforge import --from-existing \u003clegacy\u003e --out \u003cepic-root\u003e [--dry-run] [--json]\n                                               Normalize a legacy sprint folder into the canonical contract.\n                                               Output dir must be empty/absent (no --force). Source untouched.\n\nforge packets \u003cepic-path\u003e [--repo-root \u003cp\u003e]    Deterministic run-packet set for the next ready ticket.\n\nforge dispatch \u003cengineer|semantic-verifier|scope-verifier\u003e \u003cepic-path\u003e [--repo-root \u003cp\u003e]\n                                               Build one agent's dispatch spec {role, subagent_type, mode, prompt}.\nforge dispatch pm \u003cepic-path\u003e [--assigned-decision-id \u003cD-NNN\u003e] [--engineer-output \u003cf\u003e --semantic-output \u003cf\u003e\n                              --scope-output \u003cf\u003e --facts \u003cf.json\u003e] [--repo-root \u003cp\u003e]\n                                               Re-validate upstream outputs + facts, embed them verbatim, and\n                                               render the Core-pinned decision_id into the PM prompt.\n\nforge ledger append \u003cepic\u003e --decision-id \u003cD-NNN\u003e --ticket \u003cticket\u003e --branch \u003cbranch\u003e\n                                               Atomic/CAS append to the per-epic decisions ledger.\n\nforge lock acquire \u003cepic\u003e --run-id \u003cid\u003e --session-id \u003cs\u003e --ticket \u003ct\u003e --branch \u003cb\u003e --repo-root \u003cr\u003e\nforge lock release \u003cepic\u003e --run-id \u003cid\u003e\nforge lock status  \u003cepic\u003e [--heartbeat-ttl-ms \u003cn\u003e] [--acquire-ttl-ms \u003cn\u003e]\n                                               Cross-run epic lock. Acquire = atomic exclusive-create\n                                               (LOCK_HELD on collision, never overwrites). Release = owner-checked\n                                               by run_id (LOCK_FOREIGN/LOCK_ABSENT). Status = report-only stale\n                                               verdict (never clears or steals). Fail-closed throughout.\n\nforge parse-agent \u003crole\u003e (--file \u003cp\u003e | --stdin | --json-file \u003cp\u003e | --json-stdin) [--expected-decision-id \u003cD-NNN\u003e]\n                                               Validate structured agent output against the role schema.\nforge agent-schema \u003crole\u003e                      Emit the JSON Schema for a role's structured output.\n\nforge active-ticket \u003cepic-path\u003e [--json] [--repo-root \u003cp\u003e]\n                                               Emit the Core-owned forge-active-ticket/v1 fence.\n\nforge guard paths [--active \u003cactive-ticket.json\u003e] [--json] [--repo-root \u003cp\u003e]\n                                               Deterministic, read-only check that the worktree stays inside the\n                                               active ticket's fence. Exit 0 inside, 1 on violation, 2 usage.\n\nforge run-report write \u003cepic-path\u003e --repo-root \u003cp\u003e --result PASS|ESCALATE --ticket-title \u003cs\u003e\n                       --checkpoint-base \u003csha\u003e --checkpoint-head \u003csha\u003e --guard-result \u003cs\u003e --guard-exit \u003cn\u003e\n                       --gate-declared \u003cg\u003e --gate-effective \u003cg\u003e --gate-human-required \u003ctrue|false\u003e [...]\n                                               Write the Core-owned forge-run-report/v1 (safety fields typed false).\n\nforge verify-install                           Read-only install-currency check: compare this checkout's\n                                               commands/ + agents/ against the installed copies under ~/.claude.\n```\n\n**Exit codes:** `0` success · `1` failure (findings, blocked dry-run, invalid agent output, guard violation, write failure) · `2` usage error.\n\n\u003c/details\u003e\n\n| Slash command | Runs |\n|---|---|\n| `/forge-validate \u003cepic-path\u003e` | `forge validate` |\n| `/forge-status \u003cepic-path\u003e` | `forge status` |\n| `/forge-import --from-existing \u003clegacy\u003e --out \u003cepic-root\u003e [--dry-run]` | `forge import …` |\n| `/forge-run-dry-run \u003cepic-path\u003e` | `forge run … --dry-run` |\n| `/forge-run-ticket \u003cepic-path\u003e` | Orchestrates ONE ticket (engineer → verifiers → PM); stops at the commit gate |\n\n---\n\n## The v1 safety model\n\nForge v1 is intentionally conservative and human-gated. The guarantees:\n\n- **One ticket per run.** Exactly one ready ticket is selected and run.\n- **Stops at the commit gate.** It never commits, pushes, opens a PR, or merges.\n- **No status write-back, no journal write.** A run never mutates the contract's ticket status or `JOURNAL.md`/`DECISIONS.md`. *(Completed tickets may still read `status: pending` on disk — expected for now; trust git/PRs for ground truth.)*\n- **The engineer edits only `allowed_paths`.** The diff is independently scope-checked against the fence.\n- **`.forge/` runtime artifacts are gitignored** (`active-ticket.json`, `lock.json`, `run-report.json`, `decisions-ledger.json`, captured agent outputs, reports).\n- **Cross-run serialization by epic lock.** A second run on the same epic fails closed at the atomic acquire, before any mutation.\n- **Failed runs preserve evidence** and leave the tree intact.\n\n### How \"safe\" is enforced — be precise\n\nForgeGate's safety comes from **distinct layers**, and it's worth knowing which *prevents* vs. which *detects*:\n\n| Layer | Mechanism | Guarantee |\n|---|---|---|\n| **Core** | typed schemas, pinned decision_id, `safety.*` literal-false, run-report attestation | **validates \u0026 attests** — improvisation is rejected at parse time |\n| **Path-fence guard** | deterministic diff-vs-fence check | **detects** scope violations and fails the run (post-hoc, not a hard block on the edit) |\n| **Permissions hook** | PreToolUse Bash classifier | **prevents** unsafe substrate actions (git/gh) at the tool boundary; reloads on settings change; `!` is the human bypass |\n| **Orchestration discipline** | instruction + protocol-lock tests + disclosed-departure | **constrains** the runner; not structurally enforced by Core — a determined operator could deviate, but the lock tests keep the written discipline from silently disappearing |\n\nThe honest one-liner: **Core attests, the guard detects, the permissions hook prevents, and the human approves.**\nNo layer here claims full autonomy or unsupervised readiness.\n\n### Not autonomous / not magic\n\nForge **structures** Claude Code work and enforces discipline; it does **not** take over responsibility. The\nhuman stays accountable for what gets committed, pushed, or merged. v1 always stops at the commit gate.\n\n---\n\n## Cross-run concurrency \u0026 locking\n\nTwo runs on the same epic must not both proceed — they would race on the decisions ledger and overwrite each\nother's evidence. ForgeGate closes this with a Core-owned **epic lock**:\n\n- **Acquire is the gate.** `forge lock acquire` atomically creates `\u003cepic\u003e/.forge/lock.json` (`O_EXCL`/`wx`).\n  The create *is* the mutual exclusion — there is no separate existence check, so no check-then-act window. A\n  collision returns `LOCK_HELD` and **never overwrites** the holder.\n- **Release is owner-checked.** Only the run that holds the matching `run_id` can release; a foreign/absent/\n  malformed result is reported, **never force-cleared**.\n- **Both orchestrators are serialized by it** — the command runner and the workflow-backed runner acquire\n  before any mutation (active-ticket emission, checkpoint, dispatch), hold across all correction cycles, and\n  release on PASS or terminal outcome.\n- **The CAS ledger append is defense-in-depth** — even if the lock were bypassed, a decision can't be\n  duplicated or clobbered. With both runners holding the lock, this backstop sits behind real primary\n  serialization.\n- **Stale recovery is deliberately not automated.** `forge lock status` *reports* a stale/foreign/malformed\n  verdict; nothing clears, breaks, or steals a lock. A human-gated recovery path is future work.\n\n\u003e **Honest status:** the workflow runner's lock wiring is **wired and lock-tested**, and the command runner has\n\u003e exercised real acquire/release **live**. The workflow runner's first full **end-to-end live** proof (real\n\u003e lock through its own harness with real agents) is still pending — see the roadmap.\n\n---\n\n## Install \u0026 setup\n\nForgeGate is installed from a checkout — there is no published package yet. Both setup lanes end with a\n**verify-install currency check**; the install is \"done\" only once the installed `~/.claude` copies are\nconfirmed current.\n\n```bash\n# Clone (or pull an existing checkout), then:\npnpm install\npnpm build                          # emit dist/\npnpm install-commands               # commands/*.md → ~/.claude/commands/, agents/*.md → ~/.claude/agents/\nnode dist/cli.js verify-install     # confirm installed copies match this checkout (exit 0 = current)\nexport FORGE_REPO=$(pwd)            # PowerShell: setx FORGE_REPO \"\u003cpath\u003e\"\n```\n\nIf `verify-install` reports any file `stale`/`missing`, re-run `pnpm install-commands` then re-check. See\n[`docs/adopting-forgegate-in-a-project.md`](docs/adopting-forgegate-in-a-project.md) for using ForgeGate\nagainst an external repo.\n\n**CLI resolution.** Each wrapper invokes `node \"${FORGE_REPO}/scripts/run-forge-cli.mjs\" \u003csubcommand\u003e`, which\nresolves the CLI as: `$FORGE_BIN` → `forge` on `PATH` → local-dev `pnpm -C \u003crepo\u003e forge`. Set `FORGE_REPO`\n(or `pnpm link --global`) so the wrappers can find the CLI. `FORGE_REPO` only *locates* the CLI — it is never\nthe project a ticket modifies.\n\n### Develop\n\n```bash\npnpm install\npnpm typecheck\npnpm test\npnpm build\npnpm forge validate \u003cepic-path\u003e             # dev run via tsx\nnode dist/cli.js validate \u003cepic-path\u003e       # built binary\n```\n\n---\n\n## Agent charters\n\nThe Forge roles are Claude Code subagent charters in `agents/` (installed to `~/.claude/agents/`). They declare\nthe human/agent contract: role, inputs, governance to read, hard prohibitions, a **structured output schema**,\nescalation behavior, and anti-theater rules.\n\n| Charter | Role | Edits code? | Decides? |\n|---|---|---|---|\n| `forge-engineer` | Implements one ticket, TDD, within allowed paths | yes (allowed paths only) | no |\n| `forge-semantic-verifier` | Verifies acceptance is genuinely met vs. repo reality | no (read-only) | verdict only |\n| `forge-scope-verifier` | Verifies the diff stays inside the path fences | no (read-only) | verdict only |\n| `forge-pm` | Synthesizes outputs; decides PASS / CORRECT / ESCALATE | no | yes |\n| `forge-core-runner` | Typed bridge for the workflow runner to reach Core/git (read-only git only, L3) | no | no |\n\n**Dispatch model.** When the harness exposes registered `forge-\u003crole\u003e` subagent types, dispatch uses them\ndirectly (`mode: registered`). Otherwise it falls back to the general-purpose agent with the tracked charter\ninjected verbatim (`mode: injected-charter`) — never an improvised prompt. Either way the prompt pins\n`repo_root` and cwd discipline.\n\n---\n\n## Roadmap\n\nSequenced roughly by priority. Nothing here is committed; it's the honest \"what's next.\"\n\n### Near-term — close the concurrency story\n- **First live workflow-runner proof** — exercise the workflow runner end-to-end through its harness with real agents and a real lock (wiring is in place and lock-tested; live proof pending).\n- **Stale-lock recovery UX** — `forge lock status` already diagnoses stale/foreign/malformed; add a human-gated, owner-aware recovery path with strong safety controls (no silent break/steal).\n- **Evidence ownership / `run_id` enforcement** — tie active-ticket, run-report, orchestrator-facts, and captured evidence to the owning run.\n- **Worktree / shared-state architecture** — prevent per-worktree `.forge` state from fragmenting shared lock/ledger provenance.\n\n### Delivery \u0026 automation\n- **Sentinel-gated `gh pr merge`** — an approval-file-gated merge path in its own ticket (deferred follow-up).\n- **Command/workflow parity review** and a better launcher for workflow runs (run identity, pre-branch serialization).\n\n### Adoption \u0026 operations\n- **External-repo pilot sequence** once concurrency is fully closed.\n- **Operator guides** — permissions-hook behavior; \"how to recover from lock held / malformed / stale\" (after stale UX exists).\n- **Install/update lifecycle** for commands, agents, and (if they become installable) workflows.\n\n### Developer experience\n- **Escalation keyword matcher** — make it negation-aware so harmless prose (\"do not delete X\") doesn't trip auto-escalation.\n- **Tighter protocol tests** where command/workflow behavior lives in Markdown or workflow JS.\n- **Reduce friction** around hook-denied-but-safe operations without weakening the safety model.\n- Continue adopting Claude Code primitives (subagents, skills, hooks, permissions, typed workflow schemas) **only where they measurably improve safety** — MCP / Agent SDK only if they add controlled, deterministic value, not novelty.\n\n### Explicitly out of scope for v1\nFull autonomy, auto-commit/push/PR/merge, status write-back, journal automation, multi-ticket loops, and any\norchestrator autonomy without explicit human approval. Each needs a deliberate scope discussion before it\nbecomes real.\n\n---\n\n## Design docs\n\nThe reasoning behind the system lives in [`docs/`](docs/). Key entry points:\n\n- [`one-ticket-orchestration-design.md`](docs/one-ticket-orchestration-design.md) — the core orchestration design.\n- [`forge-run-ticket-design.md`](docs/forge-run-ticket-design.md) — the interactive command runner.\n- [`path-fence-guard.md`](docs/path-fence-guard.md) — the deterministic scope guard + example git hook.\n- [`cross-run-concurrency-discovery.md`](docs/cross-run-concurrency-discovery.md) — the locking/ledger trust seam.\n- [`workflow-backed-runner-design.md`](docs/workflow-backed-runner-design.md) · [`workflow-era-architecture-audit.md`](docs/workflow-era-architecture-audit.md) — the workflow runner and how it relates to the command runner.\n- [`permissions-policy-discovery.md`](docs/permissions-policy-discovery.md) — the four-class permissions model.\n- [`adopting-forgegate-in-a-project.md`](docs/adopting-forgegate-in-a-project.md) — running ForgeGate against an external repo.\n\nEpic contracts (the system dogfooding itself) live under [`docs/epics/`](docs/epics/).\n\n---\n\n## Principles\n\n- The core is real, typed, unit-tested code — never prompt logic.\n- `forge validate` is a hard, read-only precondition for any execution.\n- One responsibility per module (`schema`, `validate/*`, `orchestrator/*`, `guard`, `run-report`, `cli`).\n- Schemas at trust boundaries; types inside. Determinism is sacred — Core never invents metadata, repairs agent output, or auto-commits.\n- Honest over impressive: an `ESCALATE` with preserved evidence beats a forced green. The README does not overclaim, by design.\n\n---\n\n## License\n\n[MIT](LICENSE) © ForgeGate contributors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsj7419%2Fforge-gate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsj7419%2Fforge-gate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsj7419%2Fforge-gate/lists"}