Skip to content

feat(miner): consult selfLoopAutonomy in decideNextAction's pass-to-handoff step - #6581

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:sn-6560-autonomy-handoff
Jul 16, 2026
Merged

feat(miner): consult selfLoopAutonomy in decideNextAction's pass-to-handoff step#6581
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:sn-6560-autonomy-handoff

Conversation

@davion-knight

Copy link
Copy Markdown
Contributor

Summary

  • decideNextActionWithReason had no notion of autonomy — its own header called that out as a deferred gap, and a clean predicted-gate pass was the only path to handoff regardless of what the operator configured. AmsPolicySpec: add selfLoopAutonomy config field (default auto) #6559 landed AmsPolicySpec.selfLoopAutonomy; this wires it into the decision and threads it end-to-end.
  • The new check narrows step 3 of the precedence ladder ONLY:
    • "auto" (or unset) — unchanged handoff, no requiresApproval.
    • "auto_with_approval" — still a handoff, plus requiresApproval: true (mirrors settings/autonomy.ts's autonomyRequiresApproval).
    • "observe" — abandons with the new autonomy_observe_only reason, whose message notes a clean pass was reached and the configured level is what stopped it. Nothing went wrong here, so it deliberately does not reuse self_review_ambiguous's (or any other reason's) wording.
  • Steps 1 and 2 still win over every levelrejectionSignaled disengages silently and an ambiguous self-review abandons, even under "observe". Steps 4-6 (iteration ceiling, cost ceiling, no-progress) are likewise untouched: autonomy gates the pass→handoff transition and nothing else, never iteration count or write-action scope.
  • autonomyLevel is a true no-op when unset. It's optional on IterationState and treated as "auto" when undefined, mirroring costCeilingReached's own precedent, so every pre-existing hand-built IterationState fixture across the suite keeps its exact prior decision.
  • Plumbing follows rejectionSignaled's existing end-to-end path exactly: IterateLoopInput.autonomyLevel is copied verbatim into the per-iteration IterationState in runIterateLoopCore, and buildAttemptLoopInput maps amsPolicySpec.selfLoopAutonomy into it the same way it already maps maxIterations/maxTurnsPerIteration.

Closes #6560

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves — Closes #6560.

Validation

  • git diff --check
  • npm run typecheck — 0 errors
  • npm run test:coverage locally; codecov/patch requires ≥99% of changed lines AND branches — verified line-by-line against this diff's exact added lines in iterate-policy.ts: zero uncovered statements, zero uncovered branches (all three autonomy levels plus the unset arm are exercised).
  • npm run build --workspace @loopover/engine
  • npm run test --workspace @loopover/engine588/588 pass (includes the new iterate-policy.test.ts autonomy cases)
  • Blast radius: every root test touching iterate-policy/iterate-loop/buildAttemptLoopInput137/137 pass
  • npx eslint on every changed file — 0 errors
  • New or changed behavior has unit tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • npm audit --audit-level=moderate could not complete in this environment — the registry audit endpoint was unreachable (npm error audit endpoint returned an error), not a reported advisory. This PR adds no dependencies.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests — n/a, no auth/session surface is touched.
  • API/OpenAPI/MCP behavior is updated and tested where needed — n/a, no API/MCP surface changes.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Notes for review

Dual test suites, per the engine convention and the issue's own Codecov caveat: test/unit/engine-iterate-policy-autonomy.test.ts (the vitest mirror importing src/, which is what codecov/patch actually measures for packages/loopover-engine/src/**) and packages/loopover-engine/test/iterate-policy.test.ts (node:test, required to keep npm run test --workspace @loopover/engine green in test:ci).

One necessary test update: miner-attempt-input-builder.test.ts's exhaustive toEqual on the built IterateLoopInput now expects the new autonomyLevel field (18 keys vs 17). That assertion is intentionally exact, so it correctly caught the addition.

The stale AUTONOMY DIAL (not yet wired) header comment in iterate-policy.ts is updated to describe the wiring it now documents.

…andoff step

decideNextActionWithReason had no notion of autonomy -- its own header called
that out as a deferred gap, and a clean predicted-gate pass was the only path
to handoff regardless of what the operator configured. JSONbored#6559 landed
AmsPolicySpec.selfLoopAutonomy; this wires it into the decision and threads it
end-to-end.

The new check narrows step 3 of the precedence ladder ONLY:
- "auto" (or unset): unchanged handoff, no requiresApproval.
- "auto_with_approval": still a handoff, plus requiresApproval: true.
- "observe": abandons with the new autonomy_observe_only reason, whose message
  notes a clean pass WAS reached and the configured level is what stopped it --
  nothing went wrong, so it does not reuse any existing reason's wording.

