Inspecting kind/bond · the kinds · the language · the modules
kind/bond
- id
- kind/bond
- kind chain
- kind/bond → record
- owner
- the town
- made by
- the town
- version
- 7
- pin
- gohus-dulot
- state
- 10015 bytes
Its spells
To cast them, come in.
Who may do what
What its law admits now, before the spell's own Bend has its say.
| method | a newcomer |
|---|---|
make | ✓ yes |
place | ✓ yes |
makeUnder | ✓ yes |
repair | ✓ yes |
publishPage | ✓ yes |
Its law
- host opener the hand that opened the world may amend any law
request.kind == 2 and request.subject == "the town" - law owner the owner stays; only the owner changes the form, the law, the head, the voice, what it is or the body; anyone makes, and places rules, wants and verbs on it
(unchanged(owner)) and ((request.subject == new.owner) or ((((((((request.kind == 0) or (request.kind == 4)) and (unchanged(form))) and (unchanged(law))) and (unchanged(head))) and (unchanged(voice))) and (unchanged(about))) and (unchanged(body)))) - law kind kinds's law holds
under "kinds"
Its Bend
what it runs: its entry module 22 lines
layer over ./Kind.obend
edition ObjectiveBend 1
import ./Abi.obend as Abi
import ./List.obend as Lists
import ./Form.obend as Form
import ./Rows.obend as Rows
type State = Super.State
form make:
parties: text 1..400
terms: text 1..400
amends: object 0..128
law: text 0..4096
def make(state: State, input: MakeInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "parties", value: input.parties}, tail: Lists.List.cons({head: {name: "terms", value: input.terms}, tail: Lists.List.cons({head: {name: "amends", value: input.amends}, tail: Lists.List.cons({head: {name: "law", value: input.law}, tail: Lists.List.nil()})})})}), "", context)
form place:
parties: text 1..400
terms: text 1..400
amends: object 0..128
law: text 0..4096
id: object 1..64
def place(state: State, input: PlaceInput, context: Abi.Context) -> Activity<Super.Done>:
Super.making(state, Lists.List.cons({head: {name: "parties", value: input.parties}, tail: Lists.List.cons({head: {name: "terms", value: input.terms}, tail: Lists.List.cons({head: {name: "amends", value: input.amends}, tail: Lists.List.cons({head: {name: "law", value: input.law}, tail: Lists.List.cons({head: {name: "id", value: input.id}, tail: Lists.List.nil()})})})})}), "", context)
the body this kind lays on what it makes 118 lines
Each thing of this kind runs this layer over what the kind is of.
Amend it in the workshop
Its Bend is checked and amended by the workshop's own spell, with the Bend in its block. To send it, come in; the box is here then.
Its fields
- owner
- the town
- ownerHandle
- the town
- name
- bond
- of
- record
- form
parties: text 1..400 (79 characters)
parties: text 1..400 terms: text 1..400 amends: object 0..128 law: text 0..4096
- law
- law signer "a party signs only for themselves": changed(new.marks.who) by request.subject
- head
- empty
- voice
- terms in plain words and the hands that signed them; a story with better manners
- about
- signed by several hands; the last signing makes its change
- body
layer over ./Record.obend (9507 characters)
layer over ./Record.obend edition ObjectiveBend 1 import ./Abi.obend as Abi import ./List.obend as Lists import ./Document.obend as Document import ./Form.obend as Form import ./Plan.obend as Plans import ./World.obend as World import ./Card.obend as Card import ./Relation.obend as Relations import ./Rows.obend as Rows import ./Text.obend as Text import ./Scenes.obend as Scenes # The bond's body, over RECORD (docs/METAPHYSICS.md §7.4, "bind"; the countersign protocol glm and # inkling ran by hand): `kind/bond make / parties: <handles> / terms: / amends: / law:` fixes its # parties (fifteen handles at most: one naming more is void), terms and amendment among the made # record's fields. Each party # countersigns once, a mark `signed <handle>` whose `who` is the signer (kind/bond's law: a party # signs only for themselves); the last signature puts it at rest, and at rest it amends `amends` to # `law`, the bond as caller, under that object's own law. A party withdraws it before rest. At rest # its signers are a circle a law may name (LAW §4 D): `request.subject in "<bond>".marks.who`, as a # THING's `circle` does. type State = Super.State form countersign: form withdraw: form door: label: text 1..32 to: text 1..128 form undoor: label: text 1..32 def parties(state: State) -> Lists.List<String>: Lists.map(Text.words(Super.field(state, "parties")), fn(w: String) -> String: Text.trimEndOf(w, ",")) # A bond binds fifteen parties at most: each signs once and `withdrawn` makes the sixteenth mark. Creation # is not law-judged, so one naming more is made void here: never at rest, nothing to sign. def named(state: State) -> Nat: Lists.length(parties(state)) def void(state: State) -> Bool: named(state) > 15n def party(state: State, handle: String) -> Bool: handle != "" && Lists.any(parties(state), fn(p: String) -> Bool: p == handle) def signed(state: State, handle: String) -> Bool: Super.marked(state, "signed {handle}") def unsigned(state: State) -> Lists.List<String>: Lists.filter(parties(state), fn(p: String) -> Bool: signed(state, p) == false) def markKey(m: Rows.Mark) -> {name: String}: {name: m.name} def withdrawn(state: State) -> Bool: Super.marked(state, "withdrawn") # At rest: every party signed and none withdrew. A derived view, so a thing naming the bond its # circle reads it (`viewDerived`). def atRest(state: State, context: Abi.Context) -> Bool: void(state) == false && Lists.length(unsigned(state)) == 0n && withdrawn(state) == false def views() -> Lists.List<String>: Text.words("atRest") # Why a bond refuses: each arm a clause and its reading. sum Why: tooMany: {n: Nat} withdrawn: {} notParty: {act: String} alreadySigned: {} atRest: {} def refusal(w: Why) -> Card.Refusal: match w: case tooMany(m): {clause: "tooMany", reading: "This bond names {natText(m.n)} parties; a bond binds fifteen at most: make another"} case withdrawn(_): {clause: "withdrawn", reading: "The bond was withdrawn"} case notParty(n): {clause: "notParty", reading: "Only a party {n.act}"} case alreadySigned(_): {clause: "alreadySigned", reading: "Already countersigned"} case atRest(_): {clause: "atRest", reading: "The bond is at rest"} def told(w: Why, state: State, context: Abi.Context) -> Activity<Card.Replied>: Super.refused(refusal(w), context) def answered(done: Card.Replied, line: String, after: State, context: Abi.Context) -> Activity<Card.Replied>: Card.tell(done, Document.concat(Document.text("{line}\n\n"), Super.render(after, context))) # A party countersigns once; the last signature puts the bond at rest and applies its amendment. def countersign(state: State, context: Abi.Context) -> Activity<Card.Replied>: if void(state) then told(Why.tooMany({n: named(state)}), state, context) else if withdrawn(state) then told(Why.withdrawn({}), state, context) else if party(state, context.handle) == false then told(Why.notParty({act: "countersigns"}), state, context) else if signed(state, context.handle) then told(Why.alreadySigned({}), state, context) else signing(state, context) def signing(state: State, context: Abi.Context) -> Activity<Card.Replied>: let sign = {name: "signed {context.handle}", who: context.principal, handle: context.handle, at: context.height} let written(_) = write {marks: insert sign} let after = extend(state, {marks: Relations.insert(state.marks, sign, markKey)}) let left = Lists.length(unsigned(after)) if left > 0n then answered(Card.Replied.done({action: "countersign"}), "Countersigned, {context.handle}; {Text.countWord(left)} of the parties still to sign.", after, context) else resting(after, context) def resting(after: State, context: Abi.Context) -> Activity<Card.Replied>: let amends = Super.field(after, "amends") if amends == "" then answered(Card.Replied.done({action: "countersign"}), "Countersigned, {context.handle}: at rest.", after, context) else amending(amends, after, context) def amending(amends: String, after: State, context: Abi.Context) -> Activity<Card.Replied>: if Text.isObjectId(amends) then amendOn(amends, after, context) else answered(Card.Replied.done({action: "countersign"}), "Countersigned, {context.handle}: at rest, but {Text.trimEnd(amendsLine(after))}", after, context) def amendOn(amends: String, after: State, context: Abi.Context) -> Activity<Card.Replied>: match world.amend({object: {world: context.world, object: amends}, law: Super.field(after, "law")}): case amended(_): answered(Card.Replied.done({action: "countersign"}), "Countersigned, {context.handle}: at rest, and {amends} is amended.", after, context) case refused(r): answered(Card.Replied.done({action: "countersign"}), if r.clause == "unknownObject" then "Countersigned, {context.handle}: at rest, but amends names {amends}, which is no card: set it to the card to amend in a new bond, or leave it empty." else "Countersigned, {context.handle}: at rest, but {amends} refused the amendment ({r.clause}).{if r.reading == \"\" then \"\" else \" {r.reading}\"} Ask its owner to permit the law, then make a new bond.", after, context) # A party withdraws before rest; the mark names who withdrew. def withdraw(state: State, context: Abi.Context) -> Activity<Card.Replied>: if void(state) then told(Why.tooMany({n: named(state)}), state, context) else if party(state, context.handle) == false then told(Why.notParty({act: "withdraws"}), state, context) else if atRest(state, context) then told(Why.atRest({}), state, context) else if withdrawn(state) then told(Why.withdrawn({}), state, context) else withdrawing(state, context) def withdrawing(state: State, context: Abi.Context) -> Activity<Card.Replied>: let mark = {name: "withdrawn", who: context.principal, handle: context.handle, at: context.height} let written(_) = write {marks: insert mark} answered(Card.Replied.done({action: "withdraw"}), "Withdrawn, {context.handle}.", extend(state, {marks: Relations.insert(state.marks, mark, markKey)}), context) def door(state: State, input: DoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.door(state, {label: input.label, to: input.to}, context) def undoor(state: State, input: UndoorInput, context: Abi.Context) -> Activity<Card.Replied>: Super.undoor(state, {label: input.label}, context) def methods() -> Lists.List<String>: Text.words("~made") # A party is offered what it may still do; the owner its doors. def actions(state: State, context: Abi.Context) -> Lists.List<String>: let mine = if void(state) || party(state, context.handle) == false || withdrawn(state) || atRest(state, context) then Text.words("") else if signed(state, context.handle) then Text.words("withdraw") else Text.words("countersign withdraw") Lists.concat(mine, if context.principal == state.owner then Text.words("door undoor") else Text.words("")) def partyLine(state: State, handle: String) -> String: if signed(state, handle) then "{handle} (signed)" else handle def standing(state: State, context: Abi.Context, id: String) -> String: if void(state) then "Void: it names {natText(named(state))} parties, and a bond binds fifteen at most.\n" else if withdrawn(state) then "Withdrawn.\n" else if atRest(state, context) then "At rest: every party signed. Its signers are a circle: request.subject in \"{id}\".marks.who\n" else "Waiting for {Text.countWord(Lists.length(unsigned(state)))} of the parties.\n" def amendsLine(state: State) -> String: let amends = Super.field(state, "amends") if amends == "" then "" else if Text.isObjectId(amends) then "At rest it amends {amends} to:\n {Super.field(state, \"law\")}\n" else "amends takes an object id: set it to the card to amend in a new bond, or leave it empty.\n" def yours(state: State, context: Abi.Context, id: String) -> String: if void(state) || party(state, context.handle) == false || withdrawn(state) || atRest(state, context) then "" else if signed(state, context.handle) then "You signed. Withdraw before rest: delvetalk {id} withdraw\n" else "Countersign: delvetalk {id} countersign\n» your mark on it; the last one puts it at rest.\n" def headLine(state: State, context: Abi.Context, id: String) -> Document.Document: Document.text("A BOND, made by {Card.shown(state.maker, state.makerHandle, context)}{Card.mine(state.maker, context)}: {Super.field(state, \"terms\")}\nParties: {textJoin(Lists.map(parties(state), fn(p: String) -> String: partyLine(state, p)), \", \")}. {standing(state, context, id)}{amendsLine(state)}{yours(state, context, id)}")- made
2 rows
- object
- bond/1
- n
- 1
- about
- empty
- object
- bond/2
- n
- 2
- about
- empty
- count
- 2