{"_id":"@addforce/governor","_rev":"9-7c26b3637a32f73ff90d3dcf1b6c78d5","name":"@addforce/governor","dist-tags":{"latest":"0.4.17"},"versions":{"0.4.8":{"name":"@addforce/governor","version":"0.4.8","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.8","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"b5f9a64aee41ac3b03c16580e01ac2b070882c72","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.8.tgz","fileCount":63,"integrity":"sha512-JzZ4sKOwemo9q6NFF+n3GbpCVeuNpAx8H+r3HmrYPMT8pe7zH0pcP4pnwrkWT1NLzewrsGr1Hj18jHo8GQ9jTg==","signatures":[{"sig":"MEUCIQCNtfk/bxmJXaJm5i/17JkQXgVhtpuLyHf9W3P062SGTgIgQq0PbEuMs5a9Yz8rGPvl/yycQce1QvLCbxV2mr8ZFdM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":359489},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"}},"gitHead":"68de96e36eb43d1492efc38bfe40eba613f4f429","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"workspace:*","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.8_1787575634749_0.34743230210242815","host":"s3://npm-registry-packages-npm-production"}},"0.4.9":{"name":"@addforce/governor","version":"0.4.9","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.9","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"39977a87bae226af308c9f6b677aa46948876e6f","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.9.tgz","fileCount":64,"integrity":"sha512-fFeCyzT0z8hywfUgDiLxylAEmTwPqd8pupdesKhmN6h11czNndajFwJHKse+NH7xb+LlbJkRBSIaF6dIxZX3Rw==","signatures":[{"sig":"MEUCIE0XcIUp1oD3jU8tfDVIF0cVFnFhm9UT8TdPOLt9gQSIAiEA2+Oocgsnzk8p45aYpqzllERIuzyTxCQtdgS86ItbOPA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":394781},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"}},"gitHead":"f5a6192cda602e3e7163080fc2f757f903e7ee9a","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"^0.4.9","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.9_1787576486618_0.30696205811494015","host":"s3://npm-registry-packages-npm-production"}},"0.4.10":{"name":"@addforce/governor","version":"0.4.10","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.10","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"8cfa6b9c0e83357a43b010b52f1c699f7848f267","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.10.tgz","fileCount":64,"integrity":"sha512-5lghZjTuUzyqce/DfatWbwrHBPEogm6Q7F2MT7KB4B1Y8rGxw2D9HoMOzGHUkrbEh1R+QiVUzZXKtRvP8EBIsw==","signatures":[{"sig":"MEUCIQDeFZ/TXtLZhhXiLB7ydgKS5Gx39KZYsNF/TBp5Wz/PHQIgGpLKPQ9ZHG5utfiZtS4GyFnDRY/utZIncQ0wu0zfZg8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":401810},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"}},"gitHead":"b5c7b5d1d4045f1f53f5f9b75ae1d450ff10f3ca","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"^0.4.10","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.10_1787589641880_0.8658051198532879","host":"s3://npm-registry-packages-npm-production"}},"0.4.12":{"name":"@addforce/governor","version":"0.4.12","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.12","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"fc2e946f7868c4a93fe66583f6c9bd374434b34e","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.12.tgz","fileCount":64,"integrity":"sha512-XE5ZnP6qqo3wly4AhyfPYUPCvqNI+gIl0i+XwXCJAMyiDs9uIPCxk0llHuxGt7DXM/dw0ja15B+H14zgLrk7iQ==","signatures":[{"sig":"MEUCIFG/Kez0tsmitmCM4jVWy41dpngdiLD9W2HF2rlqt4wzAiEA0VsVTocI/TYzIC8qoJs5Z9mUSbtXXki+uhlSEVrVfow=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":416055},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"}},"gitHead":"7d13f946835a4fc468c8a591635f94b4a4eb64f7","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"^0.4.12","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.12_1787595322512_0.05361679227924676","host":"s3://npm-registry-packages-npm-production"}},"0.4.13":{"name":"@addforce/governor","version":"0.4.13","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.13","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"18bac27077d986be0695931f2b8be9453ad74ba9","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.13.tgz","fileCount":64,"integrity":"sha512-tAiuYSNLnmDnTirC1KBIWTH31750K3mOn1zVC7vjNWA1EBUaYoxvOVZU5ahhXX2Lh7zqMx8P4jOSxhX9dtjM2A==","signatures":[{"sig":"MEYCIQDLYVmELdBRKCB/tANIDGlmmFLtX9765O0H6qLp3vMihgIhAJiaSSFGdUykUfrpoLAfFTkuHokapMTplTSReXuM2bxT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":427736},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"}},"gitHead":"2dff6d20f3764b8a680df3a4bc346a142b2d3bdb","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"^0.4.13","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.13_1787763976734_0.863446071346412","host":"s3://npm-registry-packages-npm-production"}},"0.4.14":{"name":"@addforce/governor","version":"0.4.14","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.14","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"1795d9bc04cd8f0729fb58c9df79a841dd0e0a55","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.14.tgz","fileCount":76,"integrity":"sha512-Lr6Q9C9v7XMZ/X09Va1EBRMFvhKe6jpOtHa42KFRB6vY4bxh+BN/ZkedrJdTaVtNNQLpHQpTaIwjCG8QDTpAsg==","signatures":[{"sig":"MEUCIQDOAqWVnMnHCLqUAIDQby6rXhgqY8Hk74zPhgbRhjkYQgIgUd/v4e4kiUa5XTFU4i0npyKujM91UgOqsy5ZhP9Xv58=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":523469},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"}},"gitHead":"1f3f5273d90cb1476d39b174b9105a3019ea2928","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"^0.4.14","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.14_1787857246470_0.14037493398351586","host":"s3://npm-registry-packages-npm-production"}},"0.4.15":{"name":"@addforce/governor","version":"0.4.15","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.15","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"38acb71642a2c3f372fac0527f059f78b2de612f","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.15.tgz","fileCount":78,"integrity":"sha512-3UFhXeX2hlfJjFyA94D/XVIivzDb/7VsNWBVz0Ta4EKofkWM9knN7jbeToui6l1deQe/t/MpQF8OoPEsDsTNvQ==","signatures":[{"sig":"MEYCIQCYGPf7Dmw91LHYJdA1WSAvrNwPisTYlfafzSy37nmNBgIhAK48rW0Hsc0H+o0p4ODCv6bj+QVrV1QTTjDtJ+2D3OiG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":552634},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"}},"gitHead":"f1c675bd3b4384e34950ff47a0228ec6933ec3f7","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"^0.4.15","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.15_1788162491253_0.5706745509153224","host":"s3://npm-registry-packages-npm-production"}},"0.4.16":{"name":"@addforce/governor","version":"0.4.16","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","_id":"@addforce/governor@0.4.16","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"dist":{"shasum":"3ffdb3a53fcc7b6d20d5d906210d5bbcb5a86371","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.16.tgz","fileCount":86,"integrity":"sha512-sJoEXsROTOCZZRGtHhQGjtGSVDs6GefNSwuBZg8Z+jmPhOClzoNkj22s7hb6XWo/vok0sc820QFzJCJU69ocRg==","signatures":[{"sig":"MEQCICUSXwgVIWKAJVgjcbyEXaEXYBm7zEgiwYFaYLvK8yEqAiA+skQaD8txTOw1tTRDBypspwPYvLg545rmp/YVmPhz9Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":590602},"type":"module","engines":{"node":">=22.12.0"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"},"./command-runner":{"types":"./dist/command-runner.d.ts","default":"./dist/command-runner.js"}},"gitHead":"63dd0c0c436a8e6f52705bbae6ffd004063b25fb","scripts":{"test":"vitest run","build":"tsc -b","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","test:slow":"vitest run --config vitest.slow.config.ts","postinstall":"node ./postinstall.mjs"},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"repository":{"url":"git+https://github.com/MrNiceGameMaker/governor.git","type":"git","directory":"packages/adapter-mcp"},"_npmVersion":"10.9.4","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"zod":"^4.4.3","@addforce/governor-core":"^0.4.16","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_npmOperationalInternal":{"tmp":"tmp/governor_0.4.16_1788437652929_0.2551630855023672","host":"s3://npm-registry-packages-npm-production"}},"0.4.17":{"name":"@addforce/governor","version":"0.4.17","description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"homepage":"https://github.com/MrNiceGameMaker/governor#readme","bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"repository":{"type":"git","url":"git+https://github.com/MrNiceGameMaker/governor.git","directory":"packages/adapter-mcp"},"license":"SEE LICENSE IN LICENSE","author":{"name":"Ben Shoshani"},"type":"module","engines":{"node":">=22.12.0"},"bin":{"governor":"dist/index.js","governor-hook":"hooks-dist/install.js","model-router-mcp":"bin-aliases/model-router-mcp.mjs","model-router-hook":"bin-aliases/model-router-hook.mjs"},"exports":{"./state":{"types":"./dist/state.d.ts","default":"./dist/state.js"},"./tools":{"types":"./dist/tools.d.ts","default":"./dist/tools.js"},"./build-identity":{"types":"./dist/build-identity.d.ts","default":"./dist/build-identity.js"},"./auto-dispatch":{"types":"./dist/auto-dispatch.d.ts","default":"./dist/auto-dispatch.js"},"./command-runner":{"types":"./dist/command-runner.d.ts","default":"./dist/command-runner.js"}},"scripts":{"build":"tsc -b","test":"vitest run","test:slow":"vitest run --config vitest.slow.config.ts","prepack":"node ../../scripts/copy-license.mjs && node ../../scripts/copy-readme.mjs && node ./prepack-hooks.mjs","postinstall":"node ./postinstall.mjs"},"dependencies":{"@addforce/governor-core":"^0.4.17","@modelcontextprotocol/sdk":"^1.30.0","zod":"^4.4.3"},"devDependencies":{"@types/node":"^26.1.2","isomorphic-git":"^1.40.2"},"_id":"@addforce/governor@0.4.17","gitHead":"8121e0a8267289fad08d55247ad09b9ba8db2ac8","_nodeVersion":"22.22.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-kixmrQdz8t96dJ6jghWdGesXV1y72rE9oy7Jq5/Z6DAtqczpJvChyXgI9yQ7p+NaYTyQEDlVF1uogSRXMdBnYw==","shasum":"6573806bf9996fdc6e3456d2e0d8b7f38e8e83f0","tarball":"https://registry.npmjs.org/@addforce/governor/-/governor-0.4.17.tgz","fileCount":92,"unpackedSize":670885,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDn49AQRWCjVRZC8vSA+dqPQOERtiOxt2cAGSpL25tt+AiAllnLCgeXtz5Vo8MEX/zUPjQ7nzc+PA7DF8QLowR10rg=="}]},"_npmUser":{"name":"ben_addforce","email":"bensho@addforcestudio.com"},"directories":{},"maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/governor_0.4.17_1788525600473_0.7433942481736011"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-24T12:47:14.426Z","modified":"2026-09-04T12:40:00.796Z","0.4.8":"2026-08-24T12:47:14.880Z","0.4.9":"2026-08-24T13:01:26.810Z","0.4.10":"2026-08-24T16:40:42.041Z","0.4.12":"2026-08-24T18:15:22.666Z","0.4.13":"2026-08-26T17:06:16.897Z","0.4.14":"2026-08-27T19:00:46.667Z","0.4.15":"2026-08-31T07:48:11.404Z","0.4.16":"2026-09-03T12:14:13.084Z","0.4.17":"2026-09-04T12:40:00.624Z"},"bugs":{"url":"https://github.com/MrNiceGameMaker/governor/issues"},"author":{"name":"Ben Shoshani"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/MrNiceGameMaker/governor#readme","keywords":["mcp","model-context-protocol","model-routing","claude-code","code-analysis","tree-sitter","local-first"],"repository":{"type":"git","url":"git+https://github.com/MrNiceGameMaker/governor.git","directory":"packages/adapter-mcp"},"description":"Local, deterministic MCP server that scores a coding task against your repo — likely files, difficulty, criticality, model recommendation, verification level — plus an optional Claude Code hook channel. No LLM calls, no network, WASM-only parsing.","maintainers":[{"name":"ben_addforce","email":"bensho@addforcestudio.com"}],"readme":"# Governor\r\n\r\nGovernor is a local MCP server for a coding agent (or the human driving one): before a task\r\nstarts, it says which files it'll touch and which model to use for it; after, it catches an\r\nagent's \"done\" claim that doesn't actually hold up.\r\n\r\n- **Local engine, no network.** File-inference, difficulty, and criticality scoring run as pure\r\n  rules-based logic (`packages/core`) — no LLM call, no network request, no API key required.\r\n- **Stops and asks instead of guessing.** When a task description is too vague to place\r\n  confidently, it asks a clarifying question rather than silently picking files.\r\n- **Catches a \"done\" claim that didn't hold up.** `verify_task` detects and runs the project's own\r\n  test/build/lint commands and diffs files actually changed against what was predicted, so a task\r\n  claimed done with failing tests or an untouched prediction doesn't slip through.\r\n\r\nDocs in [`/docs`](docs/); this file is the quickstart.\r\nShipped-version history: [`CHANGELOG.md`](CHANGELOG.md).\r\n\r\n## Install (npm)\r\n\r\n**Language coverage:** full support, import-graph included, for TypeScript/JavaScript/Python.\r\nEvery other real-source-code file gets text-tier support — indexed, embedded, and keyword-matched,\r\nwithout the dependency-graph signal a parser would add. (Full breakdown below the install\r\ncommands.)\r\n\r\n**Registering the MCP server alone does not make it active.** The server only runs when a tool is\r\ncalled by name — nothing calls `assess_task` on its own. Install the hook below to get a brief\r\ninjected automatically on every prompt instead of relying on an agent to remember to ask.\r\n\r\nThe product packs as two artifacts: **`@addforce/governor`** (the MCP server,\r\nthe `governor` bin, and the Claude Code hook channel with its\r\n`governor-hook` installer bin, all in one package) and\r\n**`@addforce/governor-core`** (the engine it depends on, WASM grammars and the\r\nvendored embedding model included — nothing downloads at install or run\r\ntime). Install:\r\n\r\n```bash\r\nnpm i -g @addforce/governor                # pulls @addforce/governor-core automatically\r\ngovernor-hook /path/to/your/project    # registers BOTH the MCP server and the hook — one command\r\ngovernor-hook /path/to/your/project --uninstall    # removes both any time\r\n```\r\n\r\nThat's the whole install — two commands. `governor-hook` writes to THREE places, every one of them\r\nnamed in the confirmation prompt before anything happens: it merges a `\"governor\"` entry into\r\n`<project>/.mcp.json` (creating the file if it doesn't exist, leaving any other server entries\r\nthere untouched), merges `UserPromptSubmit`/`Stop` entries into `<project>/.claude/settings.json`,\r\nand appends a `.governor/` line to `<project>/.gitignore` (creating it if absent) so the record\r\nstore never shows up as untracked files in your repo. Every one of the three is named again in the\r\nsuccess message once the install finishes, and in the refusal if it can't ask you. `--uninstall`\r\nreverses the first two exactly — a file it CREATED is removed entirely, along with the `.claude/`\r\ndirectory if creating that file is the only reason it exists; a file that already existed keeps its\r\nother content minus our entries — but does not touch the `.gitignore` line, which is left in place\r\nas a harmless, permanent convenience (the uninstall message says so rather than leaving you to find\r\nit). If `.mcp.json` already has a `\"governor\"` entry pointing somewhere else, the\r\ninstaller refuses and says so rather than overwriting it — remove or rename that entry first.\r\n\r\n`governor-hook` **always asks for confirmation unless you pass `--yes`** — this holds whether or\r\nnot you gave it an explicit target directory; earlier versions skipped the prompt for an explicit\r\npath, which is not what \"asks for confirmation first\" should mean, and no longer does. The install\r\nitself also prints this same command right after it finishes (with `--foreground-scripts`, since\r\nnpm hides plain `postinstall` output by default — see below) — see it there if you skip straight to\r\nthe code. `governor-hook` works on any real project directory, git or not (it refuses only a\r\ndirectory that looks empty or unrelated — no manifest file and no source code found, one that\r\nalready has the hook installed, or a conflicting `.mcp.json` entry as above; `--help` for the full\r\noption list). Without it, the server still works once you register it yourself (below) — an agent\r\ncan call `assess_task` explicitly — it just won't happen on its own, and you're back to hand-editing\r\n`.mcp.json`.\r\n\r\nRunning `governor` with no arguments prints getting-started instructions rather than hanging as an\r\nMCP server nobody is talking to. `governor-hook` with no arguments does the same when you are not\r\ninside a project directory; run it from inside one and it treats that as the target and asks to\r\ninstall, which is the other thing you might have meant. Either way you do not need to remember the\r\ntwo commands above from memory.\r\n\r\n`governor` is the stdio server itself — an MCP client spawns it, you don't run it\r\ndirectly. If you'd rather register it by hand (a non-Claude-Code client, or you don't want the\r\nhook), or want to see what the installer writes: Claude Code's `.mcp.json` at your project root,\r\nor `claude mcp add`; other clients use their own MCP server config, same shape:\r\n\r\n```json\r\n{\r\n\t\"mcpServers\": {\r\n\t\t\"governor\": {\r\n\t\t\t\"command\": \"governor\",\r\n\t\t\t\"args\": []\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n\r\nor, without the `-g` flag (a local install into one project instead):\r\n\r\n```json\r\n{\r\n\t\"mcpServers\": {\r\n\t\t\"governor\": {\r\n\t\t\t\"command\": \"node_modules/.bin/governor\",\r\n\t\t\t\"args\": []\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n(and `node_modules/.bin/governor-hook` for the hook command above, in that case)\r\n\r\nBoth packages are licensed under PolyForm Shield 1.0.0 (see [Licence](#licence) below) and publish\r\nunder the `@addforce` scope. `pnpm gate4` packs both tarballs, installs them with plain npm into a\r\nfresh directory outside this repo, and drives a full MCP handshake, cold index, and hook\r\ninstall/uninstall round-trip against a never-seen clone with the network blocked\r\n(`gate-harness/reports/gate4-packaging-2026-08-13.md`).\r\n\r\n**Language coverage, in full:** full support, import-graph included, for TypeScript/JavaScript/\r\nPython; every other real-source-code file (Dart, Elixir, Lua, Zig, Haskell, R, Julia, Clojure, F#,\r\nC#, Java, Go, Rust, C/C++, Ruby, PHP, Kotlin, Swift, Scala, Objective-C, shell, SQL, Vue, Svelte,\r\ntemplate languages like EJS/Jade/Handlebars, and anything else that isn't positively identified as\r\ndata/markup/config, documentation, an image/media/binary, or generated/minified output) gets\r\ntext-tier support — indexed, embedded, and keyword-matched, just without the dependency-graph\r\nsignal a parser would add. This is a denylist, not a hardcoded list of languages: a language\r\nnobody thought to name still gets indexed, rather than silently contributing nothing.\r\n\r\n## Check it's working\r\n\r\nAfter registering the server (above), confirm two things: your MCP client sees it, and a real\r\ncall comes back with a real answer.\r\n\r\n**The client sees it connected.** In Claude Code, run `/mcp` — `governor` should show as\r\nconnected, and its tool list should include `assess_task`, `assess_plan`, `get_file_risk`,\r\n`report_outcome`, `verify_task`, `reindex`. Other clients have their own way to list connected\r\nMCP servers and tools; the tool names are the same everywhere.\r\n\r\n**A real call comes back with a real answer.** Ask your agent to call `assess_task` with a short\r\ndescription of something you'd actually work on next in this repo (in Claude Code, just describe\r\na task normally — it calls the tool on its own once registered). A working response looks like\r\nthis shape, always:\r\n\r\n```\r\n<one plain-language summary line — the recommended model and why, or a clarifying question>\r\n\r\n**Record ID:** `<timestamp>-<random>`\r\n\r\n_Closing the loop: call `report_outcome` with this record id once the task is done...\r\n```\r\n\r\nIf the repository you registered against isn't a git repo yet (or has no commits), the response\r\nstarts with one extra line — `NOTE: no git history available here...` — and everything else\r\nstill works; that's expected, not a problem to fix.\r\n\r\nIf you get anything else — an error message, a stack trace, or no response at all — something is\r\nactually wrong: check that the command in your `.mcp.json` resolves at all (`command -v\r\ngovernor`, or `command -v node_modules/.bin/governor` for a local install, from\r\nthe same shell your client uses — it's a stdio server, so running it directly just hangs waiting\r\nfor input, which is itself a sign it resolved correctly), and see [Development](#development)\r\nbelow for `pnpm gate4`, which reproduces this exact check from a clean install outside the\r\nmonorepo and is the fastest way to tell \"my setup\" from \"a real bug\" apart.\r\n\r\n## Using Governor outside Claude Code\r\n\r\nGovernor indexes **the directory it's launched from** — its `cwd` — unless told otherwise. Claude\r\nCode launches every MCP server it registers from the project directory itself, so this needs no\r\nattention there. Other clients don't all do that: some launch a global MCP server from wherever the\r\nIDE's own install lives, which is a different directory from any project you're actually working\r\nin. Point Governor at the right one with the `GOVERNOR_REPO` environment variable — it overrides\r\n`cwd` when set, and takes precedence over it.\r\n\r\n```json\r\n{\r\n\t\"mcpServers\": {\r\n\t\t\"governor\": {\r\n\t\t\t\"command\": \"npx\",\r\n\t\t\t\"args\": [\"-y\", \"@addforce/governor\"],\r\n\t\t\t\"env\": {\r\n\t\t\t\t\"GOVERNOR_REPO\": \"/absolute/path/to/your/project\"\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n\r\n`GOVERNOR_REPO` must resolve to a real, existing directory that looks like an actual project (a\r\n`package.json`/`pyproject.toml`/`.git`/etc. at its root, or a source file within two directory\r\nlevels — the same check the installer already uses, so if `governor-hook` would accept a directory\r\nas a target, this accepts it as `GOVERNOR_REPO` too). Point it at the wrong path, or at a directory\r\nthat isn't a real project, and every repo-reading tool (`assess_task`, `assess_plan`, `reindex`,\r\n`get_file_risk`, `verify_task`) refuses outright and says exactly why — naming the resolved path —\r\ninstead of silently falling back to `cwd` and indexing whatever happens to be there. That refusal\r\nnever writes anything: no `.governor/` directory, no files, until it's pointed at somewhere real.\r\n\r\n### Which models Governor will recommend\r\n\r\nGovernor only names a model it believes **your** environment can actually run. It used to score the\r\nsame four-model Claude set everywhere, which meant that inside a non-Claude client it would happily\r\nrecommend `claude-opus-5` — a model that client cannot run. Availability now resolves from three\r\nlayers, each overriding the one before:\r\n\r\n1. **CLI scan.** Which vendor agent CLIs (`claude`, `gemini`, `codex`, …) are on your `PATH`. This\r\n   is the most direct evidence there is, because every model call Governor makes runs through your\r\n   own CLI. Scanned once and cached in `.governor/cli-scan.json`; run `reindex` after installing a\r\n   new CLI to refresh it.\r\n2. **Host identity.** The `clientInfo` your MCP client sends during the handshake, matched against a\r\n   short table of known clients. A client not in that table resolves to *unknown* — never a guess.\r\n3. **Your own declaration.** `availableModels` via `manage_settings`, which overrides both:\r\n\r\n```\r\nmanage_settings action=set key=availableModels value=\"claude-sonnet-5, gemini-3.7-flash\"\r\n```\r\n\r\n**When Governor can't name a model, it says so instead of guessing.** If nothing in its scored\r\ncatalog is available in your environment, the response names the *tier* the task needs and stops\r\nthere — no model id. This is deliberate: an agent handles missing information far better than wrong\r\ninformation, so a tier phrase beats a confident recommendation you can't act on.\r\n\r\n**Making other models recommendable by name.** Governor's scored catalog is the four Claude tiers.\r\nIt also ships a 36-model research catalog (`RESEARCH_CATALOG`) with real prices and benchmark\r\nnumbers for models from Google, OpenAI, xAI, DeepSeek and others — but deliberately **without**\r\ntiers or task-type fit, because assigning those is a judgment call this project won't make on your\r\nbehalf. To have a non-Claude model recommended by name, add it to `.governor/registry.json` with a\r\ntier **you** choose:\r\n\r\n```json\r\n[\r\n\t{\r\n\t\t\"id\": \"gemini-3.7-flash\",\r\n\t\t\"displayName\": \"Gemini 3.7 Flash\",\r\n\t\t\"tier\": \"balanced\",\r\n\t\t\"inputCostPerMTok\": 0.3,\r\n\t\t\"outputCostPerMTok\": 2.5,\r\n\t\t\"seedScores\": {},\r\n\t\t\"seedConfidence\": \"seed\"\r\n\t}\r\n]\r\n```\r\n\r\nThat entry is scored like any other from then on. The tier is your declaration about your own setup,\r\nwhich is exactly the boundary: Governor won't invent one, and it won't stop you from setting one.\r\n\r\n## Quickstart\r\n\r\n```bash\r\npnpm install\r\npnpm build\r\n```\r\n\r\nRegister the server (already checked in at the repo root as `.mcp.json` — most MCP clients,\r\nincluding Claude Code and VS Code, pick this up automatically once you `cd` into the repo):\r\n\r\n```json\r\n{\r\n\t\"mcpServers\": {\r\n\t\t\"governor\": {\r\n\t\t\t\"command\": \"node\",\r\n\t\t\t\"args\": [\"packages/adapter-mcp/dist/index.js\"]\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n\r\n**First call is slower than the rest.** The first `assess_task`/`assess_plan`/`reindex` call\r\nagainst a repo builds the full index — file scan, git history, dependency graph, criticality\r\nscores — and warms the semantic embedding model (all in-process, no download at request time; the\r\nmodel ships vendored in the package). Expect this to take several seconds on a mid-sized repo.\r\nEvery call after that reuses the cached index and only rebuilds when `HEAD` moves. Call `reindex`\r\nexplicitly to force a full rebuild and see the cost broken out:\r\n\r\n```\r\nReindexed `/path/to/repo`.\r\n\r\n- Files: 214\r\n- Commits: 812\r\n- HEAD: `a1b2c3d4e5`\r\n- Semantic: 214 files, 1,043 chunks, 0 cache hits / 1,043 misses, 15,821ms index time\r\n- Watcher: 1 records attributed, 5 memory entries created, 42 commits processed\r\n- Total: 16,234.1ms\r\n```\r\n\r\n### Reduced vs. full mode\r\n\r\nThe phase-gate docs (`docs/phase-gates.md`) describe a future \"full mode\" — a real\r\nusage-measurement gate that could eventually justify a richer, LLM-in-the-loop enrichment layer for\r\nfile inference. That layer doesn't exist yet: as shipped, **every** response comes out of the\r\ndeterministic reduced-mode engine, whether or not you have an API key configured anywhere else in\r\nyour toolchain. There is no mode switch to flip today — \"reduced mode\" isn't a fallback, it's the\r\nwhole product right now. Every registry entry is correspondingly marked `seedConfidence: \"seed\"`,\r\nand file-inference confidence never claims more certainty than the rules-based signals actually\r\nsupport.\r\n\r\n### What leaves your machine\r\n\r\nNot one blanket claim — the layers differ in what they actually send, so each gets its own line:\r\n\r\n- **The engine** (`packages/core`: ranking, difficulty, criticality, model recommendation) makes no\r\n  LLM call and no network request, unconditionally. This is the claim above, and it does not weaken\r\n  as other layers are added on top of it.\r\n- **The intake layer's CALLER path** (`packages/adapter-mcp/src/tools.ts`'s `assessTask`, on the MCP\r\n  channel or any live turn-taking caller) introduces no new privacy surface: it asks the CALLING\r\n  AGENT — which is already inside a session the description already went to — to compute a clarity\r\n  score, a specification-vocabulary rewrite, and a model recommendation itself, and pass the answer\r\n  back on the next call. Nothing new leaves the machine that the session's own model calls did not\r\n  already receive. On by default for exactly that reason.\r\n- **The intake layer's SPAWN path** (`packages/adapter-hooks/src/intake-spawn.ts`) would be a\r\n  genuinely NEW outbound call the user did not otherwise initiate — a headless `claude` CLI\r\n  invocation carrying the task description — if it were enabled. **It is DISABLED.** The real\r\n  implementation is preserved and tested (`unsafeSpawnIntakeModelCaller`), but the path everything\r\n  actually calls (`createSpawnIntakeModelCaller`) always rejects immediately without spawning\r\n  anything, because the call measures ~10s against the hook channel's own 800ms IPC budget — 12x\r\n  over, and awaiting it inline would reopen the exact fail-open regression\r\n  `gate-harness/reports/hook-fail-open-2026-08-18.md` fixed. `.governor/hooks-config.json`'s\r\n  `intakeSpawnEnabled` flag still exists and is still read, but has no effect. **As a result, the\r\n  hook channel makes zero outbound model calls today, full stop** — see\r\n  `docs/intake-layer-spec.md`'s \"Why the SPAWN path is disabled\" section for the exact condition\r\n  under which that would change (a genuine non-blocking dispatch, or a materially faster spawn).\r\n- **\"auto\" automation mode's dispatch** (`packages/adapter-mcp/src/auto-dispatch.ts`) is a genuinely\r\n  NEW outbound call too — the router runs the task itself, spawning a headless `claude` CLI call\r\n  carrying the (rewritten) task description. It ships **off by default**:\r\n  `.governor/intake-config.json`'s `automation` is `\"recommend\"` unless explicitly set to\r\n  `\"auto\"`. Unlike the SPAWN path above, this one has no budget conflict (it only ever runs from a\r\n  live MCP/no-channel caller, never the hook channel), so it isn't disabled — but it is exactly as\r\n  opt-in. See `docs/intake-layer-spec.md`'s \"The automation switch\" section.\r\n- **The done-verification layer** (`packages/core/src/verify/`, `verify_task`) makes NO outbound\r\n  call of any kind — no model call, no network request. It only runs commands the project ALREADY\r\n  defines (its own test/build/lint scripts) via a local subprocess spawn\r\n  (`packages/adapter-mcp/src/command-runner.ts`), on your own machine, and never modifies the repo,\r\n  commits, or installs anything.\r\n\r\n### Don't take our word for it\r\n\r\nThe automated test: `scripts/gate4-pack-test.mjs` (run via `pnpm gate4`) launches the packed server\r\nwith poisoned proxy env vars and samples its live TCP connections every 5s while it handles a real\r\n`assess_task` call — see `sampleOutbound()` in that file.\r\n\r\nWatch it yourself: start the server, find its PID, then watch its connections while you send it a\r\nrequest — `Get-NetTCPConnection -OwningProcess <PID>` (PowerShell) or `lsof -i -p <PID>` /\r\n`netstat -p tcp <PID>` (macOS/Linux). You should see nothing but loopback/local, if anything at all.\r\n\r\nThe only path that ever reaches the network at runtime: \"auto\" automation mode's dispatch\r\n(`packages/adapter-mcp/src/auto-dispatch.ts`), which spawns a real `claude` CLI call. It is\r\n**opt-in and off by default** — see [What leaves your machine](#what-leaves-your-machine) above.\r\n\r\n## The tools\r\n\r\nRegistered by `packages/adapter-mcp/src/index.ts`. Every `assess_task`/`assess_plan`/`reindex`\r\nresponse carries `structured.serverBuild: {startedAt, buildHash, stale}` — a cheap mtime check\r\nagainst the server's own compiled entry and `@addforce/governor-core`'s, so a rebuild-without-restart\r\nsurfaces immediately instead of silently serving stale formulas; when `stale` is true the markdown\r\nopens with a one-line restart reminder.\r\n\r\n### `assess_task(description, files?)`\r\n\r\nThe main entry point. Scores every registry model against the task, infers which files it likely\r\ntouches (unless you already know and pass `files`), and — when confidence is high enough — renders\r\nan **opening brief**: a ready-to-paste starting-file list with the signal that justified each entry,\r\ncapped extended-checklist candidates below it, and the verification level required on completion.\r\n\r\n````\r\n## Task Assessment\r\n\r\n**Recommended model:** claude-opus-5\r\n\r\n| Model | Score | Est. cost | Breakdown |\r\n|---|---|---|---|\r\n| **claude-opus-5** | 0.85 | $0.3149 | taskTypeFit 0.86, difficultyFit 1.00, costEfficiency 0.56 |\r\n| claude-sonnet-5 | 0.77 | $0.1889 | taskTypeFit 0.85, difficultyFit 0.67, costEfficiency 0.78 |\r\n\r\n**Verification:** affected-tests — touches a medium-criticality file.\r\n\r\n**Record ID:** `1786617849385-7a337663`\r\n\r\n```\r\nOPENING BRIEF (from Governor, confidence: medium)\r\nLikely starting files — verify before editing, do not limit yourself to these:\r\n- packages/adapter-mcp/src/tools.ts — name match, semantic, co-change\r\n- packages/core/src/measurement/records.ts — name match, semantic, co-change, prompt memory\r\nExtended checklist — lower-ranked candidates worth a quick look before broad exploration:\r\n- gate-harness/src/report.ts — name match, semantic, co-change, prompt memory\r\nVerification required on completion: affected-tests — touches a medium-criticality file.\r\nIf these files look wrong, say so and explore normally.\r\n```\r\n````\r\n\r\nBelow confidence \"medium with basename evidence,\" a **tentative** brief renders instead (hedged\r\nwording, 3-file cap) whenever the top candidate still scores >= 0.6; below that, nothing renders and\r\na clarifying question takes its place. A fourth tier, **docs-hedged**, replaces whatever would have\r\nrendered when the description explicitly names a real, indexed non-code file (a README, a config\r\nfile) — near-certain evidence the task can't be seen by a ranker that only ranks code — OR when the\r\ntask merely classifies as docs/config by keyword AND no code-file candidate clears the tentative\r\nfloor either. A confident code-file candidate is trusted over a casual docs-sounding description:\r\nsampling every unit whose text merely *read* as documentation work found 15 of 15 touched real\r\nsource in the actual commit (`gate-harness/reports/task-kind-map-2026-08-17.md`), so keyword\r\nclassification alone no longer overrides a ranker that has a real lead. `structured.briefTier`\r\n(`full` / `tentative` / `docs-hedged` / `none`) and `structured.timingMs`\r\n(`{total, contextReady, inference, semantic, decide}`) are on every response for whoever wants to\r\nmeasure this without scraping markdown — see [Honest numbers](#honest-numbers).\r\n\r\n### Caller-rewrite: recovering recall on unconfident descriptions\r\n\r\nRecall falls as a task description drifts from commit-message vocabulary toward casual or vague\r\nphrasing (`gate-harness/reports/ai-ground-baseline-2026-08-17.md`). Rewriting the description into\r\ncommit-message register — before scoring it — measurably recovers most of that gap\r\n(`gate-harness/reports/query-rewrite-2026-08-17.md`: casual R@5 51.5% → 64%+ after rewriting; a\r\nfollow-up round confirmed the rewrite itself does the work, not an incidental directory listing the\r\nfirst measurement's prompt also carried —\r\n`gate-harness/reports/query-rewrite-followup-2026-08-18.md`).\r\n\r\nTwo ways to get that rewrite; this project ships the cheaper one as the default.\r\n\r\n**Caller-rewrite (default on this MCP channel).** When a description scores an unconfident\r\ncombination of signals, `assess_task`'s response gains a `callerRewriteHint`: an instruction asking\r\n**you**, the calling agent, to rewrite the description into commit-message vocabulary and call\r\n`assess_task` again — no subprocess, no separate auth, one extra turn in the session you're already\r\nrunning. Validated with a REAL separate caller (a fresh headless session per unit, not the\r\nsame session doing the validating) on the two repos where recall actually collapses: 30 units, 15\r\neach of scrapy and nest, casual + vague text only — see\r\n`gate-harness/reports/caller-rewrite-validation-2026-08-18.md` for the per-repo numbers against the\r\nspawned-subprocess alternative below.\r\n\r\nThe hint doesn't fire on every unconfident call — that was measured and rejected. Gating on\r\n`confidence !== \"high\"` alone fires on effectively every call (`\"high\"` never occurs on the\r\nholdout used to measure this), so a real gate was calibrated instead, entirely on the four\r\n**tuning** repos (zod/fastify/flask/express) — never on the holdout data used to validate it: fires\r\nwhen at least 3 of 4 structural signals are weak (a low top score, a small gap to the second\r\ncandidate, a terse description, no basename evidence on the top candidate). Read once against\r\nalready-scored holdout data (no new generation, no threshold changes after looking): calls the gate\r\nfires on gained 19.9% mean R@5 on average; calls it suppressed gained 7.0% — it fires more on the\r\ndescriptions that actually benefit, and it correctly never fires on the one repo where rewriting\r\ndoesn't move the needle at all (`gate-harness/reports/caller-rewrite-gate-2026-08-18.md`).\r\n\r\nDefault is channel-dependent: **on** for this (MCP) channel and any caller with no channel at all,\r\n**off** on the Claude Code hook channel (its injection is a one-shot prompt prepend with no\r\nmulti-turn \"read the hint, rewrite, call again\" loop to run in). Either default can be overridden\r\nper call with the `callerRewrite` boolean.\r\n\r\n**Spawned subprocess (measured, not shipped as a live feature).** The alternative — the server\r\nspawns a headless `claude -p` process to do the rewrite itself — was measured, not built into the\r\nproduct: a real call costs **~40,757 tokens** (median, dominated by the spawned CLI's own\r\nsystem-prompt/tool-definition injection — this is real per-call weight a fresh process always pays,\r\nregardless of the actual prompt) and **~14s wall-clock** when run in a real project directory\r\n(~10.6s in a bare one), with **no known quota price** — haiku has no empirical entry in\r\n`scripts/quota-weights.json` yet. Caller-rewrite's own real cost, measured live in the session that\r\nvalidated it: a single extra turn adds roughly 1,100–2,100 tokens of genuinely NEW content\r\n(cache-write + output) — but the FULL cost of any turn in a long-running session also re-reads its\r\naccumulated context (cache-read pricing, ~10x cheaper per token than fresh input, but non-zero): in\r\nan ~800K-token session that re-read alone outweighs the spawned call's fixed cost, while in a short,\r\nfresh session caller-rewrite is unambiguously far cheaper. **Which one is actually cheaper depends\r\non how much context the calling session already carries** — there is no single answer, which is\r\nexactly why the default routes through the caller (cheap in the common case, and the only path with\r\nzero fixed per-call token floor) while the spawn path stays available as a measured, documented\r\nalternative rather than a shipped one.\r\n\r\nIf the response contains a `Questions for the USER` section, that's the clarifying-question path:\r\nthe calling agent is expected to relay it to the human verbatim and stop, not answer it internally\r\n(the control contract lives in `CLAUDE.md`).\r\n\r\n### `assess_plan(steps[])`\r\n\r\nSame scoring, one step at a time, for a planning agent that already knows which files each step of\r\na multi-step plan touches:\r\n\r\n```\r\n## Plan Assessment\r\n\r\n| Step | Recommended model | Difficulty | Band | Verification |\r\n|---|---|---|---|---|\r\n| 1 | claude-sonnet-5 | 0.42 | medium | affected-tests |\r\n| 2 | claude-opus-5 | 0.71 | high | full-suite |\r\n```\r\n\r\n### `reindex()`\r\n\r\nForces a full rebuild regardless of whether `HEAD` has moved — see the Quickstart output above.\r\nNormally unnecessary; every other tool call already rebuilds on a cheap `HEAD` mismatch.\r\n\r\nTwo smaller tools round out the API: `get_file_risk(path)` looks up one file's criticality score\r\nand components without running a full assessment, and `report_outcome(recordId, chosenModelId?,\r\nnote?)` manually records which model was actually used for a prior decision (automated attribution\r\nfrom git history runs separately and does not need this call).\r\n\r\n### `verify_task(recordId, claimedDone)`\r\n\r\nThe done-verification layer (`docs/intake-layer-spec.md`'s Step 4). Call it after finishing the task\r\nnamed by `recordId`, reporting whether your own final message claims it's done. Detects and runs the\r\nproject's own test/build/typecheck/lint commands, diffs files actually changed against what was\r\npredicted, and checks any done conditions intake captured — then renders one line, in the same\r\nspirit as the intake message:\r\n\r\n```\r\nVerification: LOW — tests did not run, 1 of 3 predicted files touched\r\n```\r\n\r\n**This is a confidence level, never a correctness verdict** — it catches BROKEN work (tests fail,\r\nnothing runs, files diverge from the prediction), not WRONG-but-passing work (code that runs clean\r\nbut doesn't do what was actually asked). Runs entirely locally: no model call, and it never modifies\r\nthe repo, commits, or installs dependencies — see \"What leaves your machine\" above.\r\n\r\n### The clarifying-question dial\r\n\r\n`docs/intake-layer-spec.md`'s Step 5, shipped as MEASURABLE rather than proven — the case for\r\nasking rests on one directionally-positive small-sample measurement, not a settled result.\r\n`.governor/intake-config.json`'s `interventionLevel` (0-100, default 20) asks a clarifying\r\nquestion on the N% least-clear of THIS project's own prompts, read as a percentile of the project's\r\nown clarity-score history (never an absolute score — scores aren't comparable across models). `0`\r\nnever asks, `100` always asks. The question itself comes from the SAME intake call that already\r\nreturns the score, rewrite, and recommendation — the model is required to return `null` rather than\r\ninvent one when nothing is genuinely missing.\r\n\r\nWhen the dial fires, `assess_task` returns early with just the question:\r\n\r\n```\r\nClarifying question: <question>\r\n\r\n**Record ID:** `1786617849385-7a337663`\r\n```\r\n\r\nRelay it to the user, then call `assess_task` again with the same description, `intakeRecordId`, and\r\neither `intakeQuestionAnswer` or `intakeQuestionSkipped: true` — capped at exactly one question\r\nround per task. In `\"auto\"` automation mode a question still stops for the user first: automation\r\ngoverns dispatch, not consent to be asked.\r\n\r\n## The Claude Code hook channel\r\n\r\nThe second channel over the same engine: instead of an agent calling a tool, a `UserPromptSubmit`\r\nhook asks a warm background daemon for the assessment and injects context directly into the\r\nprompt — before the session reads your prompt. A `Stop` hook closes the loop: it reads which model\r\nactually ran from the session transcript, stamps it onto the session's decision records, and\r\ntriggers a watcher sweep so commits you just made attribute automatically.\r\n\r\n```bash\r\npnpm build\r\npnpm install-hook     # merges hook entries into .claude/settings.json, verifies the daemon starts\r\npnpm uninstall-hook   # removes exactly our entries, stops the daemon\r\n```\r\n\r\n### Injection policy: what actually gets injected, and for whom\r\n\r\nWhat the hook prints is no longer the same for every session — it is gated by tier AND by an\r\n**injection profile**, on measured evidence rather than assumption:\r\n\r\n- **Tier `none` injects nothing.** It used to print a one-line \"low confidence\" notice; the\r\n  variance-floor round's Part 0 measured that the existing brief already costs strong executors\r\n  tokens for no completion benefit on this population, and a consolation line when the render gate\r\n  itself withheld a brief is the same shape of cost for less reason to pay it.\r\n- **Cheap executors** (sonnet, haiku) get the **full brief** — file list, extended checklist, the\r\n  advisory model line — unchanged from before this policy existed.\r\n- **Strong executors** (opus, fable) get **one line only**: `Governor: task assessed\r\n  (confidence <level>); full brief via assess_task` — no file list, no checklist. The variance-floor\r\n  round measured that the file-list brief does not stabilize (and slightly destabilizes) these two\r\n  executors; the AI layer's prompt-rewrite round separately measured that a *wrong* specific guess\r\n  is worse than an honest absence of one. A strong executor is pointed at `assess_task` for the full\r\n  brief on demand rather than handed one it does not need and may act on unnecessarily.\r\n- **Executor detection** reads the last assistant turn's model from the session transcript\r\n  (`transcript_path`, the same field the `Stop` hook already reads) — best-effort, not live: a\r\n  session's first prompt has no prior turn to read, so it falls through to config. Set\r\n  `.governor/hooks-config.json`'s `injectionProfile` (`\"cheap\"` / `\"strong\"` / `\"auto\"`,\r\n  default `\"auto\"`) to override detection when it has nothing to say, or to force a profile\r\n  regardless of what's detected — detection always wins over config when it fires.\r\n- **`assess_task` called explicitly always returns the full brief**, on every channel, regardless\r\n  of profile — a human (or agent) that asked the question directly gets the full answer; the\r\n  profile only shapes what the hook chooses to push unprompted.\r\n- Every hook-channel record gains `injectionProfile` and `injectedBytes` — which profile actually\r\n  rendered and how many bytes actually went into the session's context — so this policy's real\r\n  effect is measurable from the records alone, not just assumed from the tier.\r\n\r\nThe safety rail is absolute: every hook path fails open. On daemon absence, any error, or a hard\r\n800ms budget, the hook prints nothing and exits 0 — your prompt proceeds untouched, and the failure\r\ngoes to `.governor/hook.log`, never to your face. The first prompt after a cold start usually\r\ngets no brief (the daemon is still warming); the next one does.\r\n\r\n**Warm latency scales with repository size, and not gently.** Measured directly (warm\r\n`assess_task`, p50/p95 over 20 calls, real repo content, no synthetic fixtures):\r\n\r\n| Repo | Tracked files | p50 | p95 |\r\n|---|---|---|---|\r\n| json-server | 33 | 18.5ms | 20.3ms |\r\n| flask | 236 | 66.7ms | 70.7ms |\r\n| this monorepo | 963 | ~3.0s | ~3.1s |\r\n\r\nA 4x file-count jump (flask → this monorepo) costs a 45x latency jump, not the ~4x a linear\r\nrelationship would predict — file-inference scoring is effectively all of it (2,994ms of the\r\nmonorepo's 3,010ms total; 50ms of flask's 64ms), which is worth flagging as a real, unoptimized\r\nscaling issue rather than a rounding error. **On a repository this monorepo's size, warm latency\r\nexceeds the hook channel's own 800ms hard budget** — a prompt here will typically fail open (no\r\nbrief, silent, by design) rather than deliver one. Below a few hundred tracked files, in practice,\r\nwarm latency is a non-issue. The `assess_task` MCP tool has no hard timeout of its own and always\r\nreturns the real answer, however long it takes; it is only the hook channel's fail-open budget that\r\nthis can blow through on a large repo.\r\n\r\n**Measure delivery, not installs.** A working install still fails open sometimes — a slow daemon\r\nunder real load, a machine mid-something-else — and a failed-open call produces no DecisionRecord\r\nat all, so `records.jsonl` alone cannot tell you how often the hook actually delivered a brief. It\r\nonly tells you how often it succeeded, silently dropping every failure from the denominator. Every\r\nhook invocation, delivered or failed-open, is logged with its outcome and latency to\r\n`.governor/hook-delivery.jsonl` (`pnpm dashboard`, monorepo-only — see above, reports the\r\ndelivered share over the last 7 days) — any field evaluation of the hook channel should read from\r\nthere, not from install counts or\r\nfrom `records.jsonl` alone. This was a real gap, not a hypothetical one: a controlled measurement\r\n(`docs/dev-log.md`, \"greenfield: four arms under hidden tests\") found the hook delivering nothing in\r\nup to 8 of 18 sessions of a real multi-arm run, invisible until the invocation itself was logged.\r\n\r\n**The honest limitation:** a hook cannot change a running session's model — nothing it injects can\r\nflip the picker for you. The product recommends and asks; switching is the user's action. Row 141\r\nmade the recommendation itself actionable instead of purely informational, but did not (could not)\r\nclose that gap: when the RUNNING model's tier differs from the RECOMMENDED model's tier, the\r\ninjected line instructs the agent to stop before starting work and ask you whether to switch,\r\nnaming both models and the reason — the same \"relay verbatim and stop\" shape this project's own\r\nCLAUDE.md already uses for clarifying questions. A same-tier difference (two models in the same\r\ntier) never triggers this — only a tier change does — and it fires at most once per session per\r\ntier-mismatch pairing, not on every prompt. Whether the agent actually obeys that instruction is a\r\nseparate, measured question, not an assumption: `.governor/tier-offers.jsonl` records every\r\noffer and, once the transcript shows what the next turn did, whether it was obeyed — see\r\n`docs/dev-log.md` row 141 for the mechanism and its own \"no obedience-rate claim without data\"\r\ncaveat. Recommendation-vs-reality lands in the records regardless (`recommendedModelId` from the\r\nassessment, `modelActuallyUsed` from the transcript), which is the comparison the product's story\r\nactually needs.\r\n\r\n## Development\r\n\r\n```bash\r\npnpm build\r\npnpm test        # FAST tier: pure unit tests, ~8s total — run this constantly\r\npnpm test:slow   # SLOW tier: real daemon + real IPC latency-budget tests, ~94s\r\npnpm test:all    # both, in order\r\npnpm lint\r\n```\r\n\r\n**Any change touching a package runs that package's SLOW tests before commit**; `pnpm test:all`\r\nin full before any publish and at the end of a working session. `pnpm test` alone cannot catch a\r\nlatency regression in the hook or MCP channel — the two tests that would are excluded from it by\r\ndesign. Full rationale, the per-file timing measurement behind the split, and why the daemon\r\nbudget test specifically runs serially: [`docs/testing.md`](docs/testing.md).\r\n\r\n## Honest numbers\r\n\r\nFull validation detail: [`docs/current-state.md`](docs/current-state.md) (current formulas, gate\r\nresults, known limitations) and [`docs/experiment-log.md`](docs/experiment-log.md) (every measured\r\nround, chronologically, with cited sources). Summarized plainly, no rounding in the flattering\r\ndirection:\r\n\r\n- **The opening brief's file list — what the calling agent actually receives — recalls roughly 64%\r\n  of the right files on casually-worded English task descriptions**, at the shipped confidence\r\n  gating. Extending that same ranking down through the extended checklist to rank ~20 recovers\r\n  recall to roughly 90% on the same population — most of the gap the top-of-list brief misses is\r\n  still there, just further down, not gone (`gate-harness/reports/recall-curve-2026-08-13.md`).\r\n- **Zero silent failures** on every measured variant: the \"high confidence\" bucket has never once\r\n  been wrong-and-certain across any validation round to date (`docs/current-state.md` §5).\r\n- **The no-AI ceiling is formally closed.** Four full measurement rounds after the current\r\n  formula shipped — a corrected re-ranking hypothesis, three stronger-embedding-model swaps, and an\r\n  exhaustive per-prompt error clinic sweeping 167 configurations — moved casual-English recall by at\r\n  most +0.21pp against a pre-registered +3pp bar, or won on the tuning set and lost on the frozen\r\n  holdout. Deterministic lexical/graph/co-change/embedding re-ranking has reached its ceiling on\r\n  this problem; the verdict and full evidence chain are in `docs/current-state.md` §5's \"Post-v19:\r\n  the error clinic and the no-AI ceiling.\"\r\n- Gate 1's own recall/precision thresholds still **fail outright** against their original targets\r\n  (recall 74.4% vs. >= 80%, precision 25.6% vs. >= 50%) — mitigated, not closed, by confidence\r\n  gating and clarifying questions.\r\n\r\nNone of this is presented as a finished product. It's the actual state of the numbers, and the\r\nnumbers are the pitch, not a summary written to sound better than they are.\r\n\r\n## This project measures itself\r\n\r\nEvery round of formula work runs against a **frozen test set** (real OSS commit history, sampled\r\nonce and never re-touched during tuning) plus a **calibration set** the tuning is allowed to see,\r\ndisjoint by construction — and, past that, an **express holdout repo never opened for tuning at\r\nall**, to catch a formula that wins on what it was fitted to and loses on what it wasn't.\r\nPre-registered success/failure criteria are written down before a round runs, not after — see\r\n[`docs/experiments/opening-brief.md`](docs/experiments/opening-brief.md) for the currently-running\r\nprotocol (opening-brief token savings, BRIEF vs. CONTROL, alternating assignment).\r\n\r\n`docs/dev-log.md` records every development task with the model that ran it, why that model, an\r\nAPI-equivalent token/cost estimate computed from local session transcripts\r\n(`scripts/log-usage.mjs`), and — where the routing engine's own recommendation diverged from what\r\nactually ran — that divergence, noted rather than smoothed over. The project is, deliberately, a\r\npilot of itself.\r\n\r\n**[📊 Cost dashboard](docs/dashboard.html)** — the project's own spend in both\r\ncurrencies (API-equivalent dollars and subscription-quota points), per-model\r\nbreakdown, brief-tier distribution, timing percentiles. Static HTML, no\r\ndependencies, no network; regenerate with `pnpm dashboard`. **Monorepo-only**:\r\nit summarizes THIS repository's own `docs/dev-log.md` and `.governor/`\r\nhistory — a project-self-measurement tool, not a feature the installed\r\n`@addforce/governor` package ships or runs against your repo. There is\r\ncurrently no equivalent command available from a plain `npm i` install.\r\n\r\n## Licence\r\n\r\nYou may use this software, including for commercial work, and modify it for your own use. You may\r\nnot redistribute it, sell it, or use it to build a competing product — see [`LICENSE`](LICENSE)\r\n(PolyForm Shield 1.0.0) for the exact terms.\r\n","readmeFilename":"README.md"}