Skip to content

Make privilege first-class across intents, CLI, and docs; add root emission intent#2910

Merged
IntiTechnologies merged 27 commits into
mainfrom
feat/intent-origins-root-ops
Jul 16, 2026
Merged

Make privilege first-class across intents, CLI, and docs; add root emission intent#2910
IntiTechnologies merged 27 commits into
mainfrom
feat/intent-origins-root-ops

Conversation

@unarbos

@unarbos unarbos commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Every intent now declares its chain origin (signed / subnet_owner / root) and an optional paired verify read, surfaced through list_tools() into the agent catalog (catalog/intents.json), the generated btcli tx help (own "Root (chain sudo)" panel, generated "Requires:" / "Verify afterwards:" footers), the pre-sign confirmation flow, and the generated docs (Origin column + Verify section per tx page).
  • First root intent: set_subnet_emission_enabled — takes --netuids 89,127, batches atomically via Utility.batch_all, wraps itself in Sudo.sudo, and replaces the raw-only escape hatch for AdminUtils.sudo_set_subnet_emission_enabled. Paired with a new subnet_emission_enabled read and a hyperparams-table entry so the flag shows next to subnet_is_active.
  • New codegen gate: every origin="root" intent must declare a verify read, and every declared verify must name a registered read — a privileged write can no longer ship without a way to check it.
  • Six owner-gated intents tagged origin="subnet_owner" (verified against the runtime): set_hyperparameter, start_call, trim_subnet, set_mechanism_count, set_subnet_identity, update_symbol.
  • Unified bt.Subtensor entry point: one class that is the blocking client when used directly (private loop on a daemon thread, cleaned up via GC finalizer — no close() needed) and the async Client when awaited or used with async with. Adds module-level bt.set_weights, re-points the v10 migration hints at Subtensor, and gives SyncClient weakref.finalize-based connection teardown.
  • Docs: hand-written hyperparameters/subnet-emission-enabled explainer and an "active vs emission-enabled" decision tree in the subnets guide; quickstart/migration/concepts guides rewritten around bt.Subtensor; site search and sidebar improvements; regenerated reference pages/catalogs. The generated Origin column now says "signed account" instead of "any signed key" (per review — signed is the dispatch-origin class, not blanket authorization).

Test plan

  • codegen.check --coverage / --names / --units / --namespaces all green (includes the new verify-integrity gate)
  • pytest: 952 passed, 1 skipped
  • ruff check / ruff format --check / ty check clean
  • generate.py --check: generated docs up to date
  • btcli tx set-subnet-emission-enabled --help renders privilege + verify footers; catalog JSON carries origin/verify

Made with Cursor

unarbos and others added 2 commits July 14, 2026 15:43
Co-authored-by: Cursor <cursoragent@cursor.com>
…ission intent.

Every intent now declares its chain origin (signed / subnet_owner / root)
and a paired verify read, surfaced in the tool catalog, btcli tx help and
pre-sign flow, and the generated docs. First root intent:
set_subnet_emission_enabled (multi-netuid batch_all under Sudo.sudo) with a
subnet_emission_enabled read and hyperparams entry, plus an
active-vs-emission-enabled decision tree in the subnets guide.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
subtensor Ready Ready Preview, Comment Jul 16, 2026 6:11pm

Request Review

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

🛡️ AI Review — Skeptic (security review)

VERDICT: SAFE

MEDIUM scrutiny: four-month-old account with high contribution volume, repository write access, substantial merged history, and no Gittensor association; branch targets main.

Static analysis covered privileged-call composition, nested dispatch results, runtime and precompile changes, hotkey-swap and leasing paths, SDK wallet/address handling, CI image publication, filesystem boundaries, and dependency updates. Root intents remain wrapped in Sudo.sudo, the runtime version is bumped, and trusted AI-review instructions were not modified.

Findings

No findings.

Conclusion

No malicious behavior or security vulnerability was found in the current PR.


🔍 AI Review — Auditor (domain review)

VERDICT: 👍

UNKNOWN gittensor association; established high-volume contributor with repository write access. Overlapping PRs are unrelated SDK, runtime-upgrade, and governance work.

The prior blocker is fixed: submit_shielded() now applies the shared root-call wrapper before fee estimation and signing, with a focused regression test confirming the encrypted inner call is Sudo.sudo(AdminUtils.sudo_set_subnet_emission_enabled(...)).

The PR description is substantive, and the runtime spec_version is bumped to 432. No auto-fixes were needed.

Findings

No findings.

Prior-comment reconciliation

  • 91320cef: addressedsubmit_shielded() now calls _wrap_root_call() before fee estimation and signing, and a focused regression test verifies the nested Sudo.sudo call.

Conclusion

The MEV-shielded and ordinary execution paths now preserve the same root-origin invariant. The prior blocking issue is addressed and the PR is ready.


📜 Previous run (superseded)
Sev File Finding Status
HIGH sdk/python/bittensor/executor.py:315 Root intents lose their sudo wrapper when MEV-shielded ✅ Addressed
submit_shielded() now calls _wrap_root_call() before fee estimation and signing, and a focused regression test verifies the nested Sudo.sudo call.

@github-actions github-actions 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.

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Comment thread website/apps/bittensor-website/scripts/generate.py Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

unarbos and others added 10 commits July 16, 2026 11:37
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…ixes, no diff

