Skip to content

feat(miner): build the coding-task-spec (title/instructions/acceptanceCriteriaPath) (#5132) - #5239

Merged
JSONbored merged 1 commit into
mainfrom
feat/coding-task-spec-5132
Jul 12, 2026
Merged

feat(miner): build the coding-task-spec (title/instructions/acceptanceCriteriaPath) (#5132)#5239
JSONbored merged 1 commit into
mainfrom
feat/coding-task-spec-5132

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Advances Wire CLI dispatch for the real attempt pipeline (attempt command) #5132 (maintainer-only, epic Epic: Miner Wave 3.5 — Wire the autonomous loop end-to-end #5130, Wave 3.5). The second gap discovered alongside Wire CLI dispatch for the real attempt pipeline (attempt command) #5132's CLI wiring (noted in that issue's own comment thread): 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 — "actually writing it into the attempt's worktree is the worktree primitive's job", per its own header. Adds coding-task-spec.js, the caller that finally does that.
  • buildCodingTaskFeasibility computes a real FeasibilityGateResult from 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). issueStatus is left to feasibilityInputFromPreStartCheck'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 for SelfReviewContext's own bounties/issueQuality gap (neither has a legitimate GitHub-fetchable data source for the miner yet).
  • buildCodingTaskAcceptanceCriteria + writeAcceptanceCriteriaFile compose the document and write it for real — only on a go verdict, per the module's own design (raise/avoid means the attempt should not start; the caller is expected to abandon, not proceed with no real acceptance-criteria file on disk).
  • buildCodingTaskSpec is the full composition: feasibility → acceptance criteria → (if authorized) write the file → instructions text. Returns ready: false with the computed verdict when raise/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

resolveDuplicateClusterRisk here does NOT apply #5145's >= 2 pull_request items threshold. That gate exists specifically to stop inDuplicateCluster (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 typecheck
  • npm run test:coverage locally (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 shared sanitizePromptPacketField scrubber, the write-only-on-go gate (including confirming nothing is written on raise/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.ts
  • npm run build:miner + npm run test:miner-pack
  • npm audit --audit-level=moderate
  • npm run test:workers / npm run build:mcp / npm run test:mcp-pack / npm run ui:* — skipped, no src/**, apps/**, or MCP-surface files touched.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • N/A — no auth/cookie/CORS/GitHub App/Cloudflare/session changes.
  • N/A — no UI changes.

Notes

…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.
@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 c55e37c Commit Preview URL

Branch Preview URL
Jul 12 2026, 10:38 AM

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.34%. Comparing base (7a423be) to head (c55e37c).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

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           
Flag Coverage Δ
shard-1 46.28% <ø> (-0.13%) ⬇️
shard-2 34.35% <ø> (-0.14%) ⬇️
shard-3 30.85% <ø> (-0.15%) ⬇️
shard-4 33.28% <ø> (-0.02%) ⬇️
shard-5 33.58% <ø> (-0.10%) ⬇️
shard-6 45.18% <ø> (+0.30%) ⬆️

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.

@JSONbored JSONbored self-assigned this Jul 12, 2026
@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 12, 2026
@JSONbored
JSONbored merged commit 199a995 into main Jul 12, 2026
20 checks passed
@JSONbored
JSONbored deleted the feat/coding-task-spec-5132 branch July 12, 2026 10:43
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).
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.

1 participant