@adapt-toolkit/mufl 0.10.9 → 0.10.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,7 @@ config script {
6
6
  $current_transaction_info->#"current_transaction_info.mm",
7
7
  $identity_proof_document->#"identity_proof_document.mm",
8
8
  $lists->#"lists.mm",
9
+ $limits->#"limits.mm",
9
10
  $vector->#"vector.mm",
10
11
  $platform_type_id->#"platform_type_id.mm",
11
12
  $transaction_message_decoder->#"transaction_message_decoder.mm",
@@ -51,6 +52,7 @@ config script {
51
52
  $current_transaction_info->#"current_transaction_info.mm",
52
53
  $identity_proof_document->#"identity_proof_document.mm",
53
54
  $lists->#"lists.mm",
55
+ $limits->#"limits.mm",
54
56
  $vector->#"vector.mm",
55
57
  $platform_type_id->#"platform_type_id.mm",
56
58
  $transaction_message_decoder->#"transaction_message_decoder.mm",
@@ -0,0 +1,67 @@
1
+ // Governance wrapper for the per-packet limits primitive.
2
+ //
3
+ // The engine exposes a single dangerous primitive, _set_limits, which mutates the packet's
4
+ // committed limits. It is DANGEROUS, so a packet's code must grab() it to use it. Authorization for
5
+ // a limit change -- who may change limits, and under what conditions -- is entirely the packet
6
+ // developer's policy: this library provides only the MECHANISM (the raw application path), and the
7
+ // engine enforces the hard FLOOR (a change can never exceed the global ceilings). The wrapper does
8
+ // NOT impose or imply any particular authorization model (no built-in signature requirement); the
9
+ // developer composes whatever check their policy needs -- signed request, owner identity, multi-sig,
10
+ // ... -- around set_limits before applying a change. It follows the same inject-a-grabbed-primitive
11
+ // pattern as key_storage (the app grabs _set_limits and calls limits::init to bind it here).
12
+ //
13
+ // The engine primitive validates the {name -> count} dictionary shape, the canonical dimension
14
+ // names, and the [1, ceiling] ranges.
15
+ //
16
+ // Named tiers (for reference; resolved by the ENGINE, not this library): a transaction's source-level
17
+ // limits(...) clause also accepts three vetted bundles by name -- $limits::small, $limits::standard,
18
+ // $limits::heavy -- expanded at compile time by the clause. The engine's resolver is authoritative;
19
+ // the bundles are:
20
+ // $limits::small = { fuel_ops -> 10000, call_depth -> 64, constructed_elems -> 4000 }
21
+ // $limits::standard = { fuel_ops -> 100000, call_depth -> 256, constructed_elems -> 40000 }
22
+ // $limits::heavy = { fuel_ops -> 500000, call_depth -> 1024, constructed_elems -> 200000 }
23
+ // They bound the compute dimensions only; structural dimensions stay at the enclosing effective, and
24
+ // explicit entries after a tier override it pairwise. A conformance unit test pins the engine's
25
+ // value table red-on-drift; if a ratified change lands there, update this doc block to match.
26
+ library limits {
27
+
28
+ hidden {
29
+ // Placeholder for the injected primitive. If a packet calls a limits function without first
30
+ // grabbing _set_limits and injecting it via init, this aborts loudly rather than silently
31
+ // doing nothing.
32
+ _set_limits is (any -> nil) = fn (_: any) -> nil {
33
+ abort "limits: _set_limits primitive was not grabbed and injected (call limits::init)." when TRUE.
34
+ return NIL.
35
+ }
36
+ }
37
+
38
+ // Bind the grabbed _set_limits primitive. Called once from the packet's code:
39
+ // set = grab(_set_limits). limits::init ($_set_limits -> set).
40
+ init = fn (_:($_set_limits -> set: (any -> nil))) {
41
+ _set_limits -> set.
42
+ }
43
+
44
+ // Apply a {name -> count} limit change. This library provides the MECHANISM only -- authorization
45
+ // is the packet developer's responsibility: perform whatever check your policy requires (signed
46
+ // request, owner identity, multi-sig, ...) BEFORE calling this. The engine primitive still
47
+ // validates the dictionary shape, the canonical dimension names, and the [1, ceiling] ranges, so
48
+ // a change can never exceed the global ceilings regardless of the caller's policy.
49
+ set_limits = fn (new_limits: any) -> nil {
50
+ _set_limits new_limits.
51
+ }
52
+
53
+ // Packet-creation defaults. The SDK passes packet-creation options inside the init argument; by
54
+ // convention a packet that wants creation-time default limits reads a `limits` block ({name ->
55
+ // count}, the same shape as set_limits) from its init argument and applies it here, e.g. in the
56
+ // packet's init transaction:
57
+ //
58
+ // set = grab(_set_limits).
59
+ // limits::init ($_set_limits -> set).
60
+ // if (init_arg $limits) != NIL {
61
+ // limits::set_limits (init_arg $limits).
62
+ // }
63
+ //
64
+ // This is a REQUEST TO THE PACKET'S CODE, not an engine feature: a packet whose code ignores the
65
+ // block simply keeps the global defaults. The engine still enforces the [1, ceiling] floor on
66
+ // whatever is applied.
67
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adapt-toolkit/mufl",
3
- "version": "0.10.9",
3
+ "version": "0.10.10",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "description": "The MUFL toolchain: prebuilt `mufl` (REPL) and `mufl-compile` (compiler) engine binaries plus the MUFL stdlib, meta, and transactions trees they need at run time. Linux x64 only; the binaries are proprietary (AEFL) — see LICENSE and NOTICE.",
Binary file
Binary file
@@ -5,7 +5,10 @@
5
5
 
6
6
  library __t_wrapper loads libraries transaction, key_storage, transaction_queue, identity_proof_document_types, e2e {
7
7
 
8
- metadef t_trn: ($name->str, $targ->any).
8
+ // $__limits (optional): the per-call resource budget carried inside the signed message (see
9
+ // transaction::unsigned_message). Kept as `any+` here too so a budgeted message decodes; the
10
+ // engine validates and folds it. Absent = no budget.
11
+ metadef t_trn: ($name->str, $targ->any, $__limits->any+).
9
12
  metadef t_trn_extended: ($trn->t_trn, $is_signed->bool, $is_encrypted->bool, $is_e2e->bool+).
10
13
  metadef t_trn_message_info: (
11
14
  $decoded_envelope -> transaction::envelope::external::decoded_type || t_trn,
@@ -13,7 +13,12 @@ library transaction loads libraries key_utils, key_storage, identity_proof_docum
13
13
  // }
14
14
  // }
15
15
 
16
- metadef unsigned_message: ($name -> str, $targ -> any).
16
+ // $__limits (optional) is the per-call resource budget: a {name -> count} dictionary the engine
17
+ // folds into this transaction's effective limits (tighten-only). It rides INSIDE the signed
18
+ // message, so it is authenticated input -- a post-sign edit changes the message value-id and
19
+ // fails signature verification. Absent means no per-call budget (unchanged behaviour). The engine
20
+ // validates the dictionary (canonical dimension names, [1, ceiling]); the field type is `any+`.
21
+ metadef unsigned_message: ($name -> str, $targ -> any, $__limits -> any+).
17
22
  metadef signed_message: ($trn -> unsigned_message, $ptsignature -> crypto_signature).
18
23
  metadef encrypted_pt_signed_message: ($encrypted_message -> crypto_message, $ptsignature -> crypto_signature).
19
24
  metadef encrypted_em_signed_message: ($encrypted_message -> crypto_message, $emsignature -> crypto_signature).
@@ -81,7 +86,7 @@ library transaction loads libraries key_utils, key_storage, identity_proof_docum
81
86
  }
82
87
 
83
88
  hidden {
84
- sign = fn (_:($trn -> tn: ($name -> str, $targ -> any))) -> signed_message {
89
+ sign = fn (_:($trn -> tn: ($name -> str, $targ -> any, $__limits -> any+))) -> signed_message {
85
90
  signature = key_storage::default_sign (_value_id tn |).
86
91
  return ($trn -> tn, $ptsignature -> signature) as signed_message.
87
92
  }
@@ -179,7 +184,7 @@ library transaction loads libraries key_utils, key_storage, identity_proof_docum
179
184
  return ($result_kind -> results::kind::success, $result -> actions).
180
185
  }
181
186
 
182
- encrypt = fn (_:($cid -> cid: t_container_id, $trn -> tn: ($name -> str, $targ -> any), $isemsignature -> isem: bool)
187
+ encrypt = fn (_:($cid -> cid: t_container_id, $trn -> tn: ($name -> str, $targ -> any, $__limits -> any+), $isemsignature -> isem: bool)
183
188
  ) -> encrypted_signed_message
184
189
  {
185
190
  encrypted_data = key_storage::default_encrypt tn cid.