Co-authored-by: Cursor <cursoragent@cursor.com>
Consolidate pending PRs into staging
… and improve site search and sidebar.

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions 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.

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Comment thread website/apps/bittensor-website/scripts/generate.py Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

New /docs/sdk page covers the five core primitives with their easy
constructors. Ergonomics: Wallet("cold/hot") shorthand, wallet name
strings anywhere a wallet is accepted, and key-bearing objects accepted
wherever an ss58 address parameter is expected (reads and intents).

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions 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.

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Comment thread website/apps/bittensor-website/scripts/generate.py Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

@github-actions github-actions 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.

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Comment thread website/apps/bittensor-website/scripts/generate.py Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

as_ss58 no longer touches private keyfiles (wallet shapes resolve via
public_view); Subtensor subclasses SyncClient with a lazy loop thread so
attribute inspection has no side effects; the GC finalizer can no longer
deadlock on its own loop thread; the ss58 predicate is shared between
executor and reads; the removed-name hint for v10 bt.subtensor is
restored; Wallet slash names are validated.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rust: serde_with 3.21.0, rpassword 7.5.4, tracing-subscriber 0.3.20
(unpinned from =0.3.18). npm: js-yaml, svgo, minimatch, @babel/runtime
in-range; postcss 8.5.10 and prismjs 1.30.0 via resolutions (pinned by
next and refractor). Also declares the shiki dependency already present
in the lockfile for the upcoming /code viewer.

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions 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.

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

Comment thread website/apps/bittensor-website/scripts/generate.py Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

unarbos and others added 2 commits July 16, 2026 14:07
Treat Sudo/Proxy/Multisig inner Err as failure, share one teardown path for
explicit close and GC finalizer, open+focus mobile search on ⌘K, harden
set_weights shared clients, and centralize root Sudo wrapping with clearer
origin docs. Also regenerate tx pages and add the /code viewer.

Co-authored-by: Cursor <cursoragent@cursor.com>
…).

Port the merged staging fix so published localnet manifests use smoke-tested
platform digests, plus the supporting resolve/cleanup/smoke scripts from
#2919 that this branch lacked. Also take the leasing weight tests' direct
assert_ok! form that restores clippy.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

Co-authored-by: Cursor <cursoragent@cursor.com>
@IntiTechnologies

Copy link
Copy Markdown
Contributor

Resolved AI-review threads on signed-origin labeling: docs now use signed account (pallet role may apply) (not "any signed key").

v431 is already on devnet/testnet and proposed for mainnet; this bump lets
the release train redeploy and propose the follow-on SDK/docs/CI fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

Bring in the staging→main promotion: localnet publication, SS58 balance
precompile, leasing/hotkey-swap fixes, and dependency cleanups.

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	website/package.json
#	website/yarn.lock
…merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE

@github-actions github-actions 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.

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

wallet = as_wallet(wallet)
intent = _coerce_addresses(intent)
built = await intent.build(self.substrate, wallet)
call = built.call if isinstance(built, BuiltCall) else built

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.

[HIGH] Root intents lose their sudo wrapper when MEV-shielded

execute() wraps origin == "root" calls in Sudo.sudo, but submit_shielded() signs and encrypts the raw AdminUtils.sudo_* call. Since the CLI permits --mev-shield for any mutation, the new root intent follows this path and deterministically fails BadOrigin, despite being signed by the sudo account. Apply the same centralized wrapping invariant before fee estimation and signing, and add coverage for a shielded root intent.

Suggested change
call = built.call if isinstance(built, BuiltCall) else built
call = built.call if isinstance(built, BuiltCall) else built
if intent.origin == "root" and not _is_sudo_call(call):
call = await self.substrate.compose(generated_calls.Sudo.sudo(call=call))

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👎

Clone-upgrade failed the metadata drift gate after the staging merge and
spec bump; emit _generated from a local 432 node so committed files match.

Co-authored-by: Cursor <cursoragent@cursor.com>

@github-actions github-actions 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.

AI review — see the sticky summary comment for the verdict and the inline comments below for specific findings.

wallet = as_wallet(wallet)
intent = _coerce_addresses(intent)
built = await intent.build(self.substrate, wallet)
call = built.call if isinstance(built, BuiltCall) else built

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.

[HIGH] Root intents lose their sudo wrapper when MEV-shielded

execute() converts every origin == "root" intent into Sudo.sudo, but submit_shielded() signs this raw inner call. For set_subnet_emission_enabled, the decrypted extrinsic therefore dispatches AdminUtils.sudo_set_subnet_emission_enabled with a signed origin and fails BadOrigin. Apply the same wrapping invariant here before fee estimation and signing, and add a shielded-root regression test.

Suggested change
call = built.call if isinstance(built, BuiltCall) else built
call = built.call if isinstance(built, BuiltCall) else built
if intent.origin == "root" and not _is_sudo_call(call):
call = await self.substrate.compose(generated_calls.Sudo.sudo(call=call))

@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👎

submit_shielded skipped the root wrapping that plan/execute apply, so
decrypted AdminUtils root calls failed BadOrigin under a signed origin.

Co-authored-by: Cursor <cursoragent@cursor.com>
@IntiTechnologies IntiTechnologies merged commit 8586e65 into main Jul 16, 2026
46 of 47 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🔄 AI review updated — Skeptic: SAFE Auditor: 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants