affaan-m/ECC is the largest agent-harness project to come out of 2026. It calls itself “the agent harness performance optimization system” and promises skills, instincts, memory, security and research-first development across Claude Code, Codex, OpenCode, Cursor, Gemini, Zed and a dozen other tools.
The numbers are not small. 272,248 stars, 40,652 forks, 371 contributors, 3,043 commits and 19 releases since the repository was created on 18 January 2026 — an average of 1,051 stars per day and 20 commits per day in the last week, 93 of the newest 100 commits from the maintainer alone. Its npm package has been downloaded 42,491 times in the last 30 days, and its separate security auditor, ecc-agentshield, 46,012 times — the scanner out-downloads the toolkit.
I cloned main, installed the dependencies with scripts disabled, downloaded and hashed the published tarball, ran the project’s own test suite and audit scripts, compared every duplicated skill tree byte by byte, and pulled the acquisition numbers back from the vendor’s own public endpoints, the npm registry and Wayback snapshots of the repository page.
This is what survived contact.
What the headline numbers claim, and what the tree says
Most repositories of this size fail the first check you can run without any knowledge of the project: counting files. ECC passes it exactly.
| Claim (README + AGENTS.md) | Measured on main | Verdict |
|---|---|---|
| 68 agents | 68 files in agents/ | exact |
| 293 skills | 293 directories containing SKILL.md | exact |
| 94 commands | 94 files under commands/ | exact |
| MIT, v2.2.3 | VERSION, package.json, .claude-plugin/plugin.json, .codex-plugin/plugin.json, plugins/ecc/.codex-plugin/plugin.json and the marketplace manifest all read 2.2.3 | exact |
That alignment is rarer than it sounds. Two days ago I audited a project with 109,000 stars whose own documentation, its own evaluation and a third-party benchmark disagreed about its central performance number.
The repository itself is 4,212 files and 57,707,707 bytes, and its shape is unusual for a tool that ships mostly instructions: 2,790 Markdown files make up 31.0% of the bytes, but 34 PNG files make up 40.2% — 23.2 MB of marketing and documentation imagery checked into the same tree that agents read.
Three small inconsistencies sit inside the documents that pass that count check:
- The same
README.mdsays “68 specialized subagents” in the project tree and “67 specialized subagents” in the annotated catalog 24 lines later. AGENTS.mddescribesmcp-configs/as containing “14 MCP server configurations”. The only file in that directory declares 34 servers, and the translated copies ofAGENTS.mdrepeat the 14.- The skills registry the project uses for public distribution,
skills.sh, lists 309 skills foraffaan-m/ecc— 16 more than the repository publishes.
What you actually install: the 19.5 MB npm artifact
ecc-universal@2.2.3 unpacks to 19,494,887 bytes across 2,805 files. I downloaded the tarball and reproduced both published digests locally (sha1 11f410d5…, sha512 2xDcL0lCJ9O7…), so the numbers below describe the bytes a user gets, not the repository.
| Payload | Bytes | Share of install |
|---|---|---|
| Translated documentation trees | 8,207,475 (1,255 files) | 42.1% |
skills/ | 4,611,555 | 23.7% |
scripts/ | 2,761,086 | 14.2% |
assets/ | 1,370,331 | 7.0% |
agents/ | 442,747 | 2.3% |
commands/ | 384,269 | 2.0% |
.opencode/ + .agents/ + .cursor/ + .pi/ | 861,499 | 4.4% |
README.md | 106,621 | 0.5% |
Two details in that table are worth more than the totals.
The package grew 12.6× in bytes and 9.1× in file count in 233 days — from 1,549,108 bytes over 308 files on 11 February to today’s 19.5 MB over 2,805 files. A fifth of the repository’s files now land in every node_modules that installs it.
Roughly 1.17 MB of that is sponsor artwork. The assets/images/sponsors/ directory is 1,225,612 bytes in 11 files, and the two Itô sponsorship PNGs alone are 689,077 and 476,033 bytes — 5.98% of the entire install is two images for a company the toolkit does not use by default. If you are building containers from npm ci, you are pulling and caching them on every build.
The translation payload is the other half of the story, and it is not a simple defect. Japanese (3.46 MB) and Simplified Chinese (2.54 MB) are there because ECC is explicitly offline-first: an agent in Tokyo or Shanghai can read its own instructions without a network round trip. But the translation set is wildly uneven — the Ukrainian README is 160,175 bytes, 1.5× the length of the English README, while Polish is 10,835 bytes and Vietnamese 6,866. And two of the fifteen language links in the README, Spanish and Thai, point at files excluded by the package.json files allowlist, so they are dead relative paths for anyone reading the README from node_modules. An unlinked sixteenth README, Urdu, exists in the repository and is not in the README switcher at all.
There is one more asymmetry: .kiro/, .trae/ and .codebuddy/ are not in the npm allowlist. GitHub users and npm users do not receive the same product.
The claim that breaks: “adapters map the same workflows instead of maintaining separate copies”
The README makes a specific architectural promise:
The root is the source of truth. Platform adapters package or map these same workflows instead of maintaining separate copies.
I hashed every copied SKILL.md against the canonical one. Eleven trees carry skill copies. Three of them are generated and clean; four of them are not.
| Surface | Skills present | Differ from canonical | Evidence |
|---|---|---|---|
skills/ (canonical) | 293 | — | — |
pi/core/skills | 123 | 0 | generated output, correctly in sync |
.agents/skills (Codex) | 39 | 38 | bulk-touched 19 Sep; canonical kept moving (api-design canonical 29 Sep) |
.cursor/skills | 11 | 11 | 10 of 11 older than canonical; article-writing frozen 27 Feb vs canonical 11 Jun |
.kiro/skills | 43 | 43 | 42 of 43 older; oldest 22 Mar vs canonical 29 Sep — 191 days |
docs/*/skills (translated) | 38–228 per language | all differ by design | localized copies |
The Kiro subtree is the clearest case. .kiro/ is a self-contained drop-in — its own README.md, its own install.sh, 33 agent JSON files, 33 agent Markdown files, 43 skills, 22 steering files and 13 IDE hooks, added in March 2026 by PRs #548 and #809. Its README describes itself as a repository: “This repository provides custom agents, skills, hooks, steering files and scripts.” Every skill in it differs from canonical, and the agents are worse: .kiro/agents/go-reviewer.md was last changed on 22 March, while the canonical agents/go-reviewer.md was last changed on 26 July — a 126-day gap in the file that tells an agent how to review Go.
The steel-man here is real and the vendor states it: the platform matrix in the README labels Cursor a beta project adapter, OpenCode a beta built plugin, and Gemini, Zed, Antigravity, Qwen, Hermes, OpenClaw, Kimi and CodeBuddy “experimental/minimal adapters”, with the line “full Claude feature parity is not claimed”. Kiro is not on that list at all.
But two things follow from that, and they are what a user should take away:
- A frozen snapshot is not a capability statement, it is a content decision made by a copy step. The
.cursorcopy ofarticle-writingis not “beta” — it is 104 days of edits behind a file that changed four times. - The compliance record that is supposed to make those tiers auditable is itself stale.
scripts/harness-adapter-compliance.jsshipsADAPTER_RECORDSfor 12 harnesses, each with alast_verified_atfield. Ten of the twelve say 2026-05-12, one says 2026-05-17, one says 2026-08-10. In the 145 days since the 12 May sweep, the project shipped v2.0.0, v2.1.0, v2.2.0, v2.2.1 and v2.2.2. Kiro, which ships 1.4 MB and 153 files, has no record at all.
Why CI never catches it
There is exactly one test that touches a copied surface: tests/ci/codex-skill-surface.test.js. I read it. It asserts that each .agents/skills/*/SKILL.md has frontmatter restricted to five allowed keys, that name matches its folder, that a description exists, and that an accompanying agents/openai.yaml carries display_name, a short_description of 25–64 characters and a default_prompt.
It never reads skills/. It validates the shape of the copy, not its content. That is why 38 drifted Codex copies pass CI green.
The same pattern repeats one level up. The repository ships five audit scripts — harness-audit.js, platform-audit.js, operator-readiness-dashboard.js, observability-readiness.js, release-approval-gate.js — plus the adapter compliance checker. I searched every workflow in .github/workflows: none of them invokes any of these six. They are npm scripts a human has to remember to run. The 14 workflows that do exist are genuinely good (more on that below), but they audit the repository, not the claim.
Hooks and MCP servers: a catalogue that says 34 and a document that says 14
hooks/hooks.json is 33,225 bytes declaring 24 hook entries across seven lifecycle events: nine PreToolUse matchers, seven Stop, two each SessionStart, PostToolUse and PostToolUseFailure, one PreCompact and one SessionEnd. They dispatch to 24 scripts, including cost-tracker.js, observe-runner.js, governance-capture.js, skill-run-tracker.js, config-protection.js and stop-format-typecheck.js.
Every one of the 24 commands is the same construction: a ~1,800-character inline node -e program whose only purpose is to locate the ECC root directory and then require the real dispatcher. It is defensive and portable, and it also means the JSON you review is not the code that runs — the code that runs is in scripts/hooks/.
The MCP side is where documentation and artifact diverge. mcp-configs/mcp-servers.json declares 34 servers: 22 launched as commands, 12 spoken to over HTTP. AGENTS.md says 14. The file’s own comments say “Keep under 10 MCPs enabled to preserve context window”.
If you are deciding whether to trust the catalogue, three things matter:
- Most of it is not auto-enabled. ECC ships exactly one default connector,
chrome-devtools;docs/MCP-CONNECTOR-POLICY.mddocuments a June 2026 audit that retired six previous defaults (github, context7, exa and others) in favour of CLI-backed skills, on the stated principle that “tool schemas load into every session; each default connector taxes every user’s context window whether they use it or not”. That is a stronger position than most harness projects take. - Pinning is inconsistent.
jirais pinned (uvx mcp-atlassian==0.21.0). Supabase, Context7 and Magic are not: they use@latestand are re-fetched from the registry every time the server starts. A dozen more are unpinnednpx/uvxpackage names. If you enable one, you are executing whatever was published most recently. - Some entries are placeholders or host-specific. A Memxus entry carries
Bearer YOUR_MEMXUS_API_KEY_HERE;nexus,ito-compute,devfleet(localhost:18801) andevalviewpoint at machine-local paths.
The parts that are unusually good
An audit that only lists defects is not an audit. This repository does several things that most agent-tool projects do not, and they are worth copying:
- No lifecycle scripts in the published package. No
preinstall,install,postinstallorprepare.install.shis a 42-line POSIX-safe wrapper that re-execs under bash, resolves symlinks, runsnpm install --ignore-scripts --no-audit --no-fundwhennode_modulesis missing, and hands off to the Node installer. There is nocurl | bashstep anywhere. - Four runtime dependencies.
ajv,sql.js,js-yaml,@iarna/toml. That is the whole dependency tree of a 2,805-file package. - Every GitHub Action pinned to a full commit SHA with a trailing version comment, plus a SLSA generic generator workflow, a scheduled supply-chain IOC watch, a monthly metrics workflow, and release workflows that pack the tarball, enforce exactly one
.tgzand publish its sha256. - No telemetry. I grepped
scripts/andhooks/for analytics, PostHog, Segment, Mixpanel and Sentry. Nothing. The only outbound hosts are GitHub, npm, Discord, X, the project’s own site, the compute sponsor and a jsDelivr CDN. - Version alignment across six manifests, which several popular agent tools fail.
- A large, real test suite.
npm testchains ten validators (unicode safety, agents, commands, rules, skills, hooks, hook schema keys, install manifests, context profiles, no-personal-paths), the catalog and command-registry checks, and a runner whose final box reads 6,194 tests.
One caveat on that last point, because I ran it rather than trusting it: on this Linux container (git 2.47.3, ext4) the suite ends with 4 failures out of 6,194, in two files. One is the case-folding test in tests/scripts/codex-hooks.test.js, whose skip guard — fs.existsSync(__filename.toUpperCase()) || fs.existsSync(__filename.toLowerCase()) — is a tautology on case-sensitive filesystems, because the second clause tests a lowercased name that is already the real filename. The other three are jq: command not found inside skills/skill-stocktake/scripts/scan.sh and quick-diff.sh: a shipped skill depends on jq, and jq appears nowhere in the README’s requirements. The project’s own CI on the same commit is green (its matrix runs ubuntu, macos and windows across Node 18/20/22 and four package managers), so both divergences are environmental — but a test the author intended to be macOS-only runs everywhere, and a missing external binary takes down a suite instead of skipping a case.
Growth, and the metrics the vendor publishes
ECC created its own measurement page, and the interesting thing is that it checks out — with one number that needs reading carefully.
I rebuilt the star curve from Wayback snapshots of the repository page rather than trusting a badge:
| Snapshot | Stars | Forks | Added per day since previous snapshot |
|---|---|---|---|
| 2026-05-19 | 187,033 | 28,959 | — |
| 2026-06-01 | 201,341 | 30,884 | 1,101 |
| 2026-07-07 | 226,765 | 34,677 | 706 |
| 2026-08-10 | 239,148 | 36,322 | 364 |
| 2026-09-04 | 247,534 | 37,305 | 335 |
| 2026-10-03 | 271,486 | 40,559 | 826 |
The curve decays from 1,101 to 335 stars per day through the summer, then re-accelerates to 826 per day in the last month — the fastest rate since spring, on a project that is nine months old. The fork-to-star ratio is stable at 14.9–15.5%, roughly three times the 5.4% of another trending repository I checked for comparison (ponytail, 153,411 stars, 8,227 forks).
Against that, the vendor’s own acquisition table is refreshingly honest about what it cannot prove. It states that “these channels overlap, so their counts are not added together”, that npm counts “include repeat downloads and automation”, that a missing plugin counter means unknown rather than zero, and it publishes a GitHub traffic figure (673,617 clone events, 90,216 unique cloners between 29 August and 11 September) that no outsider can verify. Two of its public numbers I checked byte for byte:
- The GitHub App install badge is a live endpoint (
api.ecc.tools/badge/installs,cacheSeconds: 300) returning 7,058 installs. That is 2.59% of the star count — the size of the gap between a project that gets starred and one that gets deployed. - The 30-day npm downloads (42,491 and 46,012) reproduce exactly from the registry API.
The number that deserves a sentence of its own is 982,400 skill installs on skills.sh. I parsed the registry’s listing for this repository: 309 skills, 982.4K total installs. Top skill 4,700 installs; median 3,400; one skill at zero. The distribution is flat — the most-installed skill has only 1.4× the median — which is not the shape you get from 982,400 developers hand-picking skills. It is the shape you get when roughly 3,200 people or CI jobs install all 309 at once. The vendor’s own methodology note says exactly that: “Individual skill installs, not full-toolkit installs or unique developers.” Read as written, it is accurate; read as marketing, it is off by two orders of magnitude, and the same page carries “The #1 agentic engineering toolkit” and logos of six large employers.
The last figure is a small lesson in not over-claiming as an auditor. The site lists 2,617 release package downloads. My first pass measured 82,356 total release-asset downloads and I nearly wrote that the vendor under-counted by 30×. It does not: 79,024 of those 82,358 downloads (95.9%) are PNG screenshots attached to two releases, and the .tgz assets sum to exactly 2,617. The vendor’s methodology excludes non-package assets and its number is precise. The real finding is the inverse and sharper — 96% of the download traffic on this project’s release page is people pulling promotional images, and the last three releases ship no artifacts at all, because npm is the distribution channel.
What to do if you install it
ECC is not a package you add to a project; it is a layer you give an agent. That changes the risk model, and these are the decisions that matter:
- Start with Claude Code. It is the only surface the project calls “stable primary”; Codex is a supported native plugin; Cursor and OpenCode are labelled beta and their in-repo copies are the drifted ones.
- Use the selective or low-context profile, not the full install, if context budget is tight. The README itself warns that the plugin advertises the whole catalogue to the model.
- Enable at most a handful of MCP servers, and pin the ones you enable. The catalogue’s own comment says under ten. Replace
@latestwith a version you chose, and be aware that enabling a server means executing its package at launch. - Ignore the three translations you cannot read — if you are not building on a network-restricted host,
npm iis fetching 8.2 MB of documentation you will never open, including a 1.17 MB sponsor image pair. - If you use a non-Claude harness, diff it against canonical. For Cursor and Kiro that is a two-command check, and the drift is real:
diff skills/article-writing/SKILL.md .cursor/skills/article-writing/SKILL.mdtakes a second and shows a 104-day-old variant. - Verify the artifact if you deploy it fleet-wide. The digests are published and reproducible, and the release pipeline signs a sha256 of the packed archive.
FAQ
Is ECC’s star count real? The counter is real and moves — I measured 271,486 stars on 3 October and 272,248 via the API on 4 October, consistent with 826 stars per day. What stars do not measure is adoption: 7,058 GitHub App installs (2.59% of stars) and 42,491 monthly npm downloads are the closer proxies.
Why do the Kiro skills differ from the main skills if the repo says it is a single source of truth? Because .kiro/ arrived as a self-contained drop-in with its own installer in March 2026 and is refreshed manually. The architecture claim holds for the generated Pi surface (123 skills, zero drift) and fails for the checked-in snapshots (.agents, .cursor, .kiro).
Does the 34-vs-14 MCP discrepancy affect me at install time? No. Neither number is activated for you: the only default connector is chrome-devtools, and the rest are a catalogue you copy from. The documentation error matters because 10 is the ceiling the project’s own guidance sets, and the catalogue is five times that.
Is it safe to run the hooks? They are local Node scripts, they do not phone home, and the package ships with no lifecycle scripts. The cost is context: 24 hook entries across seven events, and every session start injects learned “instincts” unless you cap them. The knobs are documented — ECC_HOOK_PROFILE=standard, ECC_DISABLED_HOOKS, ECC_SESSION_START_MAX_CHARS (default 8000), ECC_MAX_INJECTED_INSTINCTS (default 6), ECC_INSTINCT_CONFIDENCE_THRESHOLD (default 0.7), ECC_SESSION_RETENTION_DAYS (default 30).
Why is the npm package 19.5 MB? 42.1% is translated documentation, 23.7% is the skill library, 14.2% is installer and runtime scripts, and 6.0% is sponsor artwork. There is no size-optimised build; the growth from 1.5 MB to 19.5 MB tracks the documentation expansion, not the code.
Does it work on Windows and macOS? The CI matrix covers ubuntu, macos and windows across Node 18, 20 and 22 and four package managers, and the install path explicitly handles MSYS2/Git Bash path conversion. Ironically, the one test that fails outside their matrix is a macOS-specific case-folding case.
Conclusion
ECC is the most convincing large-scale attempt at an “agent operating layer” I have audited this year. It proves its headline counts, keeps six manifests in version lockstep, ships four runtime dependencies, signs its release artifacts, pins every action to a commit SHA, avoids telemetry entirely, and — rarest of all — publishes a metrics page that admits its channels overlap and that some of its numbers cannot be independently verified.
The weakness is the same weakness that shows up in every project that multiplies platforms: the promise of a single source of truth is maintained by copy steps, and copy steps rot quietly. Forty-three Kiro skills, eleven Cursor skills and thirty-eight Codex skills are running versions of instructions that the canonical tree replaced months ago, while the repository’s own compliance matrix still reports 12 May as the last verification across five subsequent releases. Nothing in CI can catch it, because the only test that looks at a copy validates its YAML keys rather than its content.
If you install ECC, install it deliberately: one harness, a selective profile, pinned MCP servers, and an eye on which copy of the instructions your agent is actually reading.