{"id":47695093,"url":"https://github.com/burin-labs/harn","last_synced_at":"2026-06-17T08:01:10.874Z","repository":{"id":347478933,"uuid":"1192706077","full_name":"burin-labs/harn","owner":"burin-labs","description":"A programming language for orchestrating AI agents.","archived":false,"fork":false,"pushed_at":"2026-06-11T17:02:24.000Z","size":64805,"stargazers_count":6,"open_issues_count":9,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T17:12:30.081Z","etag":null,"topics":["acp","agents","ai-agents","language","mcp-client","programming-language","rust","rust-crate"],"latest_commit_sha":null,"homepage":"https://harnlang.com","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/burin-labs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG-pre-0.6.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-26T13:36:25.000Z","updated_at":"2026-06-11T16:57:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"acabedef-a8f4-4464-ac96-3a51ea95c26f","html_url":"https://github.com/burin-labs/harn","commit_stats":null,"previous_names":["burin-labs/harn"],"tags_count":299,"template":false,"template_full_name":null,"purl":"pkg:github/burin-labs/harn","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burin-labs%2Fharn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burin-labs%2Fharn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burin-labs%2Fharn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burin-labs%2Fharn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/burin-labs","download_url":"https://codeload.github.com/burin-labs/harn/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burin-labs%2Fharn/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34341113,"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-14T02:00:07.365Z","response_time":62,"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":["acp","agents","ai-agents","language","mcp-client","programming-language","rust","rust-crate"],"created_at":"2026-04-02T16:21:27.812Z","updated_at":"2026-06-17T08:01:10.866Z","avatar_url":"https://github.com/burin-labs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Harn\n\n[![CI](https://github.com/burin-labs/harn/actions/workflows/ci.yml/badge.svg)](https://github.com/burin-labs/harn/actions/workflows/ci.yml)\n\nHarn is a programming language and runtime for orchestrating AI agents.\nIt sits between product code and provider/runtime code: products declare\nworkflows, policies, capabilities, and UI hooks, while Harn owns transcripts,\ncontext assembly, retries, tool routing, persistence, replay, and provider\nnormalization.\n\nHarn also emits portable `opentrustgraph/v0.1` trust records for autonomy\ndecisions, approval gates, and tier transitions. `v0.1` adds three\nreserved `metadata` keys (`effects_grant`, `effects_used`,\n`parent_record_id`) so chain validators can prove that a child agent's\n`effects_used` stayed inside the parent's `effects_grant`. The public\nschema and fixtures live in [`opentrustgraph-spec/`](./opentrustgraph-spec/).\n\n## Install\n\nOne-line installer (recommended; no Rust toolchain required):\n\n```bash\ncurl -fsSL https://harnlang.com/install.sh | sh\n```\n\nDetects OS/CPU, downloads the matching signed binary for the current\n[GitHub release](https://github.com/burin-labs/harn/releases),\nverifies it against the release's `SHA256SUMS` manifest, and installs\n`harn`, `harn-dap`, and `harn-lsp`. It honors `$HARN_INSTALL_DIR` or\n`$XDG_BIN_DIR` when set, otherwise uses `$HOME/bin` or `$HOME/.local/bin`\nwhen one already exists and is on `PATH`, and falls back to creating\n`$HOME/.harn/bin`. macOS binaries are notarized.\nTo upgrade later: `harn upgrade`.\n\nWith Cargo:\n\n```bash\ncargo install harn-cli\n```\n\nFrom source:\n\n```bash\ngit clone https://github.com/burin-labs/harn.git\ncd harn\n./scripts/dev_setup.sh\ncargo install --path crates/harn-cli\n```\n\nShell completions:\n\n```bash\nmkdir -p ~/.local/share/bash-completion/completions\nharn completions bash \u003e ~/.local/share/bash-completion/completions/harn\n\nmkdir -p ~/.zfunc\nharn completions zsh \u003e ~/.zfunc/_harn\n# Add to ~/.zshrc if needed: fpath=(~/.zfunc $fpath); autoload -Uz compinit; compinit\n\nmkdir -p ~/.config/fish/completions\nharn completions fish \u003e ~/.config/fish/completions/harn.fish\n```\n\nContainer image:\n\n```bash\ndocker run -p 8080:8080 -v $PWD/triggers.toml:/etc/harn/triggers.toml -e HARN_ORCHESTRATOR_API_KEYS=xxx ghcr.io/burin-labs/harn\n```\n\nRelease tags publish multi-arch `linux/amd64` and `linux/arm64` images to\nGHCR. The container defaults to `harn orchestrator serve` with\n`HARN_ORCHESTRATOR_MANIFEST=/etc/harn/triggers.toml` and\n`HARN_ORCHESTRATOR_LISTEN=0.0.0.0:8080`; set\n`HARN_ORCHESTRATOR_API_KEYS` and `HARN_ORCHESTRATOR_HMAC_SECRET` when\nyou expose authenticated `a2a-push` routes, and inject provider secrets\nwith the usual environment variables such as `OPENAI_API_KEY`,\n`ANTHROPIC_API_KEY`, or your deployment's `HARN_PROVIDER_*` /\n`HARN_SECRET_*` values.\n\nCloud deploy templates for Render, Fly.io, and Railway live under\n`deploy/`. To generate a project-local bundle and run the provider CLI:\n\n```bash\nharn orchestrator deploy --provider fly --manifest ./harn.toml --build\n```\n\n## Quick start\n\nRun a bundled demo first. It needs no API keys or project setup:\n\n```bash\nharn demo                       # menu of bundled scenarios\nharn demo merge-captain         # default scenario: persona-supervised PR triage\nharn demo --list                # all scenarios with descriptions\nharn demo provider-race --json  # machine-readable summary\n```\n\nEvery demo runs in under 30 seconds against a checked-in LLM tape, so it\nfinishes the same way on a laptop with zero credentials as it does in\nCI. Add `--live` to re-run against a configured provider.\n\nThen scaffold a project of your own:\n\n```bash\nharn new my-project --template agent\ncd my-project\nharn quickstart --non-interactive\nsource .env\nharn doctor --no-network\nharn run main.harn\nharn test tests/\nharn portal\n```\n\nRemote MCP OAuth:\n\n```bash\nharn mcp redirect-uri\nharn mcp login https://mcp.notion.com/mcp\n```\n\n`harn mcp login` prefers Harn's published CIMD client metadata document and\nfalls back to dynamic client registration when the authorization server does\nnot advertise CIMD support.\n\nSimple LLM call:\n\n```harn\nlet result = llm_call(\n  \"Explain quicksort in two sentences.\",\n  \"You are a concise CS tutor.\"\n)\nlog(result.visible_text)\n```\n\nLoop-until-done agent with tools:\n\n```harn\ntool read(path: string) -\u003e string {\n  description \"Read a file\"\n  read_file(path)\n}\n\ntool search(pattern: string) -\u003e string {\n  description \"Search project files\"\n  let result = exec(\"rg\", \"--\", pattern)\n  result.stdout + result.stderr\n}\n\ntool edit(path: string, content: string) -\u003e string {\n  description \"Edit a file\"\n  write_file(path, content)\n}\n\ntool test(filter: string) -\u003e string {\n  description \"Run a targeted cargo test filter\"\n  let result = exec(\"cargo\", \"test\", filter)\n  result.stdout + result.stderr\n}\n\nlet result = agent_loop(\n  \"Fix the failing test and verify the change.\",\n  \"You are a senior engineer.\",\n  {\n    loop_until_done: true,\n    tools: read,\n    max_iterations: 24\n  }\n)\n\nlog(result.status)\nlog(result.visible_text)\n```\n\nThe `tool` keyword declares tools with typed parameters and optional\ndescriptions. For programmatic tool registration, use `tool_define(...)`,\nwhich also preserves extra config keys such as `policy` for capability\nenforcement.\n\n### Composable LLM middleware\n\n`agent_loop` accepts an `llm_caller:` closure that owns each turn's\n`llm_call(...)`. Wrap it with middleware from `std/llm/handlers` to\ncompose retry / fallback / shadow / budget / cache behavior:\n\n```harn\nimport {default_llm_caller, with_retry, with_fallback, compose} from \"std/llm/handlers\"\n\nlet caller = compose([\n  with_retry({max_attempts: 4, backoff: \"exponential\"}),\n])(default_llm_caller())\n\nagent_loop(task, system, {loop_until_done: true, llm_caller: caller})\n```\n\nSee [docs/src/stdlib/llm-handlers.md](docs/src/stdlib/llm-handlers.md)\nfor the full module catalog (handlers, ensemble, refine, budget,\ndefaults, safe, prompts, catalog).\n\n## Core capabilities\n\n- Typed workflow graphs via `workflow_graph(...)` and `workflow_execute(...)`\n  with explicit nodes, edges, validation, policy attachment, map/join style\n  stages, and resumable execution.\n- Planner-oriented action graphs via `import \"std/agents\"`:\n  `action_graph(...)`, `action_graph_batches(...)`, `action_graph_flow(...)`,\n  and `action_graph_run(...)` normalize planner schema variants into a shared\n  executable schedule instead of leaving dependency repair and batch grouping\n  to leaf pipelines.\n- Persona orchestration primitives via `import \"std/personas/prelude\"`:\n  verifier-then-actor gates, bounded loops, cheap-classifier escalation,\n  circuit-broken parallel sweeps, audit receipt wrappers, and approval gates\n  give durable personas reusable control flow without host-specific glue.\n- Transparent profile bulletin proposals via\n  `import \"std/personas/bulletins\"`: `bulletin_propose` builds typed\n  `harn.profile_bulletin.v1` envelopes with stable id, scope, evidence,\n  source, privacy, and TTL fields; `bulletin_emit` always writes proposals\n  to `personas.bulletins.proposed`, and `bulletin_accept` / `bulletin_reject`\n  / `bulletin_expire` / `bulletin_supersede` emit\n  `harn.profile_bulletin_decision.v1` audit records so hosts (Burin local,\n  Harn Cloud) can review persona context instead of accepting silent prompt\n  mutation.\n- Delegated worker lifecycle builtins via `spawn_agent(...)`, `send_input(...)`,\n  `resume_agent(...)`, `wait_agent(...)`, `close_agent(...)`, and `list_agents()`,\n  with child run lineage, persisted worker snapshots, and host-visible worker\n  lifecycle events. Worker handles retain immutable original `request`\n  metadata plus normalized `provenance` so parent orchestration can recover\n  research questions, action items, workflow stages, and verification steps\n  without positional rebinding. Agent loops also expose lifecycle tools for\n  worker self-parking (`agent_await_resumption`) and opt-in parent-side\n  subagent pause/resume control.\n- Per-worker execution scoping on `spawn_agent(...)`: delegated workers inherit\n  the current execution ceiling by default and can narrow it further with a\n  `policy` dict or `tools: [\"name\", ...]` shorthand, with permission denials\n  returned as structured tool results instead of opaque failures.\n- `sub_agent_run(task, options?)` for isolated child agent loops that preserve a\n  clean parent transcript while returning a typed summary envelope or a\n  background worker handle.\n- Explicit continuation policy for delegated workers: `carry.transcript_mode`\n  (`inherit`, `fork`, `reset`, `compact`), artifact carryover, workflow resume\n  control, and compact parent-facing `worker_result` artifacts.\n- Runtime schema helpers for structured LLM I/O: `schema_check(...)`,\n  `schema_parse(...)`, `schema_is(...)`, JSON Schema/OpenAPI conversion, and\n  schema composition helpers, plus a lazy `std/schema` builder module for\n  ergonomic schema authoring when imported.\n- Provider-neutral GraphQL connector helpers via `import \"std/graphql\"`:\n  request/envelope normalization, introspection and SDL fixture parsing,\n  persisted-query metadata, cursor pagination helpers, auth headers, and\n  generated-style operation wrapper source for GraphQL-first providers such as\n  Linear.\n- Prompt fragment reuse via `import \"std/prompt_library\"`: load TOML catalogs\n  or front-matter `.harn.prompt` files, render cache-aware fragment payloads,\n  and propose tenant-scoped k-means hotspots for repeated context prefixes.\n- Deterministic vision OCR via `vision_ocr(...)` and `import \"std/vision\"`:\n  image path / payload normalization, structured text output\n  (`blocks`, `lines`, `tokens`), and event-log-backed OCR audit records for\n  replayable agent/tool flows.\n- Manifest-backed extension ABI: packages can publish stable module entry\n  points via `[exports]`, declare custom tool and skill surfaces via\n  `[[package.tools]]` and `[[package.skills]]`, and ship provider/alias\n  adapters declaratively via `[llm]` in `harn.toml`, without editing core\n  runtime registration code. `harn tool new \u003cname\u003e` scaffolds a Harn-native\n  tool package with manifest metadata, tests, docs, and CI, while\n  `harn package scaffold openapi` turns an OpenAPI spec into a focused\n  generated SDK package with a regeneration script and package checks.\n  Local sibling packages can be added with `harn add ../harn-openapi`;\n  Harn derives the alias from the dependency's `harn.toml` and live-links\n  directory path dependencies into `.harn/packages/` for fast multi-repo\n  development. Registry-backed discovery is available through\n  `harn package search`, `harn package info`, and\n  `harn add @burin/\u003cname\u003e@\u003cversion\u003e`, which resolve through the package\n  index and then use the same git-backed install path as direct GitHub refs.\n  Manifests can also pin direct git tags with `tag = \"v1.2.3\"` or resolve\n  registry semver ranges with `version = \"^1.2\"`.\n  `harn package list` and `harn package doctor` expose locked exports,\n  permissions, host requirements, and materialized-package integrity for host\n  UI and CI policy checks.\n- Design-by-contract and project/runtime helpers: `require ...`,\n  metadata/scanner runtime builtins, `import \"std/project\"` for\n  freshness-aware metadata and scan state, and `import \"std/runtime\"` for\n  generic runtime/process/interaction helpers inside Harn itself.\n- Isolated execution substrate via directory-scoped command builtins\n  (`exec_at`, `shell_at`) plus the `std/worktree` module for git worktree\n  creation, status, diff, shell execution, and cleanup. Worker execution\n  profiles can pin delegated runs to a cwd, env overlay, or managed\n  worktree so background execution is reproducible instead of ambient-cwd\n  dependent. Subprocesses spawned under an active capability ceiling\n  run inside a per-platform OS sandbox by default: Linux Landlock +\n  seccomp, macOS sandbox-exec, or Windows AppContainer + Job Object,\n  selected via `CapabilityPolicy::sandbox_profile` and documented in\n  [docs/src/sandboxing.md](docs/src/sandboxing.md). Pipelines that\n  spawn untrusted code opt into `sandbox_profile: \"os_hardened\"` to\n  make the OS confinement *required* (the spawn fails as\n  `tool_rejected` if the platform mechanism is missing) instead of\n  best-effort.\n- Stronger preflight behavior via `harn check`: import graph resolution,\n  literal template/render path validation, import symbol collision detection,\n  and host capability contract validation all fail before runtime.\n  `harn check` / `harn run` / the LSP share one recursive module graph that\n  resolves every `import` (including `std/*` embeds) and rejects calls to names\n  that are not builtins, local declarations, struct constructors, callable\n  variables, or imported symbols, so stale or typo'd references surface before\n  the VM starts. `render(...)` resolves relative to\n  the module source tree (including inside imported modules) instead of the\n  ambient process cwd. Literal delegated execution roots,\n  `exec_at(...)` / `shell_at(...)` directories, and unknown\n  `host_call(\"capability.operation\", ...)` contracts are also checked before launch.\n- Runtime-local typed host mocking for tests via `host_mock(...)`,\n  `host_mock_clear()`, and `host_mock_calls()`, so `.harn` conformance and VM\n  tests can exercise host-backed flows without requiring a live bridge host.\n  `import \"std/testing\"` adds higher-level helpers such as\n  `mock_host_result(...)`, `mock_host_error(...)`, and\n  `assert_host_called(...)` for ordinary Harn tests.\n- Configurable LLM mock responses via `llm_mock(...)`, `llm_mock_calls()`,\n  and `llm_mock_clear()`: queue specific text, tool calls, or mixed\n  responses for the mock provider. Supports FIFO queuing and glob-pattern\n  matching against prompts.\n- Eval suite manifests and portable eval packs via `eval_pack { ... }`,\n  `eval_pack_manifest(...)`, resumable `eval_pack_run(...)`,\n  `eval_ledger_*`, `eval_suite_manifest(...)`, `eval_suite_run(...)`,\n  `persona_eval_ladder_run(...)`, `harn eval \u003cmanifest.json|harn.eval.toml\u003e`,\n  and `harn test package --evals`, so grouped replay, rubric, threshold,\n  timeout-ladder, package-shipped connector evals, and longitudinal eval\n  ledgers are first-class runtime data instead of external scripts.\n- Typed artifacts and resources as the real context boundary. Context\n  selection is artifact-aware, budget-aware, and policy-driven rather than\n  raw prompt concatenation.\n- Host-facing artifact helpers for workspace files, snapshots, editor\n  selections, command/test/verification outputs, and diff/review decisions,\n  so product code can pass structured state into Harn without rebuilding\n  artifact taxonomy or provenance conventions.\n- Durable run records with persisted stage transcripts, artifacts, policy\n  decisions, verification outcomes, delegated child lineage, and\n  inspection/replay/eval entrypoints including recursive run-tree loading.\n- Provider-normalized LLM output with `visible_text`, `private_reasoning`,\n  `thinking_summary`, `tool_calls`, `blocks`, `provider`, `stop_reason`, and\n  transcript events.\n- Structured transcript lifecycle support: continue, fork, compact,\n  summarize, render public-only output, or render full execution history.\n- Workflow meta-editing builtins such as `workflow.inspect`, clone/insert/\n  replace/rewire operations, per-node model/context/transcript policy edits,\n  diff, validate, and commit-style validation.\n- Capability ceiling enforcement for workflows and sub-orchestration:\n  internal plans may narrow capabilities but cannot exceed the host ceiling.\n- ACP pending user-message injects for agent execution: accept with a stable\n  `messageId`, optionally replace or revoke while pending, steer after the\n  current operation, or queue until the agent yields back to the human.\n- ACP pending reminder controls for operator UIs: inspect the bridge queue and\n  revoke queued `session/remind` reminders before a checkpoint drains them.\n- Remote MCP over stdio and HTTP, including OAuth metadata discovery, stored\n  bearer tokens for standalone CLI use, and automatic token reuse for HTTP MCP\n  servers declared in `harn.toml`.\n- Runtime semantic cleanup for older surfaces: repeated `catch e { ... }`\n  bindings work within the same enclosing block, and float division keeps\n  IEEE `NaN`/`Infinity` behavior instead of raising runtime errors.\n- Formatter width handling wraps oversized comma-separated forms\n  consistently across calls, list literals, dict literals, enum payloads, and\n  struct-style construction instead of leaving long single-line output intact.\n- Tool lifecycle hooks via `register_tool_hook(...)`: pre-execution deny/modify\n  and post-execution result interception for agent tool calls, with glob-pattern\n  matching on tool names.\n- Automatic transcript compaction in agent loops: microcompaction snips oversized\n  tool outputs, auto-compaction triggers at configurable token thresholds, and\n  `compact_strategy` supports default LLM summarization, truncate fallback, or\n  custom Harn closure-based compaction. Host/user compaction instructions flow\n  through the typed `CompactionPolicy` lane so `/compact \u003cinstructions\u003e` style\n  commands can reuse runtime audit/events without bespoke prompt wiring. The\n  same pipeline is exposed directly as `transcript_auto_compact(...)`.\n- Daemon agent mode (`daemon: true`): agents stay alive waiting for\n  host-injected messages instead of terminating on text-only responses, with\n  adaptive idle backoff, persisted snapshots, timer/file-watch wakes, and\n  explicit bridge wake/resume signaling.\n- Per-agent capability policies with argument-level constraints: `agent_loop`\n  accepts a `policy` dict to scope tool permissions, including `tool_arg_constraints`\n  for pattern-matching on tool arguments.\n- Rule-based approval policies: `approval_policy.rules` expresses allow/ask/deny\n  over tool names/kinds, side-effect levels, declared paths, command identity,\n  URLs/domains/methods, MCP identity, agent/persona/mode, and repeat counts,\n  with deny-by-default sensitive path guards and replayable policy-decision\n  receipts in permission events and host approval prompts.\n- Dynamic per-agent permissions: `agent_loop`, `sub_agent_run`, and\n  `spawn_agent` accept `permissions` with `allow` / `deny` tool rules, VM\n  predicates over the tool args, and `on_escalation` callbacks that can grant a\n  denied call once or for the session. Permission decisions emit\n  `PermissionGrant`, `PermissionDeny`, and `PermissionEscalation` transcript\n  events.\n- Generic call-site type checking is stricter: `where`-clause interface\n  violations are errors, repeated generic parameters must bind to one concrete\n  type, and container bindings like `list\u003cT\u003e` propagate their element type.\n- Workflow map stages can execute in parallel with `\"all\"`, `\"first\"`, or\n  `\"quorum\"` join strategies plus `max_concurrent` throttling.\n- LSP completions surface inferred shape fields, struct members, and enum\n  payload fields on dot access instead of defaulting to dict methods.\n- Adaptive context assembly with deduplication and microcompaction via\n  `select_artifacts_adaptive(...)`, plus `estimate_tokens(...)` and\n  `microcompact(...)` utility builtins.\n- Model-aware token counting via `tiktoken_count_tokens(...)` and\n  `std/llm/budget`, with exact tiktoken counts for known OpenAI models and\n  labeled approximations for Claude/Gemini model families.\n- Host-aware static preflight: `harn check` can load host-specific capability\n  schemas and alternate bundle roots from `harn.toml` or CLI flags so host\n  adapters and bundled template layouts validate cleanly.\n- Mutation-session audit metadata for workflows, delegated workers, and bridge\n  tool gates so hosts can group write-capable operations under one trust\n  boundary without forcing one edit-application UX.\n- String method aliases for case normalization: `.lower()`, `.upper()`,\n  `.to_lower()`, and `.to_upper()`.\n\n## Trust boundary\n\nHarn owns orchestration and provenance. Hosts own concrete mutation UX.\n\n- Harn owns workflow execution, transcript lifecycle, replay/eval, worker\n  lineage, artifact provenance, and mutation-session audit metadata.\n- Hosts own approvals, patch/apply UX, concrete file mutations, and editor\n  undo/redo semantics.\n\nFor autonomous or background edits, the recommended default is worktree-backed\nexecution plus explicit host approval for destructive operations.\n\n## Release workflow\n\nMaintainer release commands and gates live in\n[Maintainer release workflow](docs/src/maintainer-release.md).\n\n## Local development\n\nFor a local contributor setup:\n\n```bash\n./scripts/dev_setup.sh\nmake all\nmake portal\n```\n\n`dev_setup.sh` configures git hooks, installs `cargo-nextest` and `sccache`,\ninstalls repo-local Node tooling including the portal frontend, builds\n`crates/harn-cli/portal-dist`, enables the sccache rustc wrapper, and runs a\nworkspace `cargo check`. When `CODEX_WORKTREE_PATH` is set, it also writes a\nper-worktree temp `target-dir` into `.cargo/config.toml` so parallel Codex\nworktrees do not fight over one shared Cargo target. Heavy setup phases are\nfingerprinted under `.codex/dev-setup/`, so rerunning the script in an already\nprepared checkout is normally a fast no-op; set `HARN_DEV_SETUP_FORCE=1` to\nrefresh all phases. The tracked Codex local\nenvironment at `.codex/environments/environment.toml` calls the same script for\nnew app-managed worktrees. Claude Code project settings use a `SessionStart`\nhook to run `scripts/claude-dev-setup-once.sh`, which delegates to this script\nonce per dependency fingerprint and writes logs under `.claude/dev-setup/`.\n`make portal` launches the built-in observability UI\nfor persisted runs under `.harn-runs/`.\n\nThe repo-root portal scripts (`npm run portal:lint`, `portal:test`,\n`portal:build`, and `portal:dev`) self-bootstrap\n`crates/harn-cli/portal/node_modules` from the checked-in lockfile when those\ndependencies are missing, and the git hooks call the same bootstrap path before\nportal lint runs.\n\n## Why this matters\n\nWithout a runtime boundary like Harn, application code often accumulates:\n\n- provider-specific message/response parsing\n- transcript compaction and summarization logic\n- tool dispatch and retry behavior\n- workflow branching and repair loops\n- provenance, replay, and eval fixtures\n- host/editor queue semantics\n\nHarn keeps those concerns in a typed runtime layer so a host app can focus on:\n\n- capabilities it wants to expose\n- top-level policy ceilings\n- workflow templates and product defaults\n- UI/session integration\n\n## Workflow runtime example\n\n```harn\nlet graph = workflow_graph({\n  name: \"review_and_repair\",\n  entry: \"plan\",\n  nodes: {\n    plan: {\n      kind: \"stage\",\n      mode: \"llm\",\n      task_label: \"Planning task\",\n      model_policy: {model_tier: \"small\"},\n      context_policy: {include_kinds: [\"summary\", \"resource\"], max_tokens: 1200}\n    },\n    implement: {\n      kind: \"stage\",\n      mode: \"agent\",\n      tools: coding_tools(),\n      model_policy: {model_tier: \"mid\"},\n      retry_policy: {max_attempts: 2}\n    },\n    verify: {\n      kind: \"verify\",\n      verify: {\n        command: \"cargo test --workspace --quiet\",\n        expect_status: 0,\n        assert_text: \"test result: ok\"\n      }\n    }\n  },\n  edges: [\n    {from: \"plan\", to: \"implement\"},\n    {from: \"implement\", to: \"verify\"},\n    {from: \"verify\", to: \"implement\", branch: \"failed\"}\n  ]\n})\n\nlet artifacts = [\n  artifact({\n    kind: \"resource\",\n    title: \"Editor selection\",\n    text: read_file(\"src/lib.rs\"),\n    source: \"workspace\"\n  })\n]\n\nlet run = workflow_execute(\n  \"Refactor the parser error message and verify it.\",\n  graph,\n  artifacts,\n  {max_steps: 8}\n)\n\nlog(run.status)\nlog(run.path)\n```\n\nUse `harn runs view --json \u003cpath\u003e` on `run.path` for the stable\n`harn.run_view.v1` projection, including stage summaries. `verify` nodes can\neither run an explicit command as shown above or use an agent/LLM mode when\nverification should stay provider-driven.\n\n## Transcript and artifact model\n\n`llm_call(...)` and `agent_loop(...)` return a canonical schema that\nseparates human-visible output from internal execution state:\n\n- `visible_text`: safe assistant-visible text\n- `private_reasoning`: provider reasoning metadata when available\n- `thinking_summary`: provider-supplied reasoning summary when available\n- `tool_calls`: normalized tool intent\n- `blocks`: canonical structured blocks across providers\n- `provider`: normalized provider identity\n- `transcript`: persisted transcript state with `messages` and `events`\n\nArtifact records are durable typed objects with provenance:\n\n```harn\nlet note = artifact({\n  kind: \"analysis_note\",\n  title: \"Parser regression risk\",\n  text: \"The lexer span mapping affects diagnostics and tree-sitter tests.\",\n  source: \"review\",\n  relevance: 0.9,\n  metadata: {owner: \"runtime\"}\n})\n\nlet focused = artifact_select([note], {\n  include_kinds: [\"analysis_note\"],\n  max_tokens: 200\n})\n```\n\n## Host integration\n\nRun Harn as an ACP backend:\n\n```bash\nharn serve acp agent.harn\nharn serve acp --transport websocket --bind 127.0.0.1:8789 agent.harn\nharn serve acp --api-key \"$HARN_ACP_KEY\" agent.harn\nHARN_PROFILE_JSON=/tmp/acp.ndjson harn serve acp agent.harn\n```\n\nInspect stable run/session views:\n\n```bash\nharn portal\nharn runs view --json .harn-runs/\u003crun\u003e.json\nharn runs view --json --session .harn-runs/\nharn replay .harn-runs/\u003crun\u003e.json\nharn eval .harn-runs/\u003crun\u003e.json\n```\n\nQueued human messages can be delivered to an in-flight agent with\n`session/inject`:\n\n- `steer`: inject after the current tool/operation boundary\n- `queue`: defer until the agent yields control\n\n## Documentation\n\n- [Docs book](https://harnlang.com/)\n- [LLM quick reference](https://harnlang.com/docs/llm/harn-quickref.html)\n- [Workflow runtime guide](https://harnlang.com/workflow-runtime.html)\n- [LLM calls and agent loops](https://harnlang.com/llm-and-agents.html)\n- [Protocol support matrix](https://harnlang.com/protocol-support.html)\n- [MCP, ACP, and A2A integration](https://harnlang.com/mcp-and-acp.html)\n- [CLI reference](https://harnlang.com/cli-reference.html)\n- [Builtin reference](https://harnlang.com/builtins.html)\n- [Language spec](spec/HARN_SPEC.md)\n- [Hosted language spec](https://harnlang.com/language-spec.html)\n\n## Development\n\n```bash\nmake fmt\nmake lint\nmake test           # default Rust test path; uses cargo-nextest when available\nmake test-cargo     # force plain cargo test --workspace\nmake test-fast      # compatibility alias for make test\nmake conformance\nharn test conformance --timing\nharn test conformance tests/worktree_runtime.harn\nmake all\n```\n\nThe workspace includes:\n\n- `harn-lexer`: scanner/tokenizer\n- `harn-parser`: parser, AST, type checker, diagnostics\n- `harn-vm`: compiler, interpreter, LLM/runtime/orchestration layer\n- `harn-fmt`: formatter\n- `harn-lint`: linter\n- `harn-cli`: CLI, ACP, A2A, conformance runner\n- `harn-lsp`: language server\n- `harn-dap`: debugger adapter\n- `tree-sitter-harn`: syntax grammar for editor integrations\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburin-labs%2Fharn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fburin-labs%2Fharn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburin-labs%2Fharn/lists"}