{"slug": "se-harness-portable-tool-agnostic-ai-coding-harness-generator", "title": "Se-harness – portable, tool-agnostic AI coding harness generator", "summary": "Se-harness (seh) is a new open-source CLI tool that generates portable, tool-agnostic AI coding harnesses from a single source of truth, AGENTS.md, eliminating vendor lock-in. The tool, available via curl install, lets developers define global and project-level rules once and sync them to multiple AI coding agents including Claude Code, Codex, Gemini, Pi, OpenCode, and Copilot, regenerating tool-specific files like CLAUDE.md and GEMINI.md automatically. Se-harness supports layered configuration (core, global, project, and package) and includes features for skills, memory, and agent skill directories.", "body_md": "Portable, tool-agnostic AI coding harness generator. One source of truth,\n`AGENTS.md`\n\nas the entrypoint, no vendor lock-in.\n\n[Quick Start](#quick-start)[Why seh](#why-seh)[Layers](#layers)[The two shapes of](#the-two-shapes-of-agentsmd)`AGENTS.md`\n\n[Commands](#commands)[Harness Packages](#harness-packages)[Skills](#skills)[Memory](#memory)[Agent skill directories](#agent-skill-directories)[Installation](#installation)[Try it (sandboxed demo)](#try-it-sandboxed-demo)[Development](#development)\n\n```\ncurl -fsSL https://raw.githubusercontent.com/manuuuel/seh/main/scripts/install.sh | sh\n\n# Once per machine: unified global ruleset + agent symlinks\nseh init --global --agents claude,codex --yes\n\n# Per project: detect stack, scaffold AGENTS.md + .seh/\ncd your-project\nseh init --tech typescript --yes\n\n# Regenerate generated files after editing .seh/ sources\nseh sync\n```\n\nThis gives you a `~/.seh/AGENTS.md`\n\nglobal ruleset symlinked into your\nagents' config paths, plus a project `AGENTS.md`\n\n(and `CLAUDE.md`\n\n,\n`GEMINI.md`\n\n, …) that every supported agent reads automatically.\n\n`seh`\n\nproduces the context files that AI coding agents (Claude Code, Codex,\nGemini, Pi, OpenCode, Copilot, …) read: a **single global ruleset** on your\nmachine plus a **per-project index** of focused, technology-specific\nguideline modules. Skills from a harness package are distributed to every\nagent that supports them. Edit one source of truth, run `seh sync`\n\n, and\nevery tool-specific file regenerates in lockstep — no more copy-pasting the\nsame rules into `CLAUDE.md`\n\n, `GEMINI.md`\n\n, and `.github/copilot-instructions.md`\n\nseparately.\n\n| Layer | Location | What it is |\n|---|---|---|\nL0 — Core |\nbundled in the CLI | The authored source content (global sections + per-technology catalog). Fallback when no package is active. |\nL1 — Global |\n`~/.seh/` |\nA single unified with your cross-cutting rules. Authored once per machine; optional agent symlinks. Not copied into repos.`AGENTS.md` |\nL2 — Project |\n`<repo>/AGENTS.md` + `.seh/` |\nA thin index linking project + per-technology modules. Committed to the repo. |\nPackage |\n`<your-harness>/` |\nA versioned git repo of global rules, stack modules, templates, and skills. Takes precedence over L0/L1 when active. |\n\nResolution order for any file: **package → ~/.seh/ → seh bundled core**.\n\nGlobal rules apply everywhere; project layers **extend — never contradict** them.\n\n**Generated files must NOT be hand-edited.** Edit the `.seh/`\n\nsources and run\n`seh sync`\n\nto regenerate.\n\n-\n**Global (**— every guardrail inlined in a single document, led by a forced`~/.seh/AGENTS.md`\n\n) is one self-contained file**Craftsmanship** principle (keep it small and sharp, write elegant code, seek the most minimal better-working design, introduce no slop). Tools that auto-load a global instructions file get the whole ruleset directly. -\n**Project (**— a short directive preamble plus a progressive index (linked table of contents) pointing at focused modules under`<repo>/.seh/AGENTS.md`\n\n) is the canonical file`.seh/`\n\n, loaded on demand:`.seh/project.md`\n\n— mission, constraints, out-of-scope (read-first)`.seh/domain/*.md`\n\n— architecture, glossary`.seh/stack/<tech>.md`\n\n— per-technology best practices\n\nTool-specific files (\n\n`AGENTS.md`\n\n,`CLAUDE.md`\n\n,`GEMINI.md`\n\n,`.github/copilot-instructions.md`\n\n, etc.) are**generated symlinks** to`.seh/AGENTS.md`\n\n, gitignored, and regenerated by`seh sync`\n\n.\n\n```\nseh init --global                              # interactive: choose which agents to symlink\nseh init --global --agents claude,codex --yes  # non-interactive\n```\n\nCreates:\n\n`~/.seh/AGENTS.md`\n\n— the unified global ruleset (Craftsmanship first, then security, quality gates, testing, commits, branching, dependencies, error handling, observability, data & privacy, documentation, refactoring, workflow, session startup, reporting, boundaries, code principles).`~/.seh/config.json`\n\n— which agents are symlinked.\n\nOptionally wire agents to auto-load it (see `seh link`\n\n).\n\n```\ncd your-project\nseh init                                         # detects technologies, interactive multi-select\nseh init --tech typescript,python --yes          # non-interactive (≥1 required)\n```\n\nCreates:\n\n`AGENTS.md`\n\n— the project index (links to the modules below)`.seh/project.md`\n\n,`.seh/domain/architecture.md`\n\n,`.seh/domain/glossary.md`\n\n`.seh/stack/<tech>.md`\n\nfor each selected technology`seh.lock`\n\n— records the selected technologies (commit it)\n\n**Supported technologies:** `javascript`\n\n, `typescript`\n\n, `python`\n\n, `go`\n\n, `c`\n\n,\n`rust`\n\n, `java`\n\n. No generic fallback — pick at least one.\n\nThen fill in `.seh/project.md`\n\nand `.seh/domain/*`\n\nand re-sync.\n\n```\nseh sync\n```\n\nRewrites the project `AGENTS.md`\n\nindex and `.seh/stack/*`\n\nfrom `seh.lock`\n\n.\nIdempotent (no change on re-run with unchanged sources).\n\n```\nseh check\n```\n\nExit 0 if the generated files match the sources; exit 1 (with a message) if\n`AGENTS.md`\n\nor a stack module is stale or missing. Suitable for pre-commit/CI.\n\n``` php\nseh link --add claude         # symlink ~/.claude/CLAUDE.md -> ~/.seh/AGENTS.md\nseh link --remove claude      # remove it\n```\n\n`AGENTS.md`\n\nstays the single source of truth; symlinks are pure pointers, so\nthere is no per-agent content to drift.\n\n**Supported agents:** `claude`\n\n, `codex`\n\n, `pi`\n\n, `gemini`\n\n, `opencode`\n\n, `copilot`\n\n, `agents`\n\nThe `agents`\n\ntarget manages the cross-agent interoperability path (`~/.agents/`\n\n,\n`.agents/`\n\n) used as an alias by Gemini CLI, Pi, Copilot, and others.\n\n| Agent | Target |\n|---|---|\n`claude` |\n`~/.claude/CLAUDE.md` |\n`codex` |\n`~/.codex/AGENTS.md` |\n`pi` |\n`~/.pi/agent/AGENTS.md` |\n`gemini` |\n`~/.gemini/GEMINI.md` |\n`opencode` |\n`~/.config/opencode/AGENTS.md` |\n`copilot` |\n`~/.copilot/copilot-instructions.md` |\n`agents` |\n`~/.agents/AGENTS.md` |\n\n| Agent | Target | Canonical |\n|---|---|---|\n`claude` |\n`CLAUDE.md` |\n`.seh/AGENTS.md` |\n`codex` |\n`AGENTS.md` |\n`.seh/AGENTS.md` |\n`pi` |\n`AGENTS.md` |\n`.seh/AGENTS.md` |\n`gemini` |\n`GEMINI.md` |\n`.seh/AGENTS.md` |\n`opencode` |\n`AGENTS.md` |\n`.seh/AGENTS.md` |\n`copilot` |\n`.github/copilot-instructions.md` |\n`.seh/AGENTS.md` |\n`agents` |\n`.agents/AGENTS.md` |\n`.seh/AGENTS.md` |\n\nA **harness package** is a plain directory the user versions with git, carries\nbetween machines, and shares with teammates. `seh`\n\nscaffolds and reads it; git\nis fully external and never wrapped.\n\n```\nmy-harness/\n├── harness.json          — package metadata (name, version, modelTag)\n├── CHANGELOG.md          — harness decisions and reasoning (human-authored)\n├── global/\n│   ├── AGENTS.md         — global ruleset (replaces ~/.seh/AGENTS.md)\n│   └── config.json       — agent symlink config\n├── templates/\n│   ├── stack/            — per-technology structural patterns\n│   └── project/          — full project scaffolds\n├── projects/             — per-repo overlays matched by repo name\n└── skills/               — skills to distribute (vendored or referenced)\n    ├── brainstorming/    — vendored skill (committed to package repo)\n    └── caveman/          — referenced skill (fetched on install)\n```\n\nScaffolds a new harness package at `path`\n\n(default: `./my-harness`\n\n). Creates\nthe full directory structure, copies bundled stack modules as a starting point,\nwrites `harness.json`\n\nand an empty `CHANGELOG.md`\n\n.\n\n```\nseh package init ~/my-harness\ncd ~/my-harness && git init && git add . && git commit -m \"init harness\"\n```\n\nPoints `seh`\n\nat an existing package. Writes `packagePath`\n\ninto `~/.seh/config.json`\n\n.\n\n```\ngit clone git@github.com:you/my-harness.git ~/my-harness\nseh package use ~/my-harness\n```\n\nShows the currently active package path, name/version from `harness.json`\n\n, and\nwhether each expected directory exists.\n\nInstalls artifacts from the active package onto the host machine.\n\n```\nseh package install --harness              # write ~/.seh/AGENTS.md + agent symlinks\nseh package install --skills               # symlink skills into ~/.seh/skills/ + agent dirs\nseh package install --all                  # both of the above\nseh package install --all --agents claude,gemini  # non-interactive agent selection\n```\n\n| Flag | Action |\n|---|---|\n`--harness` |\nWrites `~/.seh/AGENTS.md` from `package/global/AGENTS.md` ; updates agent symlinks |\n`--skills` |\nFetches referenced skills, symlinks `package/skills/<name>/` → `~/.seh/skills/<name>/` → agent skill dirs |\n`--all` |\nBoth of the above |\n`--agents <list>` |\nComma-separated agents to receive skill symlinks (prompts interactively if omitted) |\n`--force` |\nOverwrite existing files |\n\n**New machine workflow:**\n\n```\ngit clone git@github.com:you/my-harness.git ~/my-harness\nseh package use ~/my-harness\nseh package install --all\n```\n\nSkills (reusable `SKILL.md`\n\n-based capability packages) are a first-class layer\nin the harness package. `seh`\n\ndistributes them from the package to every agent\nthat supports a skill directory.\n\n```\n<package>/skills/<name>/   ← source (vendored or referenced)\n         ↓ symlink\n~/.seh/skills/<name>/      ← stable intermediate on this machine\n         ↓ symlinks\n~/.claude/skills/<name>/   ← Claude Code\n~/.codex/skills/<name>/    ← Codex CLI\n~/.gemini/skills/<name>/   ← Gemini CLI\n~/.config/opencode/skills/<name>/  ← OpenCode\n~/.pi/agent/skills/<name>/ ← Pi\n~/.copilot/skills/<name>/  ← GitHub Copilot\n~/.agents/skills/<name>/   ← cross-agent interoperability path\n```\n\n`~/.seh/skills/`\n\nis the stable intermediate: if the package moves, agent\nsymlinks remain intact until re-pointed.\n\nAdds a skill from a GitHub URL to the active package.\n\n```\nseh skills add https://github.com/JuliusBrussee/caveman --reference\nseh skills add github:you/my-skill --vendor --ref v1.2\n```\n\n`--vendor`\n\n: clones files into`<package>/skills/<name>/`\n\n(committed to git)`--reference`\n\n: records the URL in`harness.json`\n\nonly; appends`skills/<name>/`\n\nto`.gitignore`\n\n; files are fetched at install time- Prompts for type if neither flag is given\n- Infers skill name from the repo name\n\n**Routing flags** tell agents when to invoke the skill. Exactly one may be used:\n\n| Flag | When agent invokes |\n|---|---|\n`--always [label]` |\nEvery response |\n`--when <condition>` |\nWhen the described scenario matches |\n`--optional` |\nAgent decides based on context |\n\n```\nseh skills add github:you/caveman --vendor --always \"every response\"\nseh skills add github:you/systematic-debugging --vendor --when \"bug / test failure / unexpected behavior\"\nseh skills add github:you/xlsx --vendor --optional\n```\n\nRouting is stored in `harness.json`\n\nand rendered into a `## Skills`\n\nsection in\nboth the project `AGENTS.md`\n\n(by `seh sync`\n\n) and the global `~/.seh/AGENTS.md`\n\n(by `seh package install --harness`\n\n), so agents always know which skills to\ninvoke and when.\n\nRe-fetches referenced skill(s) from their source. No arguments updates all referenced skills. Errors if the named skill is vendored.\n\nShows skills in the active package with their routing mode:\n\n```\n✓ brainstorming       [vendor]   always: before any implementation\n✓ systematic-debugging [vendor]  when: bug / test failure\n✗ caveman             [reference]  https://github.com/JuliusBrussee/caveman (ref: main)\n✓ xlsx                [vendor]   optional\n```\n\n`✓`\n\n= files present on disk, `✗`\n\n= reference not yet fetched (run\n`seh package install --skills`\n\nto fetch).\n\n```\n{\n  \"name\": \"my-harness\",\n  \"version\": \"1.0.0\",\n  \"skills\": {\n    \"brainstorming\": {\n      \"type\": \"vendor\",\n      \"invoke\": { \"mode\": \"always\", \"label\": \"before any implementation\" }\n    },\n    \"systematic-debugging\": {\n      \"type\": \"vendor\",\n      \"invoke\": { \"mode\": \"when\", \"condition\": \"bug / test failure / unexpected behavior\" }\n    },\n    \"caveman\": {\n      \"type\": \"reference\",\n      \"source\": \"https://github.com/JuliusBrussee/caveman\",\n      \"ref\": \"main\",\n      \"invoke\": { \"mode\": \"always\", \"label\": \"every response\" }\n    },\n    \"xlsx\": {\n      \"type\": \"vendor\",\n      \"invoke\": { \"mode\": \"optional\" }\n    }\n  }\n}\n```\n\nThe same `## Skills`\n\nsection is appended to the project `.seh/AGENTS.md`\n\n(by\n`seh sync`\n\n) and to the global `~/.seh/AGENTS.md`\n\n(by\n`seh package install --harness`\n\n) whenever a skill has routing configured:\n\n```\n## Skills\n\nAlways invoke:\n- `brainstorming` — before any implementation\n- `caveman` — every response\n\nInvoke when:\n- `systematic-debugging` — bug / test failure / unexpected behavior\n\nOptional:\n- `xlsx`\n```\n\nSkills with no `invoke`\n\nfield are omitted from this section. If no skills have\nrouting, the section is omitted entirely.\n\n`.seh/memory/`\n\nstores typed markdown files that agents read for persistent\nproject context — decisions made, constraints discovered, learnings earned,\nproblems still open. Files are committed to the repo so the whole team (and\nevery agent) shares the same memory.\n\n```\n---\ntype: decision\n---\n\n# Auth strategy\n\nChose JWT over sessions. Sessions required sticky routing which complicates\nthe Docker setup. JWT is stateless and works across all replicas.\n```\n\n**Types:**\n\n| Type | When to use |\n|---|---|\n`decision` |\nA choice made and why (architecture, tech, approach) |\n`constraint` |\nA hard rule discovered (never do X, always do Y) |\n`learning` |\nSomething non-obvious that cost time to figure out |\n`problem` |\nUnresolved issue to pick up next session |\n\nCreates `.seh/memory/<name>.md`\n\nwith the correct frontmatter and opens\n`$EDITOR`\n\n(prints the file path if `$EDITOR`\n\nis unset). Default type is\n`decision`\n\n. Does not overwrite an existing file.\n\n```\nseh memory add auth-strategy              # type: decision (default)\nseh memory add rate-limiting --problem\nseh memory add jwt-expiry --learning\nseh memory add url-structure --constraint\n```\n\nShows all memory files grouped by type:\n\n```\nDecisions\n  auth-strategy       Chose JWT over sessions\n  db-migrations       Use Flyway, not Liquibase\n\nConstraints\n  url-structure       Never expose user IDs in URLs\n\nLearnings\n  jwt-expiry          Access tokens must be short-lived (<15m)\n\nOpen problems\n  rate-limiting       Strategy unresolved — Redis vs in-process\n```\n\nDeletes `.seh/memory/<name>.md`\n\n.\n\n`seh sync`\n\nappends a `## Memory`\n\nsection to `.seh/AGENTS.md`\n\nwhenever\n`.seh/memory/`\n\nexists. It always includes a protocol block instructing agents\nto write memory at session end, plus an index of existing files grouped by type:\n\n```\n## Memory\n\nWrite to `.seh/memory/` at end of every session:\n- **decision** — a choice made and why (architecture, tech, approach)\n- **constraint** — a hard rule discovered (never do X, always do Y)\n- **learning** — something non-obvious that cost time to figure out\n- **problem** — unresolved issue to pick up next session\n\nRun: `seh memory add <name> [--decision|--constraint|--learning|--problem]`\n\n### Decisions\n- [Auth strategy](.seh/memory/auth-strategy.md) — Chose JWT over sessions\n\n### Open problems\n- [Rate limiting](.seh/memory/rate-limiting.md) — Strategy unresolved\n```\n\nIf `.seh/memory/`\n\nis empty the protocol block is still rendered (so new agents\nknow how to populate it). If the directory doesn't exist the section is omitted.\n\nAll supported agents have confirmed user-level skill directories (as of 2026-07):\n\n| Agent | User skill directory |\n|---|---|\n`claude` |\n`~/.claude/skills/<name>` |\n`codex` |\n`~/.codex/skills/<name>` |\n`gemini` |\n`~/.gemini/skills/<name>` |\n`opencode` |\n`~/.config/opencode/skills/<name>` |\n`pi` |\n`~/.pi/agent/skills/<name>` |\n`copilot` |\n`~/.copilot/skills/<name>` |\n`agents` |\n`~/.agents/skills/<name>` |\n\nseh is distributed from GitHub — no npm registry account needed.\n\nOne command installs a **self-contained build** (deps bundled) and puts `seh`\n\non\nyour PATH — no npm, no build step, no global `node_modules`\n\n:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/manuuuel/seh/main/scripts/install.sh | sh\n```\n\n**Update:** re-run the same command.**Pin a version:**`curl -fsSL .../scripts/install.sh | SEH_REF=v0.4.1 sh`\n\n- Installs to\n`~/.local/share/seh`\n\n, symlinks`~/.local/bin/seh`\n\n(override via`SEH_HOME`\n\n/`SEH_BIN`\n\n). Requires`node`\n\non PATH. **Uninstall:**`rm -rf ~/.local/share/seh ~/.local/bin/seh`\n\n```\nnpm install -g github:manuuuel/seh          # latest main\nnpm install -g github:manuuuel/seh#v0.4.1   # a tag\n```\n\nnpm installs go through npm's git-dep preparation, which can fail with `ENOTDIR`\n\nif a previous global install left a broken entry. If that happens, remove the\nstale `.../lib/node_modules/se-harness`\n\n, run `npm cache clean --force`\n\n, and retry\n— or just use the curl installer above, which avoids npm entirely.\n\n```\ngit clone git@github.com:manuuuel/seh.git ~/pocs/seh\ncd ~/pocs/seh\nnpm install\nnpm run build\nnpm link       # makes `seh` available in $PATH\n```\n\nTo uninstall: `npm unlink -g se-harness`\n\n.\n\n```\nnpm install --save-dev github:manuuuel/seh\nnpx seh init\n```\n\nRuns the whole flow against a throwaway `HOME`\n\n— your real `~/.seh`\n\nand\n`~/.claude`\n\nare untouched:\n\n```\nnpm run try\nnpm install\nnpm run build    # compile to dist/\nnpm test         # run the test suite (155 tests)\nnpm run dev      # run the CLI via tsx without building\n```\n\n", "url": "https://wpnews.pro/news/se-harness-portable-tool-agnostic-ai-coding-harness-generator", "canonical_source": "https://github.com/manuuuel/seh", "published_at": "2026-08-11 06:14:29+00:00", "updated_at": "2026-08-11 06:42:11.203788+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-agents"], "entities": ["Se-harness", "Claude Code", "Codex", "Gemini", "Pi", "OpenCode", "Copilot"], "alternates": {"html": "https://wpnews.pro/news/se-harness-portable-tool-agnostic-ai-coding-harness-generator", "markdown": "https://wpnews.pro/news/se-harness-portable-tool-agnostic-ai-coding-harness-generator.md", "text": "https://wpnews.pro/news/se-harness-portable-tool-agnostic-ai-coding-harness-generator.txt", "jsonld": "https://wpnews.pro/news/se-harness-portable-tool-agnostic-ai-coding-harness-generator.jsonld"}}