On this page

Permissions create vs read๏ƒ

๐ŸŸก Intermediate ยท Lesson 22

Permissions LIVE - they are the sharing policy on a contract. "create" lets the borrower construct/resolve fully; "read" is resolve-only across the link. This is where the vocabulary from the cheatsheet finally does something.

Before you run๏ƒ

Use the Intermediate guide for prerequisite concepts. Run from a checkout with Melder installed and Python 3.14 free-threading selected. The collection download includes the level's local helper modules.

Run the saved script๏ƒ

python UX_and_AIX_experiences/02_intermediate/22_permissions_create_vs_read.py
py -3.14t UX_and_AIX_experiences/02_intermediate/22_permissions_create_vs_read.py

Download this collection ยท Source on GitHub

Public surface๏ƒ

add_spell_to_contract(permissions="read"/"create")

Code๏ƒ

 1"""
 2TIER: intermediate (22)
 3GOAL: Permissions LIVE - they are the sharing policy on a contract.
 4      "create" lets the borrower construct/resolve fully; "read" is
 5      resolve-only across the link. This is where the vocabulary from
 6      the cheatsheet finally does something.
 7SURFACE EXERCISED: add_spell_to_contract(permissions="read"/"create")
 8"""
 9import sys
10from pathlib import Path
11
12sys.path.insert(0, str(Path(__file__).parent))  # local helper (see _dynamic_world)
13from _dynamic_world import dynamic_spellbook
14
15import melder as md
16
17
18class OpenService:
19    pass
20
21
22class GuardedService:
23    pass
24
25
26def main() -> None:
27    owner_book = dynamic_spellbook()
28    open_id = owner_book.bind(spell=OpenService, existence="unique")
29    guarded_id = owner_book.bind(spell=GuardedService, existence="unique")
30    owner = owner_book.conjure(dynamic=True, name="perm-owner")
31    borrower = dynamic_spellbook().conjure(dynamic=True, name="perm-borrower")
32    owner.link(borrower)
33
34    # The borrower PULLS from the owner (the named conduit must OWN
35    # the spell); permissions set what the borrower may DO with it.
36    borrower.add_spell_to_contract(spell_id=open_id, conduit=owner,
37                                   permissions="create")
38    borrower.add_spell_to_contract(spell_id=guarded_id, conduit=owner,
39                                   permissions="read")
40
41    print("create-shared meld:", type(borrower.meld(spell=OpenService)).__name__)
42    try:
43        result = borrower.meld(spell=GuardedService)
44        print("read-shared meld answered:", type(result).__name__,
45              "(read = resolve-only; construction rights stay with the owner)")
46    except Exception as err:
47        print("read-shared meld refused:", type(err).__name__)
48
49
50if __name__ == "__main__":
51    main()

Check the outcome๏ƒ

The script contains its own assertions or demonstrated refusal paths. Run it to evaluate those checks against your installed version. The code above is taken directly from the saved file; no run output is invented here.

More intermediate examples ยท Level guide