feat(miner-governor): wire the gated-submission trigger into the driving loop's handoff signal (#2337)#5054
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | b054955 | Commit Preview URL Branch Preview URL |
Jul 11 2026, 12:56 PM |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feat/miner-killswitch-manage-loop-2339 #5054 +/- ##
==========================================================================
+ Coverage 94.14% 94.18% +0.04%
==========================================================================
Files 467 468 +1
Lines 39609 39619 +10
Branches 14446 14450 +4
==========================================================================
+ Hits 37289 37317 +28
+ Misses 1664 1646 -18
Partials 656 656
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-11 13:02:24 UTC
⏸️ Suggested Action - Manual Review
Review summary Concerns raised — review before merging
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
b0efe58 to
fc1fb95
Compare
fc1fb95 to
0eb3704
Compare
|
Pushed a coupling fixup (0eb3704) + rebased onto #5057 (#2339, kill-switch propagation): #2339 makes `SubmissionGateCandidate.killSwitchScope` required on `shouldSubmit`, which this PR's own `evaluateHarnessSubmissionTrigger` constructs internally -- threaded `killSwitchScope` through from this function's own candidate rather than duplicating the kill-switch check itself (`shouldSubmit`'s own guard covers it whenever the session circuit breaker hasn't already short-circuited first). Base retargeted to `feat/miner-killswitch-manage-loop-2339` so this PR's diff stays scoped to its own changes. Also closed a real, pre-existing codecov gap discovered while verifying the fixup: `submission-gate.ts` had zero root-vitest scenarios for its null-predictedGateVerdict, null-slopAssessment, slop-exceeds-threshold, and observe-mode-would-have-blocked/would-have-allowed paths -- it's only reachable from the root vitest suite through this file's own integration test (`test/unit/miner-harness-submission-trigger.test.ts`), and that test never exercised them. Added all five scenarios; `submission-gate.ts` now measures 100% branch coverage via the actual codecov-visible path. 409 -> now includes 12/12 tests in the root integration test file, all three touched files (harness-submission-trigger.js, harness-submission-trigger.ts, submission-gate.ts) independently confirmed at 100% stmts/branch/funcs/lines. |
739b132 to
6b0a998
Compare
…bmission-gate.ts) #2339's own deliverable: the manage-phase submission-gate function must check the kill-switch/dry-run state as its FIRST guard, before any other logic -- flipping the kill-switch must halt any pending submission-gate check immediately, the same way it already halts the Governor chokepoint (#2340). killSwitchScope is a new REQUIRED field on SubmissionGateCandidate (not optional-with-a-permissive-default) so a caller cannot forget to resolve and pass it. Reuses isMinerKillSwitchActive (kill-switch.ts, #2341) directly -- the single shared helper #2339 asks for, not a bespoke wrapper -- rather than duplicating the check; the sibling loop-reentry-policy.ts change (next commit) consults the identical function.
…oop-reentry-policy.ts) The sibling half of #2339's own deliverable: the manage-phase loop- reentry function must ALSO check the kill-switch/dry-run state as its FIRST guard, before any other logic. killSwitchScope is a new REQUIRED field on LoopReentryCandidate, checked via the identical isMinerKillSwitchActive helper submission-gate.ts's shouldSubmit now consults (the "single shared helper, not duplicated per call site" this issue asks for) -- not a bespoke wrapper. Threads killSwitchScope through packages/gittensory-miner/lib/loop- reentry.js's attemptLoopReentry (validated fail-closed alongside its existing repoFullName/outcome checks) and into the audit event payload for traceability.
…ing loop's handoff signal Adds evaluateHarnessSubmissionTrigger (packages/gittensory-engine/src/ miner/harness-submission-trigger.ts) + evaluateAndRecordHarnessSubmis sionTrigger (packages/gittensory-miner/lib/harness-submission- trigger.js): connects shouldSubmit (#2336) to the actual driving loop's own handoff signal -- iterate-loop.ts's (#2333) HandoffPacket, produced the moment a real run's self-review reaches a clean predicted-gate pass. Not wired into any scheduler as part of this change, per the issue's own "manual owner sign-off on the wiring before this ships to any default-on profile" deliverable. Adds the session-level circuit breaker this issue's own deliverable calls for, distinct from shouldSubmit's per-candidate signal checks: N consecutive allow:false decisions in one session pauses the run entirely pending human review (checked FIRST, before ever consulting shouldSubmit -- once tripped, only a human clearing the session's own tally can un-trip it, unlike a per-candidate block a later, different candidate can clear on its own merits). Session-scoped rather than per-repo, matching "pauses the run entirely" -- distinct from #2338's loop-reentry circuit breaker, which is deliberately per-repo. Every decision (allow or block) is appended to the local event ledger with full reasons, whether or not the circuit breaker was involved. This does NOT build or invoke buildOpenPrSpec (src/mcp/local-write- tools.ts) -- that lives in the private root src/ tree, unreachable from this portable package for the same cross-package-boundary reason self-review-adapter.ts's slop injection exists. A real call site (root-side integration, wired in a later issue) consults this function's allow:true before it builds that spec itself. On the referenced "harness driving loop": the issue cites both the old M4-era gittensory-mcp harness adapter (#781, a different package) and this session's own submission-gate.ts. Wired to iterate-loop.ts's HandoffPacket instead, since that's the actual, current, same-wave driving loop #2336 was built to compose with. Test-covered per the issue's own explicit deliverable: a full candidate -> gate-check -> submit (or correctly-blocked) cycle, plus the circuit breaker tripping and resetting, and fail-closed validation.
…ission trigger #2339 makes SubmissionGateCandidate.killSwitchScope required on shouldSubmit -- this is the coupling fixup: evaluateHarnessSubmission Trigger (#2337) constructs a shouldSubmit candidate internally, so it now requires and forwards killSwitchScope from its own candidate rather than duplicating the kill-switch check itself (shouldSubmit's own guard covers it whenever the session circuit breaker hasn't already short-circuited first). Also closes a real, pre-existing codecov gap discovered while verifying this: submission-gate.ts had ZERO root-vitest scenarios for its null-predictedGateVerdict, null-slopAssessment, slop-exceeds- threshold, and observe-mode-would-have-blocked/would-have-allowed paths -- it's only reachable from the root vitest suite through this file's own integration test, and that test never exercised them. Added all five; submission-gate.ts now measures 100% branch coverage via the actual codecov-visible path, not just the engine's own node:test suite.
…lid deps assertions Two "fails closed on malformed candidate" assertions in miner-harness-submission-trigger.test.ts passed a HarnessSubmissionCandidateInput missing slopThreshold/mode without the as-never cast the four other deliberately- invalid-shape assertions in the same test already use, so tsc rejected them once the type was fully threaded through. No behavior change -- the runtime fail-closed assertions themselves were always correct. Also carries forward the same stacked-branch rebase reconciliation as the two branches this one is built on (rerere replayed the loop-reentry.test.ts resolution automatically).
0eb3704 to
b054955
Compare
e172927
into
feat/miner-killswitch-manage-loop-2339
…bsystem (#2339) (#5057) * feat(miner-governor): propagate the kill-switch into shouldSubmit (submission-gate.ts) #2339's own deliverable: the manage-phase submission-gate function must check the kill-switch/dry-run state as its FIRST guard, before any other logic -- flipping the kill-switch must halt any pending submission-gate check immediately, the same way it already halts the Governor chokepoint (#2340). killSwitchScope is a new REQUIRED field on SubmissionGateCandidate (not optional-with-a-permissive-default) so a caller cannot forget to resolve and pass it. Reuses isMinerKillSwitchActive (kill-switch.ts, #2341) directly -- the single shared helper #2339 asks for, not a bespoke wrapper -- rather than duplicating the check; the sibling loop-reentry-policy.ts change (next commit) consults the identical function. * feat(miner-governor): propagate the kill-switch into shouldReenter (loop-reentry-policy.ts) The sibling half of #2339's own deliverable: the manage-phase loop- reentry function must ALSO check the kill-switch/dry-run state as its FIRST guard, before any other logic. killSwitchScope is a new REQUIRED field on LoopReentryCandidate, checked via the identical isMinerKillSwitchActive helper submission-gate.ts's shouldSubmit now consults (the "single shared helper, not duplicated per call site" this issue asks for) -- not a bespoke wrapper. Threads killSwitchScope through packages/gittensory-miner/lib/loop- reentry.js's attemptLoopReentry (validated fail-closed alongside its existing repoFullName/outcome checks) and into the audit event payload for traceability. * test(miner-governor): add root-vitest coverage for submission-gate.ts (#2339, #2336) submission-gate.ts had zero root-vitest (Codecov-visible) coverage -- only an engine-level node:test file, which Codecov cannot see. #2339's new kill-switch check (2 lines) was the first change to this file Codecov could measure, and it correctly flagged 0% patch coverage as a result. Ports the existing, already-comprehensive engine-level test suite (18 scenarios: kill-switch x3, pass/pass, fail/pass, pass/fail, both-fail, null-verdict, null-slop, both-null, observe-mode x2, isSlopBandWithinThreshold x4, barrel check) into a new root vitest file importing directly from engine source, giving 100% statement/branch/function/line coverage on the whole file, not just the newly-changed lines. Also resolves the rebase onto current main: an add/add conflict on test/unit/miner-loop-reentry.test.ts (this branch's own commit history still referenced an orphaned, pre-fix copy of the now-merged #2338 commit) and the shared build-script line conflict (package.json), both cleanly reconciled with no functional change to either. * feat(miner-governor): wire the gated-submission trigger into the driving loop's handoff signal (#2337) (#5054) * chore(orb): bump manifest target version to 0.4.1 (#5075) orb-v0.4.0 was cut stable earlier today (2026-07-11), but the manifest was never bumped afterward, so orb-beta-release's due-check correctly refused to cut another 0.4.0-suffixed beta -- blocking the automated beta channel for every feat/fix merged since, including #5071/#5072. * feat(miner-governor): propagate the kill-switch into shouldSubmit (submission-gate.ts) #2339's own deliverable: the manage-phase submission-gate function must check the kill-switch/dry-run state as its FIRST guard, before any other logic -- flipping the kill-switch must halt any pending submission-gate check immediately, the same way it already halts the Governor chokepoint (#2340). killSwitchScope is a new REQUIRED field on SubmissionGateCandidate (not optional-with-a-permissive-default) so a caller cannot forget to resolve and pass it. Reuses isMinerKillSwitchActive (kill-switch.ts, #2341) directly -- the single shared helper #2339 asks for, not a bespoke wrapper -- rather than duplicating the check; the sibling loop-reentry-policy.ts change (next commit) consults the identical function. * feat(miner-governor): propagate the kill-switch into shouldReenter (loop-reentry-policy.ts) The sibling half of #2339's own deliverable: the manage-phase loop- reentry function must ALSO check the kill-switch/dry-run state as its FIRST guard, before any other logic. killSwitchScope is a new REQUIRED field on LoopReentryCandidate, checked via the identical isMinerKillSwitchActive helper submission-gate.ts's shouldSubmit now consults (the "single shared helper, not duplicated per call site" this issue asks for) -- not a bespoke wrapper. Threads killSwitchScope through packages/gittensory-miner/lib/loop- reentry.js's attemptLoopReentry (validated fail-closed alongside its existing repoFullName/outcome checks) and into the audit event payload for traceability. * feat(miner-governor): wire the gated-submission trigger into the driving loop's handoff signal Adds evaluateHarnessSubmissionTrigger (packages/gittensory-engine/src/ miner/harness-submission-trigger.ts) + evaluateAndRecordHarnessSubmis sionTrigger (packages/gittensory-miner/lib/harness-submission- trigger.js): connects shouldSubmit (#2336) to the actual driving loop's own handoff signal -- iterate-loop.ts's (#2333) HandoffPacket, produced the moment a real run's self-review reaches a clean predicted-gate pass. Not wired into any scheduler as part of this change, per the issue's own "manual owner sign-off on the wiring before this ships to any default-on profile" deliverable. Adds the session-level circuit breaker this issue's own deliverable calls for, distinct from shouldSubmit's per-candidate signal checks: N consecutive allow:false decisions in one session pauses the run entirely pending human review (checked FIRST, before ever consulting shouldSubmit -- once tripped, only a human clearing the session's own tally can un-trip it, unlike a per-candidate block a later, different candidate can clear on its own merits). Session-scoped rather than per-repo, matching "pauses the run entirely" -- distinct from #2338's loop-reentry circuit breaker, which is deliberately per-repo. Every decision (allow or block) is appended to the local event ledger with full reasons, whether or not the circuit breaker was involved. This does NOT build or invoke buildOpenPrSpec (src/mcp/local-write- tools.ts) -- that lives in the private root src/ tree, unreachable from this portable package for the same cross-package-boundary reason self-review-adapter.ts's slop injection exists. A real call site (root-side integration, wired in a later issue) consults this function's allow:true before it builds that spec itself. On the referenced "harness driving loop": the issue cites both the old M4-era gittensory-mcp harness adapter (#781, a different package) and this session's own submission-gate.ts. Wired to iterate-loop.ts's HandoffPacket instead, since that's the actual, current, same-wave driving loop #2336 was built to compose with. Test-covered per the issue's own explicit deliverable: a full candidate -> gate-check -> submit (or correctly-blocked) cycle, plus the circuit breaker tripping and resetting, and fail-closed validation. * feat(miner-governor): thread killSwitchScope through the harness submission trigger #2339 makes SubmissionGateCandidate.killSwitchScope required on shouldSubmit -- this is the coupling fixup: evaluateHarnessSubmission Trigger (#2337) constructs a shouldSubmit candidate internally, so it now requires and forwards killSwitchScope from its own candidate rather than duplicating the kill-switch check itself (shouldSubmit's own guard covers it whenever the session circuit breaker hasn't already short-circuited first). Also closes a real, pre-existing codecov gap discovered while verifying this: submission-gate.ts had ZERO root-vitest scenarios for its null-predictedGateVerdict, null-slopAssessment, slop-exceeds- threshold, and observe-mode-would-have-blocked/would-have-allowed paths -- it's only reachable from the root vitest suite through this file's own integration test, and that test never exercised them. Added all five; submission-gate.ts now measures 100% branch coverage via the actual codecov-visible path, not just the engine's own node:test suite. * fix(miner-governor): add missing as-never casts for deliberately-invalid deps assertions Two "fails closed on malformed candidate" assertions in miner-harness-submission-trigger.test.ts passed a HarnessSubmissionCandidateInput missing slopThreshold/mode without the as-never cast the four other deliberately- invalid-shape assertions in the same test already use, so tsc rejected them once the type was fully threaded through. No behavior change -- the runtime fail-closed assertions themselves were always correct. Also carries forward the same stacked-branch rebase reconciliation as the two branches this one is built on (rerere replayed the loop-reentry.test.ts resolution automatically).
Summary
Advances #2337.
Adds
evaluateHarnessSubmissionTrigger(packages/gittensory-engine/src/miner/harness-submission-trigger.ts) +evaluateAndRecordHarnessSubmissionTrigger(packages/gittensory-miner/lib/harness-submission-trigger.js): connectsshouldSubmit(#2336) to the actual driving loop's own handoff signal -- iterate-loop.ts's (#2333)HandoffPacket, produced the moment a real run's self-review reaches a clean predicted-gate pass.Why "Advances" not "Closes": this issue's own text asks for a real run to, "end to end, decide to submit and invoke the local-write spec." This PR delivers the decision-wiring half genuinely, but does not build or invoke
buildOpenPrSpec(src/mcp/local-write-tools.ts) -- that lives in the private rootsrc/tree, unreachable from this portable package for the same cross-package-boundary reasonself-review-adapter.ts's slop injection exists (#2334). A real call site (root-side server/CLI integration, wired in a later issue) would consult this function'sallow: truebefore it builds that spec itself. Flagging this explicitly rather than claiming full closure.The session-level circuit breaker this issue's own deliverable calls for, distinct from
shouldSubmit's per-candidate signal checks: N consecutiveallow:falsedecisions in one session pauses the run entirely pending human review. Checked FIRST, before ever consultingshouldSubmit-- once tripped, only a human clearing the session's own tally can un-trip it, unlike a per-candidate block a later, different candidate can clear on its own merits. Session-scoped (not per-repo), matching "pauses the run entirely" -- deliberately distinct from #2338's loop-reentry circuit breaker, which is per-repo (a rejection streak on one repo must not pause unrelated repos).Every decision (allow or block) is appended to the local event ledger with full reasons, whether or not the circuit breaker was involved -- per this issue's own audit deliverable.
On the referenced "harness driving loop": the issue's references section cites both the old M4-era
gittensory-mcpharness adapter (#781, a different package, closed a while back under a different epic) and this session's ownsubmission-gate.ts. Wired toiterate-loop.ts'sHandoffPacketinstead of #781's system, since that's the actual, current, same-wave (#2333) driving loop #2336 was explicitly built to compose with -- reaching into the oldergittensory-mcppackage would be a much larger, differently-scoped undertaking than this maintainer-only issue's batch suggests.Validation
Measured, not assumed -- across both the engine's own
node:testsuite AND the actual codecov-visible root vitest path:harness-submission-trigger.js(compiled from the.tssource) 100.00% lines/branch/funcs.packages/gittensory-miner'snode --checkbuild script passes cleanly with the new file registered.Test plan
Per the issue's own explicit deliverable:
shouldSubmit's own re-check, not blindly trusted just because a handoff happened.allow: falseregardless of the underlying signals.