{"id":49309270,"url":"https://github.com/lannguyensi/harness","last_synced_at":"2026-05-15T19:01:45.131Z","repository":{"id":353324766,"uuid":"1218917765","full_name":"LanNguyenSi/harness","owner":"LanNguyenSi","description":"Declarative control plane for agent harnesses: one YAML for grounding, tools, memory, and hooks. Describe, validate, diff, apply.","archived":false,"fork":false,"pushed_at":"2026-05-14T06:11:08.000Z","size":1050,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-14T07:34:13.497Z","etag":null,"topics":["ai-agents","claude-code","control-plane","declarative","dx","harness","yaml"],"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/LanNguyenSi.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-23T10:48:19.000Z","updated_at":"2026-05-14T06:11:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/LanNguyenSi/harness","commit_stats":null,"previous_names":["lannguyensi/harness"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/LanNguyenSi/harness","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanNguyenSi%2Fharness","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanNguyenSi%2Fharness/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanNguyenSi%2Fharness/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanNguyenSi%2Fharness/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LanNguyenSi","download_url":"https://codeload.github.com/LanNguyenSi/harness/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanNguyenSi%2Fharness/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33075225,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["ai-agents","claude-code","control-plane","declarative","dx","harness","yaml"],"created_at":"2026-04-26T11:30:49.122Z","updated_at":"2026-05-15T19:01:45.125Z","avatar_url":"https://github.com/LanNguyenSi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# harness\n\n**Declarative control plane for agent harnesses.**\n\nOne zod-validated YAML manifest for grounding, tools, memory, hooks,\npolicies, and workflows, plus a CLI that describes, validates, diffs,\napplies, audits, and *enforces*.\n\n\u003e Most config tools tell you what an agent is configured to use.\n\u003e `harness` tells you what an agent is *allowed to do*, under this\n\u003e exact context, and why.\n\n`harness` collapses the six-to-eight surfaces a working agent harness\nleaks across (`settings.json`, `CLAUDE.md`, memory frontmatter, MCP\nregistrations, per-project overrides, hook scripts) into a single\nsource of truth. Today (`v0.9.0`) `harness init --interactive` walks\nnew operators through a guided setup wizard, policies fire end-to-end\nand ship as reusable *Policy Packs*: a\n`mcp__agent-tasks__pull_requests_merge` call against a session\nwithout a `review:${PR_NUMBER}` ledger entry refuses; an `Edit` /\n`apply_patch` against a session without an approved Understanding\nReport refuses; `harness explain --last --trace` shows exactly why.\nThe Understanding Gate ships across both Claude Code and Codex\nruntimes via `harness apply --runtime \u003cclaude-code|codex\u003e`.\n\n## What harness does\n\n```mermaid\nflowchart LR\n    declare[\"1. Declare\u003cbr/\u003e\u003ccode\u003eharness.yaml\u003c/code\u003e\"]\n    apply[\"2. Apply\u003cbr/\u003e\u003ccode\u003eharness apply\u003c/code\u003e\"]\n    enforce[\"3. Enforce\u003cbr/\u003ehooks + policies\u003cbr/\u003eat runtime\"]\n    record[(\"4. Record\u003cbr/\u003eevidence ledger\")]\n    observe[\"5. Observe\u003cbr/\u003e\u003ccode\u003eaudit\u003c/code\u003e / \u003ccode\u003eexplain\u003c/code\u003e /\u003cbr/\u003e\u003ccode\u003esession-export\u003c/code\u003e\"]\n\n    declare --\u003e apply\n    apply --\u003e enforce\n    enforce --\u003e record\n    record --\u003e observe\n    observe -. refine .-\u003e declare\n```\n\nOne manifest declares grounding, tools, memory, hooks, policies, and\nworkflows. `apply` materialises that into the files Claude Code\nactually reads. At runtime, hooks and policies enforce the contract\nand write decision rows to the evidence ledger. The read-side\nsurfaces (`audit`, `explain --trace`, `session-export`) replay those\nrows so you can see what fired, why, and across which session.\nWhatever you learn from observing flows back into the manifest. That\nloop is the whole product.\n\n## Pick your audience\n\n- **Operator?** Read [`docs/for-humans.md`](docs/for-humans.md). It\n  walks from `npm i -g @lannguyensi/harness` through your first\n  `apply`, your first real policy, and the diagnostics cheat sheet.\n- **Agent (or onboarding one)?** Read\n  [`docs/for-agents.md`](docs/for-agents.md). It defines the\n  workflow lifecycle, the policy / ledger sequence, the CLI cheat\n  sheet split by side-effect class, and the audit triumvirate\n  (`audit` vs `explain --trace` vs `session-export`).\n\n## Install\n\n```bash\nnpm i -g @lannguyensi/harness\n```\n\nThe CLI binary is `harness`. Node 20 or newer required.\n\n## First-time setup\n\n```bash\nharness init --interactive\n```\n\nGuided wizard that detects your environment (existing `~/.claude/` and\n`~/.codex/`, MCP servers already wired in `settings.json`, harness\nbinary version), picks a profile (`solo` / `team` / `custom`), and\nwrites a starting `harness.yaml`. Ctrl-C at any prompt aborts with no\npartial write. Walkthrough + limitations: `docs/init-interactive.md`.\n\nIf you prefer non-interactive (CI, fresh-VM provisioning), pick a\ntemplate directly:\n\n```bash\nharness init --template solo   # memory-router + understanding-before-execution pack\nharness init --template team   # solo + agent-tasks MCP + review-before-merge policy\nharness init --template full   # everything from the Appendix A reference manifest\n```\n\nDebug what the harness sees in your env without writing anything:\n\n```bash\nharness init --probe   # JSON snapshot of detected runtimes + MCPs + manifest\n```\n\n## Try it in 60 seconds\n\n```bash\ngit clone https://github.com/LanNguyenSi/harness \u0026\u0026 cd harness\nnpm install \u0026\u0026 npm run build\nnode dist/cli/main.js dry-run \"merge PR 42\" \\\n  --tool mcp__agent-tasks__pull_requests_merge \\\n  --tool-args '{\"prNumber\":42}' \\\n  --config docs/examples/full-manifest.yaml\n```\n\n`dry-run` reads the reference manifest, runs the trigger matcher,\nsubstitutes `${PR_NUMBER}=42` through the JSONPath-restricted extract\nDSL, and tells you exactly which hooks would fire and which policies\nwould match, before any ledger I/O.\n\nConvinced? Install globally and set up your own:\n`npm i -g @lannguyensi/harness \u0026\u0026 harness init --interactive`.\n\n## Status\n\n- [x] Phase 1, read-only inventory (`describe`, `validate`, `doctor`,\n      `list`, `explain`, `diff`), released as\n      [`v0.1.0`](CHANGELOG.md#010---2026-04-29).\n- [x] Phase 2, managed edits (`init`, `add`, `remove`, `adopt`,\n      `export`), released as [`v0.2.0`](CHANGELOG.md#020---2026-04-29).\n- [x] Phase 3, declarative truth (`apply`, `diff --since-apply`,\n      `harness.lock`), released as\n      [`v0.3.0`](CHANGELOG.md#030---2026-04-30).\n- [x] Phase 4, policy layer (`policy intercept`, `explain --trace`,\n      `audit`, `dry-run`, requires-evaluator + extract DSL +\n      grounding-mcp adapter), released as\n      [`v0.4.0`](CHANGELOG.md#040---2026-04-30).\n- [x] Phase 5, polish + dogfood lessons (`--verbose` policy\n      diagnostics, `$CLAUDE_SESSION_ID` env fallback, server-side\n      `audit` filter pushdown, `policy_decision` first-class entry\n      type, npm distribution as `@lannguyensi/harness`), released as\n      [`v0.5.0`](CHANGELOG.md#050---2026-05-01).\n- [x] Apply-into-settings cycle, `harness adopt`, `apply --target /\n      --merge`, `harness.lock` target tracking, released as\n      [`v0.6.0`](CHANGELOG.md#060---2026-05-03).\n- [x] Workflows-as-data + full-session audit forensics: additive\n      `workflows:` / `review_templates:` / `audit.redact[]` manifest\n      blocks, `harness session-export`, `explain --last`, audience-\n      specific docs surfaces, released as\n      [`v0.7.0`](CHANGELOG.md#070---2026-05-06).\n- [x] Phase 6, Understanding Gate Policy Pack: `policy_packs:`\n      manifest block, the canonical `understanding-before-execution`\n      pack, `harness pack add / remove / list`,\n      `harness apply --runtime \u003cclaude-code|codex\u003e` with TOML config\n      output for Codex, three permission profiles\n      (`safe-start` / `implementation-after-approval` /\n      `high-risk-grill-me`), a harness-side PreToolUse blocker that\n      consults both the evidence-ledger tag and the persisted JSON\n      report, `harness approve understanding`,\n      `harness doctor --target codex`, and a Codex Stop-equivalent\n      that captures Understanding Reports into\n      `.understanding-gate/reports/`. Released as\n      [`v0.8.0`](CHANGELOG.md#080---2026-05-10).\n- [ ] Phase 7, Risk Gate: Action Envelope + Risk Classifier +\n      `allow / warn / require_approval / deny` for destructive-action\n      prevention.\n\n## Policy Packs (v0.9.0)\n\nA *Policy Pack* is a reusable bundle of instruction template, hooks,\npolicies, and permission profiles that ships under one name and is\nreferenced from `harness.yaml` with a single key. The first pack,\n`understanding-before-execution`, forces agents to expose and confirm\ntheir task interpretation before any write-capable tool fires.\n\n```yaml\npolicy_packs:\n  - name: understanding-before-execution\n    config:\n      mode: grill_me                       # fast_confirm | grill_me | strict\n      permission_profile: safe-start       # safe-start | implementation-after-approval | high-risk-grill-me\n```\n\nManage packs with `harness pack add / remove / list`. Apply against\neither runtime:\n\n```sh\nharness apply --runtime claude-code        # default; writes harness.generated/settings.json\nharness apply --runtime codex              # writes harness.generated/codex/config.toml\n```\n\nApprove a session's Understanding Report via\n`harness approve understanding --session \u003cid\u003e` (round-trips both the\nevidence-ledger tag and the persisted JSON report). Verify the\nadapter wiring with `harness doctor --target codex` (`--json` for\nmachine-readable). The full reference lives in\n[`docs/policy-packs/understanding-before-execution.md`](docs/policy-packs/understanding-before-execution.md);\nsynthetic-stdin dogfood under\n[`dogfood/phase6-6/`](dogfood/phase6-6/run-smoke.sh) exercises the\nblock / allow / capture / approve round-trip without a real Codex\nbinary.\n\n## What's next\n\n**Phase 7, Risk Gate.** Today's policy model evaluates a rule per\nmatching trigger and returns a binary block/allow. Phase 7 makes\nharness reason about *the action itself*: an Action Envelope (tool +\nraw input + session + runtime context) is enriched by a Context\nResolver (production / staging / dev / unknown), classified by a Risk\nClassifier (severity + categories + reversibility), then matched\nagainst policies whose `when:` clauses can reference\n`risk.severity_at_least`, `environment.name`, and similar. The\ndecision space extends to `allow / warn / require_approval / deny`.\nMotivating use case: prevent `DROP TABLE users`, `kubectl delete\nnamespace prod`, `terraform destroy` against an unverified production\ntarget, even if the model would have happily run them.\n\nPhase 7 builds on Phase 4's `policy intercept` runtime backbone and\nPhase 6's Policy Pack distribution surface; neither is replaced.\n\n\u003e Bring your favorite agent harness. Add governance.\n\n## Why this exists\n\nA working agent harness today has six to eight configuration\nsurfaces, each with its own schema and lifecycle: `~/.claude/settings.json`,\n`CLAUDE.md` (per repo + root), `~/.claude/projects/*/memory/*.md`\nwith frontmatter, `~/.claude/keybindings.json`, MCP server\nregistrations in `~/.claude.json`, skill directories, per-project\noverrides, and external CLIs that behave differently per project.\n\nThere is no single place that answers *\"what can this agent do right\nnow, and why is that configured that way?\"*. Drift between sessions\nis invisible until it breaks something. Humans editing one surface\ndo not know which other surfaces they need to touch. A fresh agent\ninstance has no way to audit its own setup.\n\nOur entry point into this problem: on 2026-04-23, an\n`agent-grounding` checkout that was 16 commits behind origin led two\ntasks to be incorrectly called \"stale\". The check that would have\ncaught it already exists,\n[`agent-preflight`](https://github.com/LanNguyenSi/agent-preflight)\nruns `git fetch` + `git status` (alongside lint, typecheck, test,\naudit) and emits a structured `ready` + confidence-score result. The\nmissing piece was not the check itself, it was the deterministic\n*trigger*: a `SessionStart` hook that invokes `preflight run` and a\npolicy that gates further work on the result. Building that wiring\nneeds an agreed-upon place for harness config to live first. That\nconversation is the origin of this repo.\n\n## Related\n\n- [`agent-grounding`](https://github.com/LanNguyenSi/agent-grounding):\n  grounding primitives (evidence-ledger, claim-gate,\n  review-claim-gate); `grounding-mcp` is the canonical client surface\n  harness queries through `queryLedgerByTag`.\n- [`agent-memory`](https://github.com/LanNguyenSi/agent-memory):\n  memory surfaces the control plane inventories.\n- [`agent-tasks`](https://github.com/LanNguyenSi/agent-tasks): the\n  MCP-registered task platform whose registration + health appear in\n  `harness describe`.\n- [`agent-preflight`](https://github.com/LanNguyenSi/agent-preflight):\n  local preflight validator; the canonical implementation of\n  preflight-hook content harness wires.\n- [`codebase-oracle`](https://github.com/LanNguyenSi/codebase-oracle):\n  one of the MCP surfaces being registered.\n- [`agent-dx`](https://github.com/LanNguyenSi/agent-dx): ships\n  `git-batch-cli`, a day-to-day tool whose inventory appears in\n  `harness describe`.\n\n## License\n\nMIT, see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flannguyensi%2Fharness","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flannguyensi%2Fharness","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flannguyensi%2Fharness/lists"}