feat(miner-governor): the real create->review->gate->submit attempt pipeline (#2337)#5118
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | 21579ec | Commit Preview URL Branch Preview URL |
Jul 11 2026, 04:33 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 @@
## main #5118 +/- ##
==========================================
+ Coverage 94.22% 94.32% +0.10%
==========================================
Files 471 471
Lines 39821 39821
Branches 14533 14533
==========================================
+ Hits 37520 37560 +40
+ Misses 1645 1583 -62
- Partials 656 678 +22
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 15:59:43 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 5 non-blocking
Concerns raised — review before merging
Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 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.
|
…ipeline (#2337) Adds runMinerAttempt: the missing link between #2333's iterate-loop orchestrator and an actual, executed open_pr write. Composes, in order: runIterateLoop (create -> score -> self-review -> decide) -> on handoff, checkSubmissionFreshness (#3007) -> prepareOpenPrSubmission (#2336/#2337) -> the Governor chokepoint (#2340, which itself already composes kill-switch, dry-run, rate-limit, budget caps, non- convergence, self-reputation-throttle, and self-plagiarism into one precedence ladder -- confirmed by reading chokepoint.ts directly rather than assuming, which is why this calls it exactly once instead of also separately invoking governor-open-pr.js's self-plagiarism check) -> on allowed:true, builds the real open_pr command via the now-shared buildOpenPrSpec (moved to the engine in the prior PR) and executes it. Worktree lifecycle is deliberately NOT this module's job: runIterateLoop already takes a plain workingDirectory string, agnostic about where it came from. Allocating one is the caller's job, via the already-built slot allocator (worktree-allocator.js, #4297) -- this composes the create/review/gate/submit sequence #2337 is actually about, not worktree allocation policy, which is separate, already-solved scope. Two known, deliberate gaps, surfaced rather than papered over: - runSlopAssessment has no production implementation anywhere in this package. The real slop scorer (src/signals/slop.ts, 518 lines, 5 sibling src/signals/** dependencies) is far larger and more interconnected than local-write-tools.ts was, so extracting it is separate, substantial scope -- this function requires a real one be injected rather than silently stubbing a result that would either always pass (unsafe) or always fail (useless). - The governor's cross-attempt state (rate-limit buckets, budget-cap usage, convergence input, reputation history, self-plagiarism recent-submissions) has no persistence wiring anywhere in this package either, confirmed by reading governor-write-rate-limit.js directly: every existing governor-*.js wrapper is a pure in/out transform over caller-supplied state, with nothing persisting the returned value between calls. Durable cross-attempt tracking is portfolio-loop-level scope, not a single attempt's. The CLI dispatch wiring (bin/gittensory-miner.js, real worktree allocation, a real subprocess exec for the final command) is tracked as a separate follow-up -- this PR is the fully real, fully tested orchestrator those pieces will call.
366c138 to
21579ec
Compare
Summary
Advances #2337.
Depends on #5112 (#3007's freshness check) — currently shows 2 commits until that merges, at which point this PR's diff will shrink to just the new commit below.
Adds
runMinerAttempt(packages/gittensory-miner/lib/attempt-runner.js): the missing link between #2333's iterate-loop orchestrator and an actual, executedopen_prwrite. Composes, in order:runIterateLoop(create → score → self-review → decide, maintainer: local create->score->self-review iterate-loop orchestrator (the control-flow core) #2333)checkSubmissionFreshness(feat(miner): add a late-binding freshness check against live repo state before open_pr fires #3007)prepareOpenPrSubmission(maintainer: gated-submission trigger — predicted-gate-PASS + slop-under-threshold check before calling open_pr #2336/maintainer: wire the submission-gate trigger into the harness driving loop #2337)chokepoint.tsdirectly that it already composes kill-switch, dry-run, rate-limit, budget caps, non-convergence, self-reputation-throttle, and self-plagiarism into one precedence ladder, which is why this calls it exactly once rather than also separately invokinggovernor-open-pr.js's self-plagiarism check (that would double-gate the same decision)allowed: true→ builds the realopen_prcommand via the now-sharedbuildOpenPrSpec(moved to the engine in refactor(engine): move local-write action specs into the shared engine package #5117) and executes it via an injectedexecuteLocalWriteWorktree lifecycle is deliberately not this module's job:
runIterateLoopalready takes a plainworkingDirectorystring, agnostic about where it came from. Allocating one is the caller's job, via the already-built slot allocator (worktree-allocator.js, #4297) — this composes the create/review/gate/submit sequence #2337 is actually about, not worktree allocation policy, which is separate, already-solved scope.Two known, deliberate gaps — surfaced, not papered over
runSlopAssessmenthas no production implementation anywhere in this package. The real slop scorer (src/signals/slop.ts, 518 lines, 5 siblingsrc/signals/**dependencies) is far larger and more interconnected thanlocal-write-tools.tswas, so extracting it is separate, substantial scope. This function requires a real one be injected rather than silently stubbing a result that would either always pass (unsafe) or always fail (useless).governor-write-rate-limit.jsdirectly: every existinggovernor-*.jswrapper is a pure in/out transform over caller-supplied state, and nothing persists the returned value between calls. Durable cross-attempt tracking is portfolio-loop-level scope (the outer "process the queue" loop), not a single attempt's.The CLI dispatch wiring (
bin/gittensory-miner.js, real worktree allocation, a real subprocess exec for the final command) is tracked as a separate follow-up — this PR is the fully real, fully tested orchestrator those pieces will call once the two gaps above are resolved.Scope
.d.ts+ build-script entry + 1 test file (this PR's own commit; the extra commit is the feat(miner-governor): late-binding freshness check before open_pr fires (#3007) #5112 dependency, not new scope here).CONTRIBUTING.md.Validation
npm run build --workspace @jsonbored/gittensory-enginethennpm run typecheck— clean.node --checkon the new file + fullpackages/gittensory-minerbuild script (58 files) — all pass.npx vitest run test/unit/miner-attempt-runner.test.ts— 10/10 passing: the full happy path through to a constructed+executedopen_prcommand, abandon (no downstream gate consulted), stale (claim superseded), blocked (submission-gate kill-switch), governed×2 (dry-run mode, and the chokepoint's own kill-switch stage denying even though the submission-gate said ready), the default-governor-ledger fallback path, thebodydefaulting branch, and fail-closed validation on every malformed input/deps field.--coverage.include="packages/gittensory-miner/lib/attempt-runner.js"→ 100% stmts/branches/funcs/lines (53/53, 64/64, 4/4, 38/38).miner-submission-freshness-check,miner-governor-chokepoint,miner-harness-submission-trigger) — 68/68 passing, no interference.npm audit --audit-level=moderate— no dependency changes.Safety
executeLocalWriteand a realrunSlopAssessmentboth being injected by the caller — neither has a production default in this package yet, so there is no path to an accidental live write from this PR alone.