Skip to content

feat(miner-governor): global + per-repo kill-switch (#2341) - #5012

Merged
JSONbored merged 1 commit into
mainfrom
feat/miner-governor-kill-switch-2341
Jul 11, 2026
Merged

feat(miner-governor): global + per-repo kill-switch (#2341)#5012
JSONbored merged 1 commit into
mainfrom
feat/miner-governor-kill-switch-2341

Conversation

@JSONbored

@JSONbored JSONbored commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds the emergency-halt primitive every write-adjacent governor decision consults FIRST: packages/gittensory-engine/src/governor/kill-switch.ts.
  • Global switch: env var GITTENSORY_MINER_KILL_SWITCH, same truthy-string idiom (1/true/yes/on, case-insensitive) as the review-stack's own isGlobalAgentPause (src/settings/agent-execution.ts) — a parallel mechanism for the miner's local runtime, not the same one.
  • Per-repo switch: new MinerGoalSpec.killSwitch.paused field, resolvable from .gittensory-miner.yml. Deliberately distinct from minerEnabled (a discovery-time opt-out) — pausing halts an already-in-flight queue without deregistering the repo from targeting, so un-pausing resumes exactly where the queue left off.
  • resolveMinerKillSwitch({ global, repoPaused }) is pure and stateless: a global halt always reports "global" regardless of the per-repo flag; per-repo alone is sufficient to halt just that repo; toggling either off on the next call immediately reflects "none" with no residual state to corrupt.
  • buildMinerKillSwitchTransitionGovernorLedgerEvent records STATE TRANSITIONS only (previous scope ≠ new scope) — the "state changes are themselves recorded" deliverable. Recording every check's allow/deny for a real write action is the fail-closed Governor chokepoint's job (maintainer: wire the fail-closed Governor chokepoint before every write action #2340, not yet built), which will consult this module first in its "safest wins" precedence (global kill-switch > per-repo pause > dry-run > rate-limit > budget cap > non-convergence > allow).
  • Thin packages/gittensory-miner/lib/governor-kill-switch.js (+ hand-written .d.ts) wrapper exposes checkMinerKillSwitch() (reads process.env + a caller-supplied per-repo flag) and recordMinerKillSwitchTransition() (persists via the existing appendGovernorEvent), matching the exact composition pattern PR feat(miner-governor): wire rate-limit + jittered backoff into live write enforcement (#2344) #4984 established for governor-write-rate-limit.js.
  • Doc/schema/example surface kept in sync: packages/gittensory-miner/docs/miner-goal-spec.md, packages/gittensory-miner/schema/miner-goal-spec.schema.json, .gittensory-miner.yml.example — required by the existing miner-goal-spec-doc.test.ts field-exhaustiveness check.

Scope

Validation

  • git diff --check
  • npm run typecheck — clean.
  • npm run build + npm run test in packages/gittensory-engine — 369/369 passing (9 new kill-switch tests + 2 new MinerGoalSpec.killSwitch parser tests + updates to 3 pre-existing exact-object assertions that needed the new field added).
  • npm run build in packages/gittensory-miner (node --check over every lib file, including the new governor-kill-switch.js) — clean.
  • Targeted vitest run on every touched/adjacent root-level suite (miner-goal-spec-parser, miner-goal-spec-doc, miner-governor-kill-switch, miner-governor-write-rate-limit, miner-governor-ledger, find-opportunities, mcp-cli-find-opportunities) — 58/58 passing.
  • npm run docs:drift-check — unaffected (that check covers feature-flags/commands/gate-mode/RepositorySettings/FocusManifest surfaces, not MinerGoalSpec; the dedicated miner-goal-spec-doc.test.ts is the real doc-sync gate here and is green).
  • npm run test:coverage, test:workers, build:mcp, test:mcp-pack, ui:*, npm audit — not re-run locally; this PR touches only packages/gittensory-engine/**, packages/gittensory-miner/**, and test/unit/** (no top-level src/**, Worker, MCP-pack, or UI code), and per CONTRIBUTING.md only src/** is Codecov-measured, so these are unaffected. CI runs them authoritatively.

Safety

  • No secrets, wallet/hotkey/trust-score/reward data anywhere.
  • This PR adds a DETECTOR/RESOLVER only — no IO, no enforcement wiring, no behavior change for any existing consumer. Nothing calls resolveMinerKillSwitch or checkMinerKillSwitch yet; that wiring is the Governor chokepoint's job (maintainer: wire the fail-closed Governor chokepoint before every write action #2340).
  • Fail-open note (intentional, documented in the module's own doc comment): isGlobalMinerKillSwitch/resolveMinerKillSwitch do not themselves fail closed on ambiguous input — they are pure classifiers. Fail-closed composition (any calculator erroring ⇒ deny) is explicitly the Governor chokepoint's (maintainer: wire the fail-closed Governor chokepoint before every write action #2340) responsibility, per the phase brief's "safest wins" precedence design.
  • No UI changes — no UI Evidence section needed.
  • Docs updated (miner-goal-spec.md, JSON Schema, .gittensory-miner.yml.example); no CHANGELOG.md change (not a release-prep PR).

Notes

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 11, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gittensory-ui 820d62c Commit Preview URL

Branch Preview URL
Jul 11 2026, 09:16 AM

Adds the emergency-halt primitive every write-adjacent governor decision
will consult first: a GLOBAL env-level switch (GITTENSORY_MINER_KILL_SWITCH,
mirroring isGlobalAgentPause's truthy-string idiom) that halts every repo at
once, and a PER-REPO switch (MinerGoalSpec.killSwitch.paused, from
.gittensory-miner.yml) that halts only its own repo's queue. Pure/stateless
resolver + a state-transition ledger-event builder; every-check allow/deny
recording for a real write action is the fail-closed Governor chokepoint's
job (#2340), which composes this module first.
@JSONbored JSONbored added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 11, 2026
@JSONbored JSONbored linked an issue Jul 11, 2026 that may be closed by this pull request
4 tasks
@JSONbored
JSONbored force-pushed the feat/miner-governor-kill-switch-2341 branch from b418a79 to 820d62c Compare July 11, 2026 09:15
@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.73684% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.35%. Comparing base (445c9fc) to head (820d62c).
⚠️ Report is 3 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ages/gittensory-engine/src/governor/kill-switch.ts 92.30% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5012   +/-   ##
=======================================
  Coverage   94.35%   94.35%           
=======================================
  Files         457      458    +1     
  Lines       39216    39235   +19     
  Branches    14300    14309    +9     
=======================================
+ Hits        37004    37022   +18     
  Misses       1558     1558           
- Partials      654      655    +1     
Flag Coverage Δ
shard-1 46.77% <10.52%> (-0.01%) ⬇️
shard-2 33.40% <10.52%> (-0.01%) ⬇️
shard-3 31.45% <21.05%> (+0.41%) ⬆️
shard-4 32.79% <10.52%> (-0.39%) ⬇️
shard-5 33.49% <63.15%> (+0.01%) ⬆️
shard-6 45.15% <42.10%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/gittensory-engine/src/miner-goal-spec.ts 98.03% <100.00%> (+0.12%) ⬆️
...ages/gittensory-engine/src/governor/kill-switch.ts 92.30% <92.30%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. and removed gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. labels Jul 11, 2026
@JSONbored
JSONbored merged commit dcc1601 into main Jul 11, 2026
19 of 20 checks passed
@JSONbored
JSONbored deleted the feat/miner-governor-kill-switch-2341 branch July 11, 2026 09:19
JSONbored added a commit that referenced this pull request Jul 11, 2026
…llName fallback (#5047)

PR #5012 (#2341, merged) landed with codecov/patch failing at
92.30% -- one partial branch never exercised: the root vitest test
only ever supplied repoFullName on transitions, so
buildMinerKillSwitchTransitionGovernorLedgerEvent's
`input.repoFullName ?? null` fallback (kill-switch.ts:69) never took
its null-producing side. Add a real, non-no-op transition (a genuine
scope change) with repoFullName omitted, asserting the ledger row's
repoFullName lands as null rather than undefined or omitted.

kill-switch.ts now measures 100/100/100/100 via the same root vitest
+ vi.mock source-redirect path codecov actually reads (the engine
package's own separate node:test suite, which this session had been
using for local verification elsewhere, is invisible to codecov --
only files with a corresponding miner-lib wrapper exercised by a root
vitest test are.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Development

Successfully merging this pull request may close these issues.

maintainer: global + per-repo kill-switch maintainer: wire the fail-closed Governor chokepoint before every write action

1 participant