You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The semantics accepted in #114 and implemented in #119 define:
fundOut: assets leave the account in the current transaction;
debt: the Capability increases the account?s repayment obligations, even when no asset leaves in the current transaction.
Those definitions resolved debt-increasing borrow, but they also made a residual authoring gap explicit.
Core currently has no valid authored state for:
The Capability author has reviewed the operation, but none of the current closed-set RiskLabels accurately applies.
Omitting risk is invalid, an explicit empty list is rejected, and a non-empty list may force the author to select a label known to be inaccurate.
Confirmed cases
aPriori claim
During requestRedeem, the owner?s aprMON shares are transferred into vault custody. The later claim settles that request and pays matured MON to the receiver.
The exposed claim transaction does not move an asset out of the account or create a repayment obligation. fundOut, debt, approval, and priceImpact therefore do not describe this Capability.
The adapter currently retains:
risk: ["fundOut"]
with a comment recording that the operation is inflow-only and that the label is a Registry-compatible placeholder. Although #119 has since added debt, that label does not fit claim because completion does not increase a repayment obligation.
FastLane has the same transaction shape. requestUnstake commits the shMON in an earlier transaction; after the epoch completes, completeUnstake only pays MON from FastLane to the owner.
The integration-branch comment says that fundOut ?does not fit,? notes that Registry rejects an empty risk set, calls the declaration the ?least-wrong placeholder,? and points to #12 and #104 for the pending ruling.
The declaration nevertheless remains:
risk: ["fundOut"]
The payout direction is supported by a real Monad-mainnet completion transaction documented in #158.
intent: "Complete a delayed unstaking request after epoch completion",
verb: "unstake",
params: completeUnstakeParams,
receipt: "completeUnstakeReceipt",
// This step is inflow-only: requestUnstake already committed the shMON, and
// completion only pays MON back to the owner. `fundOut` as settled in #114
// means assets leave the account in this transaction, so it does not fit,
// but Registry rejects an empty risk set and the closed set has no
// inflow-only entry. Kept as the least-wrong placeholder pending the ruling
// asked for in #12 and #104.
risk: ["fundOut"],
tags: ["staking","unstake","delayed"],
})
asynccompleteUnstake(){
return[this.staking.completeUnstake([])];
Why this needs a Core decision
load() exposes risk separately from free-form tags. A placeholder therefore becomes part of the structured contract an Agent reads rather than remaining an internal adapter comment.
Registry currently enforces a non-empty invariant: every registered Capability must provide at least one Core classification. This can prevent omitted classification, but the confirmed cases show that it can also force a known-inaccurate label when the closed set contains no applicable category.
?No current Core RiskLabel applies? is not a safety, trust, or execution-policy decision. Mandatory simulation, Receipt and Warning handling, pre-signing presentation, wallet review, and user approval remain unchanged.
It means only that none of the current Core-defined static danger categories accurately describes the operation.
Proposed direction
Keep the risk field required, but allow an explicitly authored empty list:
risk: []
For a Capability, define this as:
The author has reviewed the operation and determined that none of the current closed-set Core RiskLabels accurately applies.
The field remains required, missing or malformed metadata remains invalid, every non-empty member remains closed-set validated, and load() projects the authored empty list unchanged.
The public shape is already RiskLabel[], and Query stubs already project an empty list. This would not require a new TypeScript, JSON, or MCP data shape.
It would nevertheless be an Agent-facing semantic compatibility change. Consumers that rely on Registry?s runtime guarantee that every Capability has at least one RiskLabel would need to stop making that assumption, so the change should be documented and released accordingly.
The strongest objection is that an empty list could become an easy opt-out if contributors use it instead of analysing the operation or proposing a missing reusable danger semantic. The authoring rule below is intended to prevent that use.
Authoring decision rule
risk: [] must not be used merely because the existing labels are inconvenient or because the operation has not been fully analysed.
When no current RiskLabel accurately applies:
If the Capability exposes a recurring static danger that the current closed set cannot represent, contributors should raise a focused Core vocabulary issue.
If no current label applies and, after reviewing the operation?s static dangers, no distinct reusable danger semantic has been identified from the evidence, an explicitly authored risk: [] may represent that result.
If the classification remains uncertain, the contributor should request Core or maintainer review rather than use an inaccurate placeholder or treat risk: [] as a substitute for analysis.
If Core later defines an applicable RiskLabel, an existing risk: [] declaration should be replaced with that label.
Alternatives considered
Add fundIn
This preserves the non-empty invariant, and the FastLane author explicitly preferred this direction over risk: [] in #158 for that reason.
Its advantage is that every Capability continues to have at least one Core-defined classification. The tradeoff is that receiving funds is not itself a category of danger. fundIn would broaden RiskLabel toward a general asset-direction taxonomy, while the representation question may recur for operations that have neither an applicable danger label nor a pure-inflow shape.
Add a sentinel such as noApplicableRisk
This preserves a non-empty list and explicitly represents the author?s conclusion.
However, the sentinel is not a danger category and would require combination rules to reject contradictory states such as:
risk: ["noApplicableRisk","approval"]
It would mix classification status with the RiskLabel taxonomy.
Other alternatives
Making risk optional would conflate a deliberate decision with omitted metadata.
Free-form tags do not replace the structured risk contract exposed by load().
Structured severity, conditions, review status, or dynamic risk objects are outside this representation question.
Maintainer decisions requested
Should Core allow an explicitly authored risk: [] when none of the current closed-set RiskLabels applies, while keeping the field required?
If Core should preserve the non-empty invariant, an alternative accurate public representation would resolve the same adapter pressure without relying on known-inaccurate placeholders.
Should the canonical meaning and authoring guidance distinguish:
a reviewed operation for which no current danger category applies?
Should the focused Core implementation establish the public representation, validation, coverage, documentation, authoring rule, and changeset, while leaving adapter adoption to coordinated follow-up work?
Suggested acceptance coverage
For the maintainer-approved representation, the focused Core implementation should:
implement the representation while keeping risk required;
reject missing, malformed, and unknown metadata;
cover Registry registration, validation, and exact load() projection;
preserve compile-time required-field and closed-set guarantees;
update the canonical glossary, MCP documentation, and short Protocol-onboarding rule;
include the Core changeset and pass the full pnpm lint ? build ? typecheck ? test verification chain.
The focused Core PR may close this issue once the approved public contract and coverage land.
Adapter adoption is downstream work and should not block closure of the Core issue. aPriori adoption can be handled in a separately coordinated follow-up without expanding #159, while FastLane adoption should be coordinated with the existing #12/#158 contributors. Each affected adapter package can carry its own appropriate changeset.
Scope
This issue is limited to the Core authoring representation for a Capability when none of the current closed-set RiskLabels accurately applies.
It does not:
redesign the broader RiskLabel taxonomy;
define liquidation, leverage, severity, or dynamic account risk;
change Warnings, Receipts, simulation, or Agent policy;
require aPriori or FastLane implementation changes in the Core PR;
This issue extracts the shared residual Core question made explicit by the accepted #114/#119 semantics. It does not supersede the concrete adapter findings, implementation work, or attribution above.
This issue does not claim implementation ownership. A focused Core PR can follow the maintainer decision.
Problem
Moss requires every Capability to declare a
riskfield, but Registry rejects an empty list:The current closed set is:
The semantics accepted in #114 and implemented in #119 define:
fundOut: assets leave the account in the current transaction;debt: the Capability increases the account?s repayment obligations, even when no asset leaves in the current transaction.Those definitions resolved debt-increasing
borrow, but they also made a residual authoring gap explicit.Core currently has no valid authored state for:
Omitting
riskis invalid, an explicit empty list is rejected, and a non-empty list may force the author to select a label known to be inaccurate.Confirmed cases
aPriori
claimDuring
requestRedeem, the owner?s aprMON shares are transferred into vault custody. The laterclaimsettles that request and pays matured MON to the receiver.The exposed claim transaction does not move an asset out of the account or create a repayment obligation.
fundOut,debt,approval, andpriceImpacttherefore do not describe this Capability.The adapter currently retains:
with a comment recording that the operation is inflow-only and that the label is a Registry-compatible placeholder. Although #119 has since added
debt, that label does not fitclaimbecause completion does not increase a repayment obligation.Source:
moss/packages/protocols/apriori/src/adapter.ts
Lines 185 to 198 in 97df9c1
FastLane
completeUnstakeFastLane has the same transaction shape.
requestUnstakecommits the shMON in an earlier transaction; after the epoch completes,completeUnstakeonly pays MON from FastLane to the owner.The integration-branch comment says that
fundOut?does not fit,? notes that Registry rejects an empty risk set, calls the declaration the ?least-wrong placeholder,? and points to #12 and #104 for the pending ruling.The declaration nevertheless remains:
The payout direction is supported by a real Monad-mainnet completion transaction documented in #158.
Source:
moss/packages/protocols/fastlane/src/fastlane.ts
Lines 195 to 210 in 8357d33
Why this needs a Core decision
load()exposesriskseparately from free-formtags. A placeholder therefore becomes part of the structured contract an Agent reads rather than remaining an internal adapter comment.Registry currently enforces a non-empty invariant: every registered Capability must provide at least one Core classification. This can prevent omitted classification, but the confirmed cases show that it can also force a known-inaccurate label when the closed set contains no applicable category.
?No current Core RiskLabel applies? is not a safety, trust, or execution-policy decision. Mandatory simulation, Receipt and Warning handling, pre-signing presentation, wallet review, and user approval remain unchanged.
It means only that none of the current Core-defined static danger categories accurately describes the operation.
Proposed direction
Keep the
riskfield required, but allow an explicitly authored empty list:For a Capability, define this as:
The field remains required, missing or malformed metadata remains invalid, every non-empty member remains closed-set validated, and
load()projects the authored empty list unchanged.The public shape is already
RiskLabel[], and Query stubs already project an empty list. This would not require a new TypeScript, JSON, or MCP data shape.It would nevertheless be an Agent-facing semantic compatibility change. Consumers that rely on Registry?s runtime guarantee that every Capability has at least one RiskLabel would need to stop making that assumption, so the change should be documented and released accordingly.
The strongest objection is that an empty list could become an easy opt-out if contributors use it instead of analysing the operation or proposing a missing reusable danger semantic. The authoring rule below is intended to prevent that use.
Authoring decision rule
risk: []must not be used merely because the existing labels are inconvenient or because the operation has not been fully analysed.When no current RiskLabel accurately applies:
If the Capability exposes a recurring static danger that the current closed set cannot represent, contributors should raise a focused Core vocabulary issue.
The issue should provide concrete Capability evidence, define the proposed semantic boundary, compare existing labels and alternatives, and wait for a maintainer decision before implementation?the sequence demonstrated by [feature] Clarify RiskLabel semantics for debt-increasing lending capabilities #114/feat(core): add debt risk label #119.
If no current label applies and, after reviewing the operation?s static dangers, no distinct reusable danger semantic has been identified from the evidence, an explicitly authored
risk: []may represent that result.If the classification remains uncertain, the contributor should request Core or maintainer review rather than use an inaccurate placeholder or treat
risk: []as a substitute for analysis.If Core later defines an applicable RiskLabel, an existing
risk: []declaration should be replaced with that label.Alternatives considered
Add
fundInThis preserves the non-empty invariant, and the FastLane author explicitly preferred this direction over
risk: []in #158 for that reason.Its advantage is that every Capability continues to have at least one Core-defined classification. The tradeoff is that receiving funds is not itself a category of danger.
fundInwould broadenRiskLabeltoward a general asset-direction taxonomy, while the representation question may recur for operations that have neither an applicable danger label nor a pure-inflow shape.Add a sentinel such as
noApplicableRiskThis preserves a non-empty list and explicitly represents the author?s conclusion.
However, the sentinel is not a danger category and would require combination rules to reject contradictory states such as:
It would mix classification status with the RiskLabel taxonomy.
Other alternatives
riskoptional would conflate a deliberate decision with omitted metadata.fundOutto historical or flow-level outflow would contradict [feature] Clarify RiskLabel semantics for debt-increasing lending capabilities #114/feat(core): add debt risk label #119.riskcontract exposed byload().Maintainer decisions requested
Should Core allow an explicitly authored
risk: []when none of the current closed-set RiskLabels applies, while keeping the field required?If Core should preserve the non-empty invariant, an alternative accurate public representation would resolve the same adapter pressure without relying on known-inaccurate placeholders.
Should the canonical meaning and authoring guidance distinguish:
Should the focused Core implementation establish the public representation, validation, coverage, documentation, authoring rule, and changeset, while leaving adapter adoption to coordinated follow-up work?
Suggested acceptance coverage
For the maintainer-approved representation, the focused Core implementation should:
riskrequired;load()projection;pnpm lint?build?typecheck?testverification chain.The focused Core PR may close this issue once the approved public contract and coverage land.
Adapter adoption is downstream work and should not block closure of the Core issue. aPriori adoption can be handled in a separately coordinated follow-up without expanding #159, while FastLane adoption should be coordinated with the existing #12/#158 contributors. Each affected adapter package can carry its own appropriate changeset.
Scope
This issue is limited to the Core authoring representation for a Capability when none of the current closed-set RiskLabels accurately applies.
It does not:
Related work and attribution
fundOutboundary.debtsemantics.fundInover allowingrisk: []in order to preserve the non-empty invariant; this issue retains that position as an alternative for the Core decision.This issue extracts the shared residual Core question made explicit by the accepted #114/#119 semantics. It does not supersede the concrete adapter findings, implementation work, or attribution above.
This issue does not claim implementation ownership. A focused Core PR can follow the maintainer decision.