Steps 1 and 2 are untouched and still win over every level: rejectionSignaled
disengages silently, and an ambiguous self-review abandons, even under
"observe". Steps 4-6 (iteration ceiling, cost ceiling, no-progress) are
likewise unchanged -- autonomy gates the pass->handoff transition and nothing
else, never iteration count or write-action scope.

autonomyLevel is optional on IterationState and treated as "auto" when unset,
mirroring costCeilingReached's own precedent, so every pre-existing hand-built
IterationState fixture keeps its exact prior decision. A regression test asserts
an omitted field and an explicit "auto" produce deep-equal decisions.

Plumbing follows rejectionSignaled's existing end-to-end path exactly:
IterateLoopInput.autonomyLevel is copied verbatim into the per-iteration
IterationState in runIterateLoopCore, and buildAttemptLoopInput maps
amsPolicySpec.selfLoopAutonomy into it the same way it already maps
maxIterations/maxTurnsPerIteration.

Closes JSONbored#6560
@davion-knight
davion-knight requested a review from JSONbored as a code owner July 16, 2026 15:06
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.64%. Comparing base (3ac9501) to head (3fa54c7).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6581      +/-   ##
==========================================
+ Coverage   93.62%   93.64%   +0.01%     
==========================================
  Files         678      678              
  Lines       67959    67964       +5     
  Branches    18675    18678       +3     
==========================================
+ Hits        63628    63642      +14     
+ Misses       3360     3347      -13     
- Partials      971      975       +4     
Flag Coverage Δ
shard-1 43.87% <0.00%> (-0.01%) ⬇️
shard-2 36.92% <20.00%> (-0.01%) ⬇️
shard-3 32.44% <0.00%> (-0.01%) ⬇️
shard-4 34.82% <0.00%> (+0.17%) ⬆️
shard-5 31.57% <0.00%> (+0.55%) ⬆️
shard-6 45.46% <100.00%> (-0.28%) ⬇️

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

Files with missing lines Coverage Δ
packages/loopover-engine/src/miner/iterate-loop.ts 83.33% <ø> (ø)
...ckages/loopover-engine/src/miner/iterate-policy.ts 58.62% <100.00%> (+46.12%) ⬆️
...ckages/loopover-miner/lib/attempt-input-builder.js 100.00% <ø> (ø)

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 16, 2026
@loopover-orb

loopover-orb Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-16 15:17:08 UTC

6 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This wires the previously-deferred selfLoopAutonomy check into decideNextActionWithReason's step 3 (pass->handoff), threading it through IterationState, IterateLoopInput, and buildAttemptLoopInput exactly as described, with an unset level treated as "auto" for backward compatibility. The precedence ladder logic is correct: rejectionSignaled and ambiguous self-review still short-circuit before step 3, and the new observe/auto_with_approval branches only touch the pass path. Test coverage is thorough, covering all three autonomy levels, the no-op default case, and non-interference with higher-precedence steps and ceilings.

Nits — 4 non-blocking
  • The duplicate test suites in test/unit/engine-iterate-policy-autonomy.test.ts and packages/loopover-engine/test/iterate-policy.test.ts covering nearly identical cases add maintenance overhead going forward — consider consolidating once codecov/patch collection is unified across both suites.
  • packages/loopover-engine/src/miner/iterate-policy.ts: the `AbandonReason` union and `IterateLoopDecision.requiresApproval` additions are fine, but verify downstream consumers of `AbandonReason` (e.g. any exhaustive switch over abandon reasons) handle the new `autonomy_observe_only` case rather than falling through silently.
  • Consider factoring the three-way autonomyLevel branch in iterate-policy.ts into a small helper (e.g. `applyAutonomyGate`) if a fourth level is ever added, though at 3 branches this isn't urgent.
  • Double check that callers consuming `IterateLoopDecision.requiresApproval` (outside this diff) actually gate on it — the plumbing here only sets the flag, it doesn't enforce approval itself.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #6560
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 (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 164 registered-repo PR(s), 107 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor davion-knight; Gittensor profile; 164 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The diff adds autonomyLevel to IterationState, requiresApproval to IterateLoopDecision, and the autonomy_observe_only AbandonReason, then narrows exactly the step-3 pass->handoff branch per the three specified levels while leaving other precedence steps untouched, and plumbs the field through IterateLoopInput/runIterateLoopCore and buildAttemptLoopInput's selfLoopAutonomy mapping. Tests cover all

Review context
  • Author: davion-knight
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 164 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

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

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit 7a275c7 into JSONbored:main Jul 16, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iterate-policy: consult selfLoopAutonomy in decideNextAction's pass-to-handoff step

1 participant