Skip to content

feat(miner-governor): shape the gated open-pr submission payload from a handoff (#2337)#5091

Merged
JSONbored merged 1 commit into
mainfrom
feat/harness-open-pr-submission-2337
Jul 11, 2026
Merged

feat(miner-governor): shape the gated open-pr submission payload from a handoff (#2337)#5091
JSONbored merged 1 commit into
mainfrom
feat/harness-open-pr-submission-2337

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Advances #2337.

Adds prepareOpenPrSubmission to packages/gittensory-miner/lib/harness-submission-trigger.js: bridges one completed handoff through the existing evaluateAndRecordHarnessSubmissionTrigger (#2337 predecessor, PR #5054) to a submission-READY payload — the exact input shape buildOpenPrSpec (root src/mcp/local-write-tools.ts) expects: { repoFullName, base, head, title, body, draft }.

  • On allow: true{ ready: true, decision, event, openPrInput }.
  • On allow: false{ ready: false, decision, event }, without requiring a source branch at all — a blocked candidate never needs one, so it must not throw for an unrelated missing-field reason.
  • Fails closed on a missing PR title/base immediately (before any gate evaluation or ledger write — a caller bug, not a policy decision).
  • Fails closed on a missing handoffPacket.branchRef only once allow: true is already known — a PR cannot be opened without a branch, but the gate's own decision is still recorded to the audit ledger before this throws, so the trail survives even when the downstream spec-build step fails.

What this does NOT do (honest scope, same tension PR #5054 already flagged)

This still does not call buildOpenPrSpec itself — that lives in the private root src/ tree, unreachable from this portable package (same cross-package-boundary reason self-review-adapter.ts's slop injection exists, #2334). A real root-side/MCP call site (e.g. the existing gittensory_open_pr tool, src/mcp/server.ts) would take openPrInput from a ready: true result and pass it through to that function or the equivalent tool call.

More significantly: I traced every real (non-test) call site of runIterateLoop in the repo and found there isn't one — packages/gittensory-miner's CLI (lib/cli.js) has no command that instantiates a real CodingAgentDriver (the SDK-backed one lives at packages/gittensory-engine/src/miner/agent-sdk-driver.ts) and drives the loop end to end with live credentials. Building that CLI/driver entrypoint — the actual "real run" deliverable 1 asks for — is separate, materially larger scope (worktree/credential handling, a live driver instance, and a decision for how the miner's local process actually reaches gittensory's gittensory_open_pr MCP tool over the network) that I'm not comfortable inventing unilaterally in the same PR as this decision-to-payload bridge, given the issue's own explicit "manual owner sign-off on the wiring before this ships to any default-on profile" deliverable and its framing as the single highest-stakes trigger surface in the roadmap ("a bug here means an autonomous write happens when it should not have"). Flagging this precisely rather than claiming closure.

Status of the issue's other deliverables (unchanged by this PR, already true from #5054)

  • Circuit breaker (N consecutive allow:false pauses the session) — already built, unaffected here.
  • Every decision recorded to the local event ledger — already built, unaffected here.
  • Manual owner sign-off before default-on — not yet relevant; nothing autonomous is wired to run any of this yet.

Scope

Validation

  • npm run typecheck — clean.
  • node --check on the modified file + full packages/gittensory-miner build script (55 files) — all pass.
  • npx vitest run test/unit/miner-harness-submission-trigger.test.ts — 20/20 passing (11 new, covering: the full ready:true shape, the ready:false/no-branch-required path, both new fail-closed checks with ledger-state assertions proving when each fires relative to the gate call, default/omitted fields, trimming, and malformed-candidate guards).
  • Scoped coverage on the modified file (same technique PR feat(miner-governor): wire the gated-submission trigger into the driving loop's handoff signal (#2337) #5054's own validation used): npx vitest run test/unit/miner-harness-submission-trigger.test.ts --coverage --coverage.include="packages/gittensory-miner/lib/harness-submission-trigger.js" → 100% stmts/branches/funcs/lines (43/43, 50/50, 4/4, 31/31).
  • Confirmed empirically (not assumed) that this file's coverage is outside codecov's tracked scope regardless: vitest.config.ts's coverage.include is ["src/**/*.ts", "packages/gittensory-engine/src/**/*.ts", "review-enrichment/src/analyzers/codeowners.ts"]packages/gittensory-miner/lib/** isn't in it. Checked PR feat(miner-governor): wire the gated-submission trigger into the driving loop's handoff signal (#2337) #5054 (touched the same file, same shape of change) actually merged with codecov/patch: pass and codecov/project: pass, confirming this is a non-issue in practice, not a silent gap.
  • npm audit --audit-level=moderate — no dependency changes.

Safety

  • No secrets/wallets/hotkeys/trust-scores exposed.
  • Not wired into any automatic schedule (same as its predecessor) — this is pure, injected-dependency logic with no live call site yet.
  • Not an API/OpenAPI/MCP/UI surface change.
  • Fail-closed on every malformed-input path (tested).

Notes

Read the full #2337 issue text directly (not just PR #5054's own paraphrase of it) before scoping this, specifically to check whether "root-side server/CLI integration" meant the gittensory root src/ server or the miner's own CLI — traced runIterateLoop's actual (zero) call sites to confirm the real remaining gap before writing any code, rather than guessing an architecture.

… a handoff (#2337)

Adds prepareOpenPrSubmission to harness-submission-trigger.js: bridges a
completed handoff through evaluateAndRecordHarnessSubmissionTrigger to a
submission-READY payload -- the exact input shape buildOpenPrSpec (root
src/mcp/local-write-tools.ts) expects (repoFullName/base/head/title/
body/draft). On allow:true returns { ready: true, openPrInput, ... };
on allow:false returns { ready: false, ... } without requiring a source
branch at all, since a blocked candidate never needs one. Fails closed
on a missing PR title/base immediately, and on a missing handoff
branchRef only once allow:true is known (the audit trail still records
the gate's own decision even when the spec-build step itself fails).

Does not call buildOpenPrSpec directly -- that remains unreachable from
this portable package (same cross-package-boundary reason self-review-
adapter.ts's slop injection exists). A real root-side/MCP call site
(e.g. the existing gittensory_open_pr tool) takes openPrInput from a
ready:true result and passes it through. The CLI/driver entrypoint that
instantiates a real CodingAgentDriver and runs the loop end to end with
live credentials still does not exist in this package -- separate,
larger scope from this decision-to-payload bridge.
@superagent-security

Copy link
Copy Markdown
Contributor

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

@cloudflare-workers-and-pages

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 a8cc316 Commit Preview URL

Branch Preview URL
Jul 11 2026, 02:22 PM

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.20%. Comparing base (e2bc19b) to head (a8cc316).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5091   +/-   ##
=======================================
  Coverage   94.20%   94.20%           
=======================================
  Files         470      470           
  Lines       39736    39736           
  Branches    14501    14501           
=======================================
  Hits        37435    37435           
  Misses       1645     1645           
  Partials      656      656           
Flag Coverage Δ
shard-1 46.40% <ø> (-0.02%) ⬇️
shard-2 33.48% <ø> (-0.12%) ⬇️
shard-3 31.16% <ø> (-0.18%) ⬇️
shard-4 33.05% <ø> (+0.23%) ⬆️
shard-5 33.45% <ø> (-0.10%) ⬇️
shard-6 45.10% <ø> (+0.19%) ⬆️

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

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gittensory-orb gittensory-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 11, 2026
@JSONbored JSONbored linked an issue Jul 11, 2026 that may be closed by this pull request
5 tasks
@gittensory-orb

gittensory-orb Bot commented Jul 11, 2026

Copy link
Copy Markdown

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-11 14:26:29 UTC

3 files · 2 AI reviewers · 2 blockers · readiness 93/100 · CI green · unstable

⏸️ Suggested Action - Manual Review

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.

Review summary
Adds `prepareOpenPrSubmission`, a pure bridge from a handoff candidate through the existing `evaluateAndRecordHarnessSubmissionTrigger` gate to a `buildOpenPrSpec`-shaped payload. Tracing the logic: base/title are validated and throw before the gate call (and before any ledger write, confirmed by the test asserting zero events), the gate call always records exactly one audit event regardless of outcome, and `branchRef` is only required once `decision.allow` is true, so a blocked candidate with no branch never throws for the wrong reason — this matches the PR description precisely. Property access on `candidate.repoFullName` and `candidate.handoffPacket.branchRef` is safe because `evaluateAndRecordHarnessSubmissionTrigger` (called first) already validates both as present/object before this function ever reads them. Tests are thorough and exercise the real code paths (ready:true shaping, ready:false short-circuit without requiring a branch, both fail-closed throws, ledger-write timing, trimming, and defaulting), and the function itself is not yet wired to any live call site, which the description honestly discloses as out of scope.

Nits — 5 non-blocking
  • The JSDoc/type comment on `prepareOpenPrSubmission` (harness-submission-trigger.js) says handoffPacket only needs `branchRef?: string`, but relies on `evaluateAndRecordHarnessSubmissionTrigger`'s stricter validation for object-ness — fine functionally, just worth a one-line note that the two functions' candidate shapes are coupled.
  • `candidate.draft === true` silently coerces any non-boolean truthy value (e.g. the string `"true"`) to `false` with no validation error — reasonable but undocumented; a one-line comment on the strictness would help future readers.
  • Since this function has no real caller yet (by the PR's own admission), consider linking the tracking issue for the root-side `gittensory_open_pr` call site directly in the JSDoc so it's easy to find when that wiring lands.
  • Given branchRef/base/title/repoFullName are all independently trimmed inline, a tiny shared `trimmedStringOrEmpty` helper could reduce repetition across this function and `evaluateAndRecordHarnessSubmissionTrigger`, though this is a minor DRY nit given the small scope.
  • nit: packages/gittensory-miner/lib/harness-submission-trigger.d.ts:45 duplicates the root buildOpenPrSpec input contract by hand, so this type can drift unless the later root-side wiring adds a contract check against the actual builder.

Concerns raised — review before merging

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.
Signal Result Evidence
Code review ❌ 2 blockers 2 reviewers, synthesized
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 46 registered-repo PR(s), 38 merged, 416 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 46 PR(s), 416 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
Improvement ✅ Minor risk: clean · value: minor — Code changes are accompanied by test evidence. LLM value judgment: moderate — The change correctly and narrowly advances the #2337 issue chain with well-targeted validation and thorough tests, but remains inert scaffolding since no real call site invokes it yet, as the PR itself discloses.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 46 PR(s), 416 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Explain no-issue PR.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
[BETA] Chat with Gittensory

Ask 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.

  • @gittensory ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @gittensory chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @gittensory mention with a real question is routed to the closest matching read-only command automatically -- no exact syntax required.

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.

  • Re-run Gittensory review

@JSONbored JSONbored self-assigned this Jul 11, 2026
@gittensory-orb gittensory-orb Bot added the manual-review Gittensor contributor context label Jul 11, 2026
@JSONbored JSONbored merged commit 86d1338 into main Jul 11, 2026
20 checks passed
@JSONbored JSONbored deleted the feat/harness-open-pr-submission-2337 branch July 11, 2026 14:32
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. manual-review Gittensor contributor context

Projects

Development

Successfully merging this pull request may close these issues.

maintainer: wire the submission-gate trigger into the harness driving loop

1 participant