feat(miner): build the coding-task-spec (title/instructions/acceptanceCriteriaPath) (#5132) - #5239
Merged
Merged
Conversation
…eCriteriaPath) (#5132) The second gap discovered alongside #5132's CLI wiring: IterateLoopInput's title/instructions/acceptanceCriteriaPath had no builder anywhere in this package. packages/gittensory-engine/src/miner/acceptance-criteria.ts already composes a PromptPacket + FeasibilityGateResult into an immutable AcceptanceCriteria document, but deliberately does not write it -- "that's the worktree primitive's job" per its own header. This module is that caller. buildCodingTaskFeasibility computes a real FeasibilityGateResult from signals the miner already has: whether the issue is present in the fetched context, its real claim status (the claim ledger), and its real duplicate-cluster risk (buildCollisionReport). issueStatus is left to feasibilityInputFromPreStartCheck's own documented "ready" default when quality data is unavailable -- the same honest-default precedent #5145 established for SelfReviewContext's own bounties/issueQuality gap. buildCodingTaskAcceptanceCriteria + writeAcceptanceCriteriaFile compose and write the real file -- only for a go verdict, per the module's own design (raise/avoid means the attempt should not start). Deliberately duplicate-cluster risk here does NOT apply #5145's ">= 2 pull_request items" threshold: that gate exists to stop self-review inDuplicateCluster from false-flagging one legitimately-closing PR. Feasibility asks a different question -- should this attempt even start -- where any existing PR already working the issue is a real caution signal, documented inline.
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | c55e37c | Commit Preview URL Branch Preview URL |
Jul 12 2026, 10:38 AM |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5239 +/- ##
=======================================
Coverage 94.34% 94.34%
=======================================
Files 473 473
Lines 39982 39982
Branches 14576 14576
=======================================
Hits 37722 37722
Misses 1585 1585
Partials 675 675
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
10 tasks
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
Closes #5132 The final assembly: attempt-cli.js now fetches a real SelfReviewContext (#5145), builds a real coding-task spec (#5239, blocking on an infeasible verdict), resolves the real AmsPolicySpec execution policy (#5249, extended here with maxIterations/maxTurnsPerIteration -- the same operator-risk-policy gap capLimits/submissionMode/slopThreshold already covered), assembles the real IterateLoopInput + Governor chokepoint context, and calls runMinerAttempt for real -- the first point in this epic where a real coding agent actually executes rather than every path ending in a reported block. New attempt-input-builder.js holds the two pure composers (buildAttemptGovernorContext, buildAttemptLoopInput) so the assembly logic is independently unit-tested, mirroring coding-task-spec.js's own precedent. Real outcomes now surface distinct exit codes: 0 (submitted), 7 (abandon), 8 (stale), 9 (blocked by submission gate), 10 (governed), plus the existing 4 (blocked_infeasible, repurposed from the old blocked_missing_prerequisite placeholder), 5 (rejection_signaled), 6 (worktree_preparation_failed). The worktree is cleaned up on submission, retained on any other real outcome for post-mortem inspection (cleanupAttemptWorktree's own retention policy). KNOWN, DOCUMENTED GAPS (not fabricated -- see attempt-input-builder.js and attempt-cli.js's own header comments): - governor.killSwitchRepoPaused only checks the GLOBAL env-var kill switch; a real per-repo .gittensory-miner.yml pause needs miner-goal-spec.js (#5255, open) wired in as a fast-follow. - governor.convergenceInput is an honest first-attempt-shaped literal, not a real per-issue attempt-history query -- attempt-log.js's schema has no repo+issue index, and reenqueue counts aren't tracked anywhere yet (non-convergence.ts's own header: that belongs on the portfolio-queue table once it grows attempt-history columns, a real separate schema change). This closes #5132 for the core attempt pipeline; #5135 (the autonomous supervising loop) remains as separate, explicitly-flagged safety-critical follow-up work.
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
Closes #5132 The final assembly: attempt-cli.js now fetches a real SelfReviewContext (#5145), builds a real coding-task spec (#5239, blocking on an infeasible verdict), resolves the real AmsPolicySpec execution policy (#5249, extended here with maxIterations/maxTurnsPerIteration -- the same operator-risk-policy gap capLimits/submissionMode/slopThreshold already covered), assembles the real IterateLoopInput + Governor chokepoint context, and calls runMinerAttempt for real -- the first point in this epic where a real coding agent actually executes rather than every path ending in a reported block. New attempt-input-builder.js holds the two pure composers (buildAttemptGovernorContext, buildAttemptLoopInput) so the assembly logic is independently unit-tested, mirroring coding-task-spec.js's own precedent. Real outcomes now surface distinct exit codes: 0 (submitted), 7 (abandon), 8 (stale), 9 (blocked by submission gate), 10 (governed), plus the existing 4 (blocked_infeasible, repurposed from the old blocked_missing_prerequisite placeholder), 5 (rejection_signaled), 6 (worktree_preparation_failed). The worktree is cleaned up on submission, retained on any other real outcome for post-mortem inspection (cleanupAttemptWorktree's own retention policy). KNOWN, DOCUMENTED GAPS (not fabricated -- see attempt-input-builder.js and attempt-cli.js's own header comments): - governor.killSwitchRepoPaused only checks the GLOBAL env-var kill switch; a real per-repo .gittensory-miner.yml pause needs miner-goal-spec.js (#5255, open) wired in as a fast-follow. - governor.convergenceInput is an honest first-attempt-shaped literal, not a real per-issue attempt-history query -- attempt-log.js's schema has no repo+issue index, and reenqueue counts aren't tracked anywhere yet (non-convergence.ts's own header: that belongs on the portfolio-queue table once it grows attempt-history columns, a real separate schema change). This closes #5132 for the core attempt pipeline; #5135 (the autonomous supervising loop) remains as separate, explicitly-flagged safety-critical follow-up work.
JSONbored
added a commit
that referenced
this pull request
Jul 12, 2026
…5261) * feat(miner): wire the real runMinerAttempt call into attempt-cli.js Closes #5132 The final assembly: attempt-cli.js now fetches a real SelfReviewContext (#5145), builds a real coding-task spec (#5239, blocking on an infeasible verdict), resolves the real AmsPolicySpec execution policy (#5249, extended here with maxIterations/maxTurnsPerIteration -- the same operator-risk-policy gap capLimits/submissionMode/slopThreshold already covered), assembles the real IterateLoopInput + Governor chokepoint context, and calls runMinerAttempt for real -- the first point in this epic where a real coding agent actually executes rather than every path ending in a reported block. New attempt-input-builder.js holds the two pure composers (buildAttemptGovernorContext, buildAttemptLoopInput) so the assembly logic is independently unit-tested, mirroring coding-task-spec.js's own precedent. Real outcomes now surface distinct exit codes: 0 (submitted), 7 (abandon), 8 (stale), 9 (blocked by submission gate), 10 (governed), plus the existing 4 (blocked_infeasible, repurposed from the old blocked_missing_prerequisite placeholder), 5 (rejection_signaled), 6 (worktree_preparation_failed). The worktree is cleaned up on submission, retained on any other real outcome for post-mortem inspection (cleanupAttemptWorktree's own retention policy). KNOWN, DOCUMENTED GAPS (not fabricated -- see attempt-input-builder.js and attempt-cli.js's own header comments): - governor.killSwitchRepoPaused only checks the GLOBAL env-var kill switch; a real per-repo .gittensory-miner.yml pause needs miner-goal-spec.js (#5255, open) wired in as a fast-follow. - governor.convergenceInput is an honest first-attempt-shaped literal, not a real per-issue attempt-history query -- attempt-log.js's schema has no repo+issue index, and reenqueue counts aren't tracked anywhere yet (non-convergence.ts's own header: that belongs on the portfolio-queue table once it grows attempt-history columns, a real separate schema change). This closes #5132 for the core attempt pipeline; #5135 (the autonomous supervising loop) remains as separate, explicitly-flagged safety-critical follow-up work. * fix(miner): use a real FocusManifest fixture in attempt-cli tests CI's typecheck (not caught by an earlier stale local tsc run -- incremental cache silently no-op'd) correctly failed: the hand-rolled {present, settings, gate, warnings} manifest fixture doesn't satisfy FocusManifest's real shape (source, wantedPaths, preferredLabels, linkedIssuePolicy, and 8 more required fields). Uses the engine's own parseFocusManifest(undefined) to build a genuinely valid absent manifest instead, and drops the `as never` cast in miner-attempt-input-builder.test.ts that was silently working around the same gap there. * fix(miner): use a real RepositoryRecord shape in attempt-cli test fixtures CI's typecheck (again not caught locally -- verified this time with a genuinely fresh tsc run, all .tsbuildinfo caches cleared) correctly failed: the hand-rolled repo fixture used the wrong field names entirely (private/ownerLogin) instead of RepositoryRecord's real shape (isPrivate/owner, plus required isInstalled/isRegistered).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
IterateLoopInput'stitle/instructions/acceptanceCriteriaPathhad no builder anywhere in this package.packages/gittensory-engine/src/miner/acceptance-criteria.tsalready composes aPromptPacket+FeasibilityGateResultinto an immutableAcceptanceCriteriadocument, but deliberately does not write it — "actually writing it into the attempt's worktree is the worktree primitive's job", per its own header. Addscoding-task-spec.js, the caller that finally does that.buildCodingTaskFeasibilitycomputes a realFeasibilityGateResultfrom signals the miner already has: whether the issue is present in the fetched context (Build a SelfReviewContext fetcher for the miner's self-review pass #5145), its real claim status (the claim ledger), and its real duplicate-cluster risk (buildCollisionReport, the same function Build a SelfReviewContext fetcher for the miner's self-review pass #5145 exported to the public barrel).issueStatusis left tofeasibilityInputFromPreStartCheck's own documented"ready"default when quality data is unavailable — the same honest-default precedent Build a SelfReviewContext fetcher for the miner's self-review pass #5145 established forSelfReviewContext's ownbounties/issueQualitygap (neither has a legitimate GitHub-fetchable data source for the miner yet).buildCodingTaskAcceptanceCriteria+writeAcceptanceCriteriaFilecompose the document and write it for real — only on agoverdict, per the module's own design (raise/avoidmeans the attempt should not start; the caller is expected to abandon, not proceed with no real acceptance-criteria file on disk).buildCodingTaskSpecis the full composition: feasibility → acceptance criteria → (if authorized) write the file → instructions text. Returnsready: falsewith the computed verdict whenraise/avoid, so the eventual caller (attempt-cli.js, follow-up work) can report why an attempt didn't start rather than silently doing nothing.A deliberate divergence from #5145 worth flagging for review
resolveDuplicateClusterRiskhere does NOT apply #5145's>= 2 pull_request itemsthreshold. That gate exists specifically to stopinDuplicateCluster(self-review: "does MY OWN just-submitted PR look redundant") from false-flagging the ordinary case of one PR already legitimately closing the issue. Feasibility asks a genuinely different question — "should I even START working on this issue" — where an issue already having any open PR against it (buildCollisionReport's pairwise "shared linked issue" rule, which fires at"high"for exactly one PR) is a real caution signal, not a false positive to filter out. Documented inline in the code; flagging here too since it's an easy thing to assume should be reused verbatim.Validation
npm run typechecknpm run test:coveragelocally (743 test files, 0 failures, 14,712 tests). 14 new tests: feasibility verdicts for go/claimed/duplicate-cluster/not-found paths, the documented "ready" default with no fabricated issue-quality data, sanitization of unsafe economic/identity terms through the sharedsanitizePromptPacketFieldscrubber, the write-only-on-go gate (including confirming nothing is written onraise/avoid), and a REGRESSION test proving the full composed spec produces a real file on disk with the expected content.npx tsx scripts/check-engine-parity.tsnpm run build:miner+npm run test:miner-packnpm audit --audit-level=moderatenpm run test:workers/npm run build:mcp/npm run test:mcp-pack/npm run ui:*— skipped, nosrc/**,apps/**, or MCP-surface files touched.Safety
Notes
attempt-cli.js'srunAttempt— that final assembly (combining this, the worktree preparation from the prior PR,rejectionSignaled, and Build a SelfReviewContext fetcher for the miner's self-review pass #5145's fetcher into a realIterateLoopInput) is the next follow-up.