← Skills

sui

sui

The chain half — Move packages generated from schema/sui.tql, promise settlement on chain, stake verification and replay defence, and what is safe to read versus what spends. Use when touching pay/contracts/, move.ts codegen, promise:settle's on-chain leg, tasks:stake, sui-stake-verify, a publish or an UpgradeCap question, or any claim about what is deployed on testnet or mainnet. Triggers — "settle on chain", "mint the package", "is this deployed", "verify the stake", "generated Move", "can we upgrade the package".

Sui — generated Move, and the things that cost money

Generated stays generated

pay/contracts/generated/sources/*.move is emitted from schema/sui.tql by
move.ts. It stays byte-identical for anything touching money. A withdraw
in generated Move is forbidden by a green test; advance caps at state 2; the
module emitter ignores @sui:holds-value. Stake, refund-after-TTL,
settle-effect and soul-bound rewards belong in a hand-written companion
package
, meeting the generated module on origin. New codegen rules for those
is the wrong answer, and "zero new rules" is the deliverable rather than a
shortfall.

A proof is a READ; a settle may be a spend

Reading an object to prove a promise costs nothing and needs no funded key.
Never reach for funds to prove something a sui_getObject answers. Before
claiming any package is live, read it from a fullnode — and know that the
public fullnode JSON-RPC now refuses some methods (-32601); publicnode and
blockvision answer. suix_getNormalizedMoveFunction is unavailable, so
deployed signatures are unverified, not verified.

The two facts that have cost the most time

There is no UpgradeCap, so a redeploy is a fresh publish — a temp dir with
Published.toml dropped. A package whose struct gained a field cannot be served
by the already-deployed package; that is a republish, not a patch.

A key is not a role. PROMISE_ORACLE is not automatically the publisher of
any other package — measured by listing AdminCap owners, not assumed. A
companion package mints its own cap to the oracle at init.

Stake is not staking

tasks:stake is a burn on tags with no refund. Never call it "staking" in
copy. Its verification must bind the signed sender to the caller's own wallet
and spend the digest before the mark, or any signed-in caller replays any
wallet's public digest N times. The seam is spendVisitorStake
(one.ie/web/src/lib/stake-spend.ts) and every door must go through it —
a second door is how the first fix was found to be incomplete.

Cannot run

This is the skill where being wrong costs money, so the refusal is wider here
than anywhere else in the pool.

Say cannot-run in these states:

  • You cannot read the object. A proof is a sui_getObject, and the public
    fullnode JSON-RPC now refuses some methods with -32601. If publicnode and
    blockvision are also unreachable, the package's state is UNKNOWN. Never round
    an unreachable fullnode up to "deployed" — or down to "not deployed".
  • "Is it deployed?" was asked of the repo. A package id in Move.toml, a
    green codegen and a committed Published.toml describe an intent to publish,
    not a published package. The door here is SEALED rather than merely shut:
    NETWORK is absent from one.ie/web/wrangler.toml (grep count 0) and the
    testnet gateway's worker_public_key is empty on-chain, so nothing mints and
    therefore nothing settles. A settle reported from a sealed door is a
    settlement that never happened. The same refusal covers "did the stake
    verify" and "has this digest been spent" — both are on-chain facts, and
    reasoning about spendVisitorStake tells you what the code intends to do,
    never what it did.
  • The question is a deployed signature. suix_getNormalizedMoveFunction is
    unavailable, so a deployed function's shape cannot be read at all. Every such
    answer is unverified, which is cannot-run and not a pass.
  • Proving it would require a spend. A read costs nothing and needs no funded
    key; a settle may spend. If the only route to the answer moves funds, say so
    and stop — the decision to spend belongs to a person, never to this skill.
  • The key is assumed rather than listed. A key is not a role. If you have
    not listed the AdminCap owners, you do not know who can publish, and there
    is no mainnet key on record in this estate — confirm it, never fill it in.
  • The Move is not the generated Move. If you cannot establish that
    pay/contracts/generated/sources/*.move is byte-identical to what move.ts
    emits from schema/sui.tql, every claim about what the module does is about a
    file, not about the chain.

Return { ok: false, reason: "<which of those, and the line that says so>" }
and close with warn. "It probably published" is the most expensive sentence
this skill can produce.