Bound faces to talk structures. Renamed stations to circles.

Communication structures get no new faces because their ideal implementation uses gates to process them.
This commit is contained in:
Fang 2017-04-24 20:17:56 +02:00
parent 0a4d5e9b3b
commit 23bdb637b2
3 changed files with 303 additions and 293 deletions

View File

@ -36,11 +36,11 @@
sources/(set partner) ::< our subscriptions
:: partner details ::
remotes/(map partner atlas) ::< remote presences
mirrors/(map station config) ::< remote configs
mirrors/(map circle config) ::< remote configs
:: ui state ::
folks/(map ship human) ::< human identities
nik/(map (set partner) char) ::< bound station glyphs
nak/(jug char (set partner)) ::< station glyph lookup
nik/(map (set partner) char) ::< bound circle glyphs
nak/(jug char (set partner)) ::< circle glyph lookup
cli/shell ::< interaction state
== ::
++ shell ::> console session
@ -65,11 +65,11 @@
{$peer wire dock path} ::
== ::
++ work ::> interface action
$% :: station management ::
$% :: circle management ::
{$join p/where} ::< subscribe to
{$leave p/where} ::< unsubscribe from
{$create p/posture q/knot r/cord} ::< create station
{$delete p/knot q/(unit cord)} ::< delete station
{$create p/posture q/knot r/cord} ::< create circle
{$delete p/knot q/(unit cord)} ::< delete circle
{$depict p/knot q/cord} ::< change description
{$source p/knot q/(set partner)} ::< add source
{$invite p/knot q/(set ship)} ::< give permission
@ -88,11 +88,11 @@
{$nick p/(unit ship) q/(unit cord)} ::< un/set/show nick
{$set p/knot} ::< enable setting
{$unset p/knot} ::< disable setting
:: miscellaneous ::
:: miscellaneous ::
{$help $~} ::< print usage info
== ::
++ where (set partner) ::< non-empty audience
++ glyphs `wall`~[">=+-" "}),." "\"'`^" "$%&@"] ::< station char pool '
++ glyphs `wall`~[">=+-" "}),." "\"'`^" "$%&@"] ::< circle char pool '
--
::
::> ||
@ -124,8 +124,8 @@
our
(sein our)
::
++ inbox ::< reader's station
::> produces the name of the station used by this
++ inbox ::< reader's circle
::> produces the name of the circle used by this
::> reader for all its operations
(main our.bol)
::
@ -266,38 +266,38 @@
==
::
++ ta-low-confs ::< apply changed confs
::> applies new station configurations.
::> applies new circle configurations.
::> because of how this reader only subscribes to
::> the main mailbox, {coy} is always the mailbox's
::> config.
::
|= {coy/(unit config) cofs/(map station (unit config))}
|= {coy/(unit config) cofs/(map circle (unit config))}
^+ +>
::> if possible, update {sources}. if we do, and we
::> gain new ones, update the prompt. (this is to
::> remove the mailbox from the audience after
::> creating or joining a new station.)
::> creating or joining a new circle.)
?~ coy ~&(%mailbox-gone !!)
=. +> ::TODO =?
?~ (~(dif in sources.u.coy) sources) +>.$
?~ (~(dif in src.u.coy) sources) +>.$
=< sh-done
%- ~(sh-pact sh(sources sources.u.coy) cli)
(~(dif in sources.u.coy) sources)
=. sources sources.u.coy
%- ~(sh-pact sh(sources src.u.coy) cli)
(~(dif in src.u.coy) sources)
=. sources src.u.coy
=. cofs (~(put by cofs) [our.bol inbox] coy)
:: print changes for each config.
=. +>.$
=< sh-done
%+ roll (~(tap by cofs))
|= {{s/station c/(unit config)} core/_sh}
|= {{s/circle c/(unit config)} core/_sh}
%^ ~(sh-low-config core cli)
s (~(get by mirrors) s) c
:: apply config changes to {mirrors}.
=. mirrors
%- ~(gas by *_mirrors)
%+ murn (~(tap by cofs))
|= {s/station c/(unit config)}
^- (unit (pair station config))
|= {s/circle c/(unit config)}
^- (unit (pair circle config))
?~(c ~ `[s u.c])
+>.$
::
@ -351,7 +351,7 @@
::
|= gam/telegram
^+ +>
=+ old=(~(get by known) p.q.gam)
=+ old=(~(get by known) uid.tot.gam)
?~ old
(ta-append gam) ::< add
(ta-revise u.old gam) ::< modify
@ -364,7 +364,7 @@
%= +>
grams [gam grams]
count +(count)
known (~(put by known) p.q.gam count)
known (~(put by known) uid.tot.gam count)
==
::
++ ta-revise ::< revise message
@ -514,10 +514,10 @@
==
==
::
++ stat ::< local station
++ stat ::< local circle
;~(pfix cen sym)
::
++ stan ::< station
++ stan ::< circle
;~ pose
(cold [our.bol inbox] col)
;~(pfix cen (stag our.bol sym))
@ -589,7 +589,7 @@
::
++ nick (cook crip (stun [1 14] low)) ::< nickname
++ text (cook crip (plus (shim ' ' '~'))) ::< bullets separating
++ glyph (mask "/\\\{(<!?{(zing glyphs)}") ::< station postfix
++ glyph (mask "/\\\{(<!?{(zing glyphs)}") ::< circle postfix
++ setting ::< setting flag
%- perk :~
%noob
@ -601,7 +601,7 @@
=- ;~(pose ;~(pfix sem -) message)
;~ pose
::
:: station management
:: circle management
::
;~((glue ace) (perk %join ~) para)
::
@ -808,7 +808,7 @@
::
++ work ::< call correct worker
?- -.job
:: station management
:: circle management
$join (join +.job)
$leave (leave +.job)
$create (create +.job)
@ -903,8 +903,8 @@
^- (list ship)
%+ murn (~(tap by folks))
|= {p/ship q/human}
?~ hand.q ~
?. =(u.hand.q nym) ~
?~ han.q ~
?. =(u.han.q nym) ~
[~ u=p]
::
++ twig-head ::< eval data
@ -916,7 +916,7 @@
[our.bol now.bol (shas %eny eny.bol)]
::
::> ||
::> || %station-management
::> || %circle-management
::> ||
::+|
::
@ -946,7 +946,7 @@
(sh-act %source inbox | pas)
::
++ create ::< %create
::> creates station {nom} with specified config.
::> creates circle {nom} with specified config.
::
|= {por/posture nom/knot txt/cord}
^+ ..sh-work
@ -958,7 +958,7 @@
(join [[%& our.bol nom] ~ ~])
::
++ delete ::< %delete
::> deletes our station {nom}, after optionally
::> deletes our circle {nom}, after optionally
::> sending a last announce message {say}.
::
|= {nom/knot say/(unit cord)}
@ -973,21 +973,21 @@
(sh-act %depict nom txt)
::
++ source ::< %source
::> adds {pas} to {nom}'s sources.
::> adds {pas} to {nom}'s src.
::
|= {nom/knot pas/(set partner)}
^+ ..sh-work
(sh-act %source nom & pas)
::
++ invite ::< %invite
::> invites {sis} to our station {nom}.
::> invites {sis} to our circle {nom}.
::
|= {nom/knot sis/(set ship)}
^+ ..sh-work
(sh-act %permit nom & sis)
::
++ banish ::< %banish
::> banish {sis} from our station {nom}.
::> banish {sis} from our circle {nom}.
::
|= {nom/knot sis/(set ship)}
^+ ..sh-work
@ -1039,12 +1039,13 @@
=< (murn (sort (~(tap by alt)) aor) .)
|= {a/ship b/presence c/human} ^- (unit tank)
=. c
?. =(hand.c `(scot %p a)) c
[true.c ~]
?. =(han.c `(scot %p a)) c
[tru.c ~]
?- b
$gone ~
$hear `leaf+:(weld "hear " (scow %p a) " " (trip (fall hand.c '')))
$talk `leaf+:(weld "talk " (scow %p a) " " (trip (fall hand.c '')))
$idle `leaf+:(weld "idle " (scow %p a) " " (trip (fall han.c '')))
$hear `leaf+:(weld "hear " (scow %p a) " " (trip (fall han.c '')))
$talk `leaf+:(weld "talk " (scow %p a) " " (trip (fall han.c '')))
==
::
++ what ::< %what
@ -1120,17 +1121,17 @@
%+ turn (~(tap by folks))
|= {p/ship q/human}
:- %txt
?~ hand.q
?~ han.q
"{<p>}:"
"{<p>}: {<u.hand.q>}"
"{<p>}: {<u.han.q>}"
::> show her nick
?~ nym
?> ?=(^ her)
=+ asc=(~(get by folks) u.her)
%+ sh-fact %txt
?~ asc "{<u.her>} unbound"
?~ hand.u.asc "{<u.her>}:"
"{<u.her>}: {<u.hand.u.asc>}"
?~ han.u.asc "{<u.her>}:"
"{<u.her>}: {<u.han.u.asc>}"
::> show nick ship
?~ her
%+ sh-fact %mor
@ -1225,7 +1226,7 @@
::> if partner is a passport, ignore.
?. ?=($& -.tay) +>
=+ cof=(~(get by mirrors) +.tay)
?. |(?=($~ cof) !?=($white p.cordon.u.cof))
?. |(?=($~ cof) !?=($white sec.con.u.cof))
+>.$
(sh-pact [tay ~ ~])
::
@ -1244,7 +1245,7 @@
|- ^- (unit (set partner))
?~ grams ~
::> get first partner from a telegram's audience.
=+ pan=(silt (turn (~(tap by q.q.i.grams)) head))
=+ pan=(silt (turn (~(tap by aud.tot.i.grams)) head))
?: (~(has in lax) pan) `pan
$(grams t.grams)
::
@ -1271,11 +1272,11 @@
|- ^+ ret
?~ eno ret
=. ret $(eno t.eno)
?: =(%gone p.q.i.eno) ret
?: =(%gone pec.q.i.eno) ret
=+ unt=(~(get by two) p.i.eno)
?~ unt
ret(old [i.eno old.ret])
?: =(%gone p.u.unt)
?: =(%gone pec.u.unt)
ret(old [i.eno old.ret])
?: =(q.i.eno u.unt) ret
ret(cha [[p.i.eno u.unt] cha.ret])
@ -1284,10 +1285,10 @@
|- ^+ ret
?~ owt ret
=. ret $(owt t.owt)
?: =(%gone p.q.i.owt) ret
?: =(%gone pec.q.i.owt) ret
?. (~(has by one) p.i.owt)
ret(new [i.owt new.ret])
?: =(%gone p:(~(got by one) p.i.owt))
?: =(%gone pec:(~(got by one) p.i.owt))
ret(new [i.owt new.ret])
ret
ret
@ -1329,11 +1330,11 @@
::> maps, producing lists of removed, added and
::> changed configs.
::
|= {one/(map station config) two/(map station config)}
|= {one/(map circle config) two/(map circle config)}
=| $= ret
$: old/(list (pair station config))
new/(list (pair station config))
cha/(list (pair station config))
$: old/(list (pair circle config))
new/(list (pair circle config))
cha/(list (pair circle config))
==
^+ ret
=. ret
@ -1374,7 +1375,7 @@
::> renders a reaction to the cli.
::
|= rac/reaction
(sh-lame (trip what.rac))
(sh-lame (trip wat.rac))
::
++ sh-lame ::< send error
::> just puts some text into the cli as-is.
@ -1435,9 +1436,9 @@
++ sh-spaz ::< render status
::> gets the presence of {saz} as a tape.
::
|= saz/status
|= sat/status
^- tape
['%' (trip p.saz)]
['%' (trip pec.sat)]
::
++ sh-show-precs ::< print atlas diff
::> prints presence changes to the cli.
@ -1510,38 +1511,38 @@
|= {pre/tape laz/config loc/config}
^+ +>
=. +>.$
?: =(caption.loc caption.laz) +>.$
(sh-note :(weld pre "cap " (trip caption.loc)))
?: =(cap.loc cap.laz) +>.$
(sh-note :(weld pre "cap " (trip cap.loc)))
=. +>.$
%+ sh-show-sources
(weld (trip inbox) ": ")
(sh-set-diff sources.laz sources.loc)
?: !=(p.cordon.loc p.cordon.laz)
=. +>.$ (sh-note :(weld pre "but " (sh-puss p.cordon.loc)))
(sh-set-diff src.laz src.loc)
?: !=(sec.con.loc sec.con.laz)
=. +>.$ (sh-note :(weld pre "but " (sh-puss sec.con.loc)))
%^ sh-show-permits
(weld (trip inbox) ": ")
p.cordon.loc
[~ (~(tap in q.cordon.loc))]
sec.con.loc
[~ (~(tap in ses.con.loc))]
%^ sh-show-permits
(weld (trip inbox) ": ")
p.cordon.loc
(sh-set-diff q.cordon.laz q.cordon.loc)
sec.con.loc
(sh-set-diff ses.con.laz ses.con.loc)
::
++ sh-low-config ::< do show config
::> prints a station's config changes to the cli.
::> prints a circle's config changes to the cli.
::
|= {sat/station old/(unit config) new/(unit config)}
|= {sat/circle old/(unit config) new/(unit config)}
^+ +>
?~ old ~&([%new-conf sat] +>)
?~ new ~&([%del-conf sat] +>) ::TODO tmp
%^ sh-show-config
(weld ~(sr-phat sr sat) ": ")
(weld ~(cr-phat cr sat) ": ")
u.old u.new
::
++ sh-low-remco ::TODO delete me
::> prints changes to remote configs to the cli
::
|= {ole/(map station config) neu/(map station config)}
|= {ole/(map circle config) neu/(map circle config)}
^+ +>
=+ (sh-remco-diff ole neu)
=. +>.$
@ -1550,15 +1551,15 @@
=. +>.^$ $(new t.new)
=. +>.^$ (sh-pest [%& p.i.new])
%+ sh-show-config
(weld ~(sr-phat sr p.i.new) ": ")
(weld ~(cr-phat cr p.i.new) ": ")
[*config q.i.new]
=. +>.$
|- ^+ +>.^$
?~ cha +>.^$
=. +>.^$ $(cha t.cha)
%+ sh-show-config
(weld ~(sr-phat sr p.i.cha) ": ")
[(~(got by ole) `station`p.i.cha) q.i.cha]
(weld ~(cr-phat cr p.i.cha) ": ")
[(~(got by ole) `circle`p.i.cha) q.i.cha]
+>.$
::
++ sh-low-rempe ::< show remotes
@ -1630,81 +1631,81 @@
::> rendering cores.
::+|
::
++ sr ::< station renderer
::> used in both station and ship rendering.
++ cr ::< circle renderer
::> used in both circle and ship rendering.
::
|_ ::> one: the station.
|_ ::> one: the circle.
::
one/station
one/circle
::
++ sr-best ::< best to show
++ cr-best ::< best to show
::> returns true if one is better to show, false
::> otherwise. prioritizes: our > main > size.
::TODO maybe simplify. (lth (xeb (xeb p.one)) (xeb (xeb p.two)))
::TODO maybe simplify. (lth (xeb (xeb hos.one)) (xeb (xeb hos.two)))
::
|= two/station
|= two/circle
^- ?
:: the station that's ours is better.
?: =(our.bol p.one)
?: =(our.bol p.two)
?< =(q.one q.two)
:: if both stations are ours, the main story is better.
?: =((main p.one) q.one) %&
?: =((main p.two) q.two) %|
:: the circle that's ours is better.
?: =(our.bol hos.one)
?: =(our.bol hos.two)
?< =(nom.one nom.two)
:: if both circles are ours, the main story is better.
?: =((main hos.one) nom.one) %&
?: =((main hos.two) nom.two) %|
:: if neither are, pick the "larger" one.
(lth q.one q.two)
(lth nom.one nom.two)
%&
:: if one isn't ours but two is, two is better.
?: =(our.bol p.two)
?: =(our.bol hos.two)
%|
?: =(p.one p.two)
?: =(hos.one hos.two)
:: if they're from the same ship, pick the "larger" one.
(lth q.one q.two)
(lth nom.one nom.two)
:: when in doubt, pick one if its ship is "smaller" than its channel.
(lth p.one q.one)
(lth hos.one nom.one)
::
++ sr-curt ::< render name in 14
++ cr-curt ::< render name in 14
::> prints a ship name in 14 characters. left-pads
::> with spaces. {mup} signifies "are there other
::> targets besides this one?"
::
|= mup/?
^- tape
=+ raw=(cite p.one)
=+ raw=(cite hos.one)
(runt [(sub 14 (lent raw)) ' '] raw)
::
++ sr-nick ::< nick or name in 14
++ cr-nick ::< nick or name in 14
::> get nick for ship, or shortname if no nick.
::> left-pads with spaces.
::
|. ^- tape
=+ nym=(~(get by folks) p.one)
=+ nym=(~(get by folks) hos.one)
?~ nym
(sr-curt |)
?~ hand.u.nym
(sr-curt |)
=+ raw=(trip u.hand.u.nym)
(cr-curt |)
?~ han.u.nym
(cr-curt |)
=+ raw=(trip u.han.u.nym)
=+ len=(sub 14 (lent raw))
(weld (reap len ' ') raw)
::
++ sr-phat ::< render accurately
::> prints a station fully, but still taking
++ cr-phat ::< render accurately
::> prints a circle fully, but still taking
::> "shortcuts" where possible:
::> ":" for local mailbox, "~ship" for foreign
::> mailbox, "%channel" for local station,
::> "/channel" for parent station.
::> mailbox, "%channel" for local circle,
::> "/channel" for parent circle.
::
^- tape
?: =(p.one our.bol)
?: =(q.one inbox)
?: =(hos.one our.bol)
?: =(nom.one inbox)
":"
['%' (trip q.one)]
?: =(p.one (sein our.bol))
['/' (trip q.one)]
=+ wun=(scow %p p.one)
?: =(q.one (main p.one))
['%' (trip nom.one)]
?: =(hos.one (sein our.bol))
['/' (trip nom.one)]
=+ wun=(scow %p hos.one)
?: =(nom.one (main hos.one))
wun
:(welp wun "/" (trip q.one))
:(welp wun "/" (trip nom.one))
--
::
++ pr ::< partner renderer
@ -1716,8 +1717,8 @@
::
++ pr-beat ::< more relevant
::> returns true if one is better to show, false
::> otherwise. prefers stations over passports.
::> if both are stations, ++sr-best.
::> otherwise. prefers circles over passports.
::> if both are circles, ++cr-best.
::> if both are passports, pick the "larger" one.
::> if they're equal, content hash.
::
@ -1726,7 +1727,7 @@
$&
?- -.two
$| %&
$& (~(sr-best sr p.one) p.two)
$& (~(cr-best cr p.one) p.two)
==
::
$|
@ -1767,13 +1768,13 @@
|= moy/(unit ?)
^- tape
?- -.one
:: render station (as glyph if we can).
:: render circle (as glyph if we can).
$&
?~ moy
=+ cha=(~(get by nik) one ~ ~)
=- ?~(cha - "'{u.cha ~}' {-}")
~(sr-phat sr p.one)
(~(sr-curt sr p.one) u.moy)
~(cr-phat cr p.one)
(~(cr-curt cr p.one) u.moy)
:: render passport.
$|
=/ pre ^- tape
@ -1850,9 +1851,9 @@
::
|= pan/partner ^- ?
?& ?=($& -.pan)
=(p.p.pan our.bol)
=(hos.p.pan our.bol)
=+ sot=(~(get by mirrors) +.pan)
&(?=(^ sot) ?=($brown p.cordon.u.sot))
&(?=(^ sot) ?=($brown sec.con.u.sot))
==
::
++ ar-pref ::< audience glyph
@ -1915,8 +1916,8 @@
:: ?: oug
:: ~(ar-whom ar tr-pals)
?. (~(has in sef) %noob)
(~(sr-curt sr [who (main who)]) |)
(~(sr-nick sr [who (main who)]))
(~(cr-curt cr [who (main who)]) |)
(~(cr-nick cr [who (main who)]))
?: (~(has in sef) %showtime)
=+ dat=(yore now.bol)
=/ t
@ -1959,31 +1960,32 @@
tan+~
::
$lin
tan+~[leaf+"{?:(p.sep "" "@ ")}{(trip q.sep)}"]
tan+~[leaf+"{?:(pat.sep "" "@ ")}{(trip msg.sep)}"]
::
$url
url+(crip (earf p.sep))
url+(crip (earf url.sep))
::
$exp
tan+~[leaf+"# {(trip p.sep)}"]
tan+~[leaf+"# {(trip exp.sep)}"]
::
$fat
[%mor $(sep q.sep) tan+(tr-tors p.sep) ~]
[%mor $(sep sep.sep) tan+(tr-tors tac.sep) ~]
::
$inv
:- %tan
:_ ~
:- %leaf
%+ weld
?: p.sep
?: inv.sep
"you have been invited to "
"you have been banished from "
~(sr-phat sr q.sep)
~(cr-phat cr sat.sep)
::
$mor
mor+(turn p.sep |=(speech ^$(sep +<)))
mor+(turn ses.sep |=(speech ^$(sep +<)))
::
$app
tan+~[rose+[": " ~ ~]^~[leaf+"[{(trip p.sep)}]" leaf+(trip q.sep)]]
tan+~[rose+[": " ~ ~]^~[leaf+"[{(trip app.sep)}]" leaf+(trip msg.sep)]]
::
$api
:- %tan
@ -2002,7 +2004,7 @@
|= a/torso
^- tang
?- -.a
$name (welp $(a q.a) leaf+"={(trip p.a)}" ~)
$name (welp $(a tac.a) leaf+"={(trip nom.a)}" ~)
$tank +.a
$text (turn (flop +.a) |=(b/cord leaf+(trip b)))
==
@ -2050,25 +2052,25 @@
~&(tr-lost+sep "")
::
$mor
?~ p.sep ~&(%tr-mor-empty "")
?~ ses.sep ~&(%tr-mor-empty "")
|- ^- tape
?~ t.p.sep ^$(sep i.p.sep)
(tr-both ^$(sep i.p.sep) $(p.sep t.p.sep))
?~ t.ses.sep ^$(sep i.ses.sep)
(tr-both ^$(sep i.ses.sep) $(ses.sep t.ses.sep))
::
$fat
%+ tr-both $(sep q.sep)
?+ -.p.sep "..."
$tank ~(ram re %rose [" " `~] +.p.sep)
%+ tr-both $(sep sep.sep)
?+ -.tac.sep "..."
$tank ~(ram re %rose [" " `~] +.tac.sep)
==
::
$exp
(tr-chow 66 '#' ' ' (trip p.sep))
(tr-chow 66 '#' ' ' (trip exp.sep))
::
$url
=+ ful=(earf p.sep)
=+ ful=(earf url.sep)
?: (gth 64 (lent ful)) ['/' ' ' ful]
:+ '/' '_'
=+ hok=r.p.p.p.sep
=+ hok=r.p.p.url.sep
~! hok
=- (swag [a=(sub (max 64 (lent -)) 64) b=64] -)
^- tape
@ -2080,8 +2082,8 @@
(welp b '.' (trip a))
::
$lin
=+ txt=(trip q.sep)
?: p.sep
=+ txt=(trip msg.sep)
?: pat.sep
=+ pal=tr-pals
=. pal ?: =(who our.bol) pal ::TODO =?
(~(del in pal) [%& who (main who)])
@ -2090,13 +2092,13 @@
::
$inv
%+ weld
?: p.sep
?: inv.sep
" invited you to "
" banished you from "
~(sr-phat sr q.sep)
~(cr-phat cr sat.sep)
::
$app
(tr-chow 64 "[{(trip p.sep)}]: {(trip q.sep)}")
(tr-chow 64 "[{(trip app.sep)}]: {(trip msg.sep)}")
::
$api
%+ tr-chow 64

View File

@ -3,8 +3,10 @@
:: :: ::
::
::TODO master changes
::TODO char57 comments as line comments when regarding code.
::TODO avoid lark where possible
::TODO maybe rename wires. repeat & friend -> message & follower
::TODO put printfs properly through console/mailbox
::TODO think about what printfs we want to keep for the user to see.
::TODO document what user-facing printfs actually mean!
::TODO ::> to :> etc.
@ -44,8 +46,8 @@
outbox/(pair @ud (map @ud thought)) ::< urbit outbox
log/(map knot @ud) ::< logged to clay
folks/(map ship human) ::< human identities
nik/(map (set partner) char) ::< bound station glyphs
nak/(jug char (set partner)) ::< station glyph lookup
nik/(map (set partner) char) ::< bound circle glyphs
nak/(jug char (set partner)) ::< circle glyph lookup
== ::
++ story ::> wire content
$: count/@ud ::< (lent grams)
@ -53,7 +55,7 @@
locals/atlas ::< local presence
remotes/(map partner atlas) ::< remote presence
shape/config ::< configuration
mirrors/(map station config) ::< remote config
mirrors/(map circle config) ::< remote config
::TODO never gets updated. ::
sequence/(map partner @ud) ::< partners heard
known/(map serial @ud) ::< messages heard
@ -85,7 +87,7 @@
== ::
++ weir ::> parsed wire
$% {$repeat p/@ud q/@p r/knot} ::< messaging wire
{$friend p/knot q/station} ::< subscription wire
{$friend p/knot q/circle} ::< subscription wire
== ::
--
::
@ -197,7 +199,7 @@
::> a story core. if it doesn't, does nothing.
::
|= nom/knot
|* fun/$-(_so _+>)
|= fun/$-(_so _ta)
^+ +>+>
=+ pur=(~(get by stories) nom)
?~ pur
@ -242,7 +244,7 @@
|= {src/ship cod/command}
^+ +>
?- -.cod
::> %review commands prompt us (as a station host)
::> %review commands prompt us (as a circle host)
::> to verify and distribute messages.
$review
(ta-think | src +.cod)
@ -268,7 +270,7 @@
++ work ::< perform action
^+ ..ta-action
?- -.act
:: station configuration
:: circle configuration
$create (action-create +.act)
$source (action-source +.act)
$depict (action-depict +.act)
@ -291,7 +293,7 @@
::> if it doesn't, reacts accordingly.
::
|= nom/knot
|* fec/$-(_so _ta)
|= fec/$-({_so story} _ta)
^+ ta
=+ pur=(~(get by stories) nom)
?^ pur
@ -299,7 +301,7 @@
%+ ta-react red
[%fail (crip "no story {(trip nom)}") `act]
::
::> || %station-configuration
::> || %circle-configuration
::+|
++ action-create ::< create story
::> creates a story with the specified parameters.
@ -316,11 +318,11 @@
|= {nom/knot sub/? pas/(set partner)}
^+ ..ta-action
%- (affect nom) |= {sor/_so soy/story}
=. sources.shape.soy
=. src.shape.soy
%. pas
?: sub
~(uni in sources.shape.soy)
~(dif in sources.shape.soy)
~(uni in src.shape.soy)
~(dif in src.shape.soy)
(ta-config nom shape.soy)
::
++ action-depict ::< change description
@ -329,7 +331,7 @@
|= {nom/knot des/cord}
^+ ..ta-action
%- (affect nom) |= {sor/_so soy/story}
=. caption.shape.soy des
=. cap.shape.soy des
(ta-config nom shape.soy)
::
++ action-permit ::< invite/banish
@ -403,12 +405,12 @@
^+ ..ta-action
?. =((~(get by folks) sip) `nic) ..ta-action ::< no change
=. folks
?~ hand.nic (~(del by folks) sip)
?~ han.nic (~(del by folks) sip)
(~(put by folks) sip nic)
%+ ta-inform %names
::TODO think long and hard, do we need unit for delition or is a human
:: with [~ ~] good enough? if the latter, agent's $names will change.
(strap sip ?~(hand.nic ~ `nic))
(strap sip ?~(han.nic ~ `nic))
::
++ action-glyph ::< bind a glyph
::> un/bind glyph {lif} to partners {pas}.
@ -440,7 +442,7 @@
++ ta-diff-report ::< subscription update
::> process a talk report from {sat} into story {nom}.
::
|= {nom/knot sat/station ret/report}
|= {nom/knot sat/circle ret/report}
%- (ta-know nom) |= sor/_so =< so-done
(so-diff-report:sor sat ret)
::
@ -527,14 +529,14 @@
++ ta-retry ::< subscription resend
::> re-subscribes {sat} to story {nom}.
::
|= {nom/knot sat/station}
|= {nom/knot sat/circle}
%- (ta-know nom) |= sor/_so =< so-done
(so-acquire:sor [%& sat]~)
::
++ ta-quit ::< subscription failed
::> removes {sat} from story {nom}'s followers.
::
|= {nom/knot sat/station}
|= {nom/knot sat/circle}
%- (ta-know nom) |= sor/_so =< so-done
(so-quit:sor %& sat)
::
@ -674,17 +676,17 @@
::
++ ta-sane ::< sanitize
::> sanitize %lin speech, enforce lowercase and no special characters.
::TODO make configurable per-station.
::TODO make configurable per-circle.
::
|= tot/thought
^- thought
?. ?=({$lin *} r.r.tot) tot
%_ tot
q.r.r
?. ?=({$lin *} sep.sam.tot) tot
%_ tot
msg.sep.sam
%- crip
%+ scag 64
%- tufa
%+ turn (tuba (trip q.r.r.tot))
%+ turn (tuba (trip msg.sep.sam.tot))
|= a/@c
?: &((gte a 'A') (lte a 'Z'))
(add a 32)
@ -698,7 +700,7 @@
::
|= {pub/? aut/ship tot/thought}
=. tot (ta-sane tot)
=+ aud=(~(tap by q.tot))
=+ aud=(~(tap by aud.tot))
|- ^+ +>.^$
?~ aud +>.^$
$(aud t.aud, +>.^$ (ta-conduct pub aut p.i.aud tot))
@ -709,16 +711,16 @@
|= {pub/? aut/ship pan/partner tot/thought}
^+ +>
?- -.pan
$& ::< station partner
$& ::< circle partner
?: pub
?. (team our.bol aut)
~&([%talk-strange-author aut] +>)
=. aut our.bol
?: =(aut p.p.pan)
(ta-record q.p.pan p.p.pan tot)
?: =(aut hos.p.pan)
(ta-record nom.p.pan hos.p.pan tot)
(ta-transmit p.pan tot)
?. =(our.bol p.p.pan) +>
(ta-record q.p.pan aut tot)
?. =(our.bol hos.p.pan) +>
(ta-record nom.p.pan aut tot)
::
$| !! ::< passport partner
==
@ -734,13 +736,13 @@
::> sends thought {tot} to {sat}.
::> stores it to the outbox to await confirmation.
::
|= {sat/station tot/thought}
|= {sat/circle tot/thought}
^+ +>
=. +>
%+ ta-emit ost.bol
:* %poke
/repeat/(scot %ud p.outbox)/(scot %p p.sat)/[q.sat]
[p.sat %talk-guardian]
/repeat/(scot %ud p.outbox)/(scot %p hos.sat)/[nom.sat]
[hos.sat %talk-guardian]
[%talk-command [%review tot ~]]
==
+>(p.outbox +(p.outbox), q.outbox (~(put by q.outbox) p.outbox tot))
@ -760,9 +762,9 @@
=+ oot=(~(get by q.outbox) num)
?~ oot ~|([%ta-repeat-none num] !!)
=. q.outbox (~(del by q.outbox) num)
=. q.u.oot
=+ olg=(~(got by q.u.oot) pan)
%+ ~(put by q.u.oot) pan
=. aud.u.oot
=+ olg=(~(got by aud.u.oot) pan)
%+ ~(put by aud.u.oot) pan
:- -.olg
?~ fal %received
~> %slog.[0 u.fal]
@ -787,10 +789,10 @@
::> wyt: will be white
=+ :+ neu=!(~(has by stories) nom)
pur=(fall (~(get by stories) nom) *story)
wyt=?=(?($white $green) p.cordon.con)
=. q.cordon.con ::TODO =?
wyt=?=(?($white $green) sec.con.con)
=. ses.con.con ::TODO =?
?: &(neu wyt) [our.bol ~ ~]
q.cordon.con
ses.con.con
so-done:(~(so-reform so nom ~ pur) con)
::
++ ta-unconfig ::< delete story
@ -922,8 +924,8 @@
%- ~(urn by remotes) :: XX performance
|= {pan/partner atl/atlas}
^- atlas
?. &(?=($& -.pan) =(our.bol p.p.pan)) atl
=+ soy=(~(get by stories) q.p.pan)
?. &(?=($& -.pan) =(our.bol hos.p.pan)) atl
=+ soy=(~(get by stories) nom.p.pan)
?~ soy atl
locals.u.soy
::
@ -937,22 +939,22 @@
::> process a talk report from {sat}.
::> if we didn't expect it, ignore.
::
|= {sat/station ret/report}
|= {sat/circle ret/report}
^+ +>
?. (~(has in sources.shape) [%& sat])
?. (~(has in src.shape) [%& sat])
~& [%talk-so-diff-unexpected sat -.ret]
+>
?- -.ret
$cabal (so-cabal sat +.ret)
$group (so-remind [%& sat] +.ret)
$grams (so-lesson q.+.ret)
$grams (so-lesson gaz.ret)
==
::
++ so-cabal ::< update config
::> add station's config to our remote config map.
::> add circle's config to our remote config map.
::
::TODO when do we care about ham?
|= {sat/station con/config ham/(map station config)}
::TODO when do we care about rem?
|= {sat/circle con/config rem/(map circle config)}
^+ +>
=+ old=mirrors
=. mirrors (~(put by mirrors) sat con)
@ -986,7 +988,7 @@
::+|
::
++ so-reform ::< reconfigure
::> changes the config of this story and notify
::> changes the config of this story and notify::
::> our followers.
::> subscribes to new sources, unsubs from removed
::> ones.
@ -994,10 +996,10 @@
|= cof/config
=. +>.$ (so-inform %confs `cof ~)
=/ dif/(pair (list partner) (list partner))
=+ old=`(list partner)`(~(tap in sources.shape) ~)
=+ new=`(list partner)`(~(tap in sources.cof) ~)
:- (skip new |=(a/partner (~(has in sources.shape) a)))
(skip old |=(a/partner (~(has in sources.cof) a)))
=+ old=`(list partner)`(~(tap in src.shape) ~)
=+ new=`(list partner)`(~(tap in src.cof) ~)
:- (skip new |=(a/partner (~(has in src.shape) a)))
(skip old |=(a/partner (~(has in src.cof) a)))
=. +>.$ (so-acquire p.dif)
=. +>.$ (so-abjure q.dif)
=. shape cof
@ -1005,22 +1007,22 @@
::
++ so-reform-gone ::< delete story
::> deletes this story. removes it from {stories}
::> and unsubscribes from all sources.
::> and unsubscribes from all src.
::
=. stories (~(del by stories) nom)
=. . (so-inform %confs ~ ~)
=. . (so-report-cabal so-followers)
(so-abjure (~(tap in sources.shape)))
(so-abjure (~(tap in src.shape)))
::
++ so-notify ::< local presence
::> add {her} status to this story's presence map.
::> if this changes it, send a report.
::
|= {her/ship sas/status}
|= {her/ship sat/status}
^+ +>
=/ nol (~(put by locals) her sas)
=/ nol (~(put by locals) her sat)
?: =(nol locals) +>.$
=. +>.$ (so-inform %precs (strap her sas) ~)
=. +>.$ (so-inform %precs (strap her sat) ~)
(so-report-group(locals nol) so-followers)
::
::> ||
@ -1047,12 +1049,12 @@
?- -.pan
$| !! ::< passport partner
::
$& ::< station partner
$& ::< circle partner
:_ ~
:* %peer
/friend/show/[nom]/(scot %p p.p.pan)/[q.p.pan]
[p.p.pan %talk-guardian]
/[q.p.pan]/[ini]
/friend/show/[nom]/(scot %p hos.p.pan)/[nom.p.pan]
[hos.p.pan %talk-guardian]
/[nom.p.pan]/[ini]
==
==
::
@ -1068,11 +1070,11 @@
?- -.pan
$| !! ::< passport partner
::
$& ::< station partner
$& ::< circle partner
:_ ~
:* %pull
/friend/show/[nom]/(scot %p p.p.pan)/[q.p.pan]
[p.p.pan %talk-guardian]
/friend/show/[nom]/(scot %p hos.p.pan)/[nom.p.pan]
[hos.p.pan %talk-guardian]
~
==
==
@ -1083,8 +1085,8 @@
::
|= pan/partner
^+ +>
?. (~(has in sources.shape) pan) +>
=. sources.shape (~(del in sources.shape) pan)
?. (~(has in src.shape) pan) +>
=. src.shape (~(del in src.shape) pan)
=. +> (so-inform %confs `shape ~)
(so-report-cabal so-followers)
::
@ -1131,13 +1133,13 @@
?~ gaz [dun end zeg]
?: ?- -.q.riv :: after the end
$ud (lte p.q.riv end)
$da (lte p.q.riv p.r.q.i.gaz)
$da (lte p.q.riv wen.sam.tot.i.gaz)
==
:: if past the river, continue back, mark as done.
$(end (dec end), gaz t.gaz, dun &)
?: ?- -.p.riv :: before the start
$ud (lth end p.p.riv)
$da (lth p.r.q.i.gaz p.p.riv)
$da (lth wen.sam.tot.i.gaz p.p.riv)
==
:: if before the river, we're done searching.
[dun end zeg]
@ -1188,12 +1190,12 @@
=+ old=[p=(welp p.lef p.rit) q=(welp q.lef q.rit)]
?: ?- -.q.q.n.followers :: after the end
$ud (lte p.q.q.n.followers num)
$da (lte p.q.q.n.followers p.r.q.gam)
$da (lte p.q.q.n.followers wen.sam.tot.gam)
==
[[p.n.followers p.old] [[p.n.followers %quit ~] q.old]]
?: ?- -.p.q.n.followers :: before the start
$ud (gth p.p.q.n.followers num)
$da (gth p.p.q.n.followers p.r.q.gam)
$da (gth p.p.q.n.followers wen.sam.tot.gam)
==
old
:- p.old
@ -1217,22 +1219,22 @@
::
|= gam/telegram
^+ +>
?. (so-admire p.gam) ::< write permissions
?. (so-admire aut.gam) ::< write permissions
+>.$
=. q.q.gam
=. aud.tot.gam
::> if we are in the audience, mark as received.
=+ ole=(~(get by q.q.gam) [%& our.bol nom])
?^ ole (~(put by q.q.gam) [%& our.bol nom] -.u.ole %received)
::> federated stations need to pretend ~src/nom
=+ ole=(~(get by aud.tot.gam) [%& our.bol nom])
?^ ole (~(put by aud.tot.gam) [%& our.bol nom] -.u.ole %received)
::> federated circles need to pretend ~src/nom
::> is also ~our/nom.
::TODO pass src through explicitly instead of
:: relying on src.bol.
=+ ole=(~(get by q.q.gam) [%& src.bol nom])
?~ ole q.q.gam
:: relying on src.bol. :
=+ ole=(~(get by aud.tot.gam) [%& src.bol nom])
?~ ole aud.tot.gam
::> as described above, fake src into our.
=. q.q.gam (~(del by q.q.gam) [%& src.bol nom])
(~(put by q.q.gam) [%& our.bol nom] -.u.ole %received)
=+ old=(~(get by known) p.q.gam)
=. aud.tot.gam (~(del by aud.tot.gam) [%& src.bol nom])
(~(put by aud.tot.gam) [%& our.bol nom] -.u.ole %received)
=+ old=(~(get by known) uid.tot.gam)
?~ old
(so-append gam) ::< add
(so-revise u.old gam) ::< modify
@ -1245,7 +1247,7 @@
%+ %= so-refresh
grams [gam grams]
count +(count)
known (~(put by known) p.q.gam count)
known (~(put by known) uid.tot.gam count)
==
count
gam
@ -1276,7 +1278,7 @@
^+ +>
::> wyt: whitelist?
::> add: add to list?
=/ wyt/? ?=(?($white $green) p.cordon.shape)
=/ wyt/? ?=(?($white $green) sec.con.shape)
=/ add/? =(inv wyt)
=. +>.$ ::TODO =?
?: inv +>.$
@ -1290,11 +1292,11 @@
[[%inv inv [our.bol nom]] t]
%- so-reform
%= shape
q.cordon
ses.con
%. sis
?: add
~(uni in q.cordon.shape)
~(dif in q.cordon.shape)
~(uni in ses.con.shape)
~(dif in ses.con.shape)
==
::
++ so-admire ::< accept from
@ -1302,11 +1304,11 @@
::
|= her/ship
^- ?
?- p.cordon.shape
$black !(~(has in q.cordon.shape) her) ::< channel, blacklist
$white (~(has in q.cordon.shape) her) ::< village, whitelist
$green (~(has in q.cordon.shape) her) ::< journal, whitelist
$brown !(~(has in q.cordon.shape) her) ::< mailbox, blacklist
?- sec.con.shape
$black !(~(has in ses.con.shape) her) ::< channel, blacklist
$white (~(has in ses.con.shape) her) ::< village, whitelist
$green (~(has in ses.con.shape) her) ::< journal, whitelist
$brown !(~(has in ses.con.shape) her) ::< mailbox, blacklist
==
::
++ so-visible ::< display to
@ -1314,9 +1316,9 @@
::
|= her/ship
^- ?
?- p.cordon.shape
$black !(~(has in q.cordon.shape) her) ::< channel, blacklist
$white (~(has in q.cordon.shape) her) ::< village, whitelist
?- sec.con.shape
$black !(~(has in ses.con.shape) her) ::< channel, blacklist
$white (~(has in ses.con.shape) her) ::< village, whitelist
$green & ::< journal, all
$brown (team our.bol her) ::< mailbox, our team
==
@ -1330,7 +1332,7 @@
::
++ etch ::< parse wire
::> parses {wir}} to obtain either %friend with story
::> and station or %repeat with message number,
::> and circle or %repeat with message number,
::> source ship and story.
::
|= wir/wire
@ -1356,7 +1358,7 @@
::
|= $: wir/wire
$= fun
$- {nom/knot sat/station}
$- {nom/knot sat/circle}
{(list move) _.}
==
=+ wer=(etch wir)
@ -1425,7 +1427,7 @@
^- (quip move +>)
=^ mos +>.$
%+ etch-friend wir
|= {nom/knot sat/station}
|= {nom/knot sat/circle}
ta-done:(ta-diff-report:ta nom sat ret)
=^ mow +>.$
log-all-to-file
@ -1456,7 +1458,7 @@
^- (quip move +>)
?~ fal [~ +>]
%+ etch-friend [%friend wir]
|= {nom/knot sat/station}
|= {nom/knot sat/circle}
=. u.fal [>%reap-friend-fail nom sat< u.fal]
%- (slog (flop u.fal))
ta-done:(ta-quit:ta nom sat)
@ -1467,7 +1469,7 @@
|= wir/wire
^- (quip move +>)
%+ etch-friend [%friend wir]
|= {nom/knot sat/station}
|= {nom/knot sat/circle}
ta-done:(ta-retry:ta nom sat)
::
++ coup-repeat ::< message n/ack

View File

@ -3,8 +3,6 @@
!:
|%
::
::TODO station -> circle
::
::> ||
::> || %reader-communication
::> ||
@ -12,32 +10,35 @@
::+|
::
++ action ::> user action
$% :: station configuration ::
{$create (trel knot cord posture)} ::< create station
{$source (trel knot ? (set partner))} ::< un/sub p to/from r
{$depict (pair knot cord)} ::< change description
{$permit (trel knot ? (set ship))} ::< invite/banish
{$delete (pair knot (unit cord))} ::< delete + announce
$% :: circle configuration ::
{$create nom/knot des/cord sec/posture} ::< create circle
{$source nom/knot sub/? src/(set partner)} ::< un/sub p to/from r
{$depict nom/knot des/cord} ::< change description
{$permit nom/knot inv/? sis/(set ship)} ::< invite/banish
{$delete nom/knot ano/(unit cord)} ::< delete + announce
:: messaging ::
{$convey (list thought)} ::< post exact
{$phrase (pair (set partner) (list speech))} ::< post easy
{$convey tos/(list thought)} ::< post exact
{$phrase aud/(set partner) ses/(list speech)} ::< post easy
:: personal metadata ::
::TODO change to target partners, not only our stations.
{$status (pair (set knot) status)} ::< our status update
::TODO change to target partners, not only our circles.
{$status nos/(set knot) sat/status} ::< our status update
:: changing shared ui ::
{$human (pair ship human)} ::< new identity
{$glyph (trel char (set partner) ?)} ::< un/bind a glyph
{$human sip/ship man/human} ::< new identity
{$glyph gyf/char pas/(set partner) bin/?} ::< un/bind a glyph
== ::
++ reaction ::> user information
$: kind/?($info $fail) ::< result
what/@t ::< explain
$: res/?($info $fail) ::< result
wat/@t ::< explain
why/(unit action) ::< cause
== ::
++ lowdown ::> new/changed state
$% :: story state ::
{$confs (unit config) (map station (unit config))}::< configs
{$precs register} ::< presences
{$grams (pair @ud (list telegram))} ::< messages
$: $confs ::< configs
loc/(unit config) ::< local config
rem/(map circle (unit config)) ::< remote configs
== ::
{$precs reg/register} ::< presences
{$grams num/@ud gaz/(list telegram)} ::< messages
:: ui state ::
{$glyph (jug char (set partner))} ::< glyph bindings
{$names (map ship (unit human))} ::< nicknames
@ -50,12 +51,12 @@
::+|
::
++ command ::> effect on story
$% {$review (list thought)} ::< deliver
$% {$review tos/(list thought)} ::< deliver
== ::
++ report ::> update
$% {$cabal cabal} ::< config neighborhood
{$group register} ::< presence
{$grams (pair @ud (list telegram))} ::< thoughts
$% {$cabal cab/cabal} ::< config neighborhood
{$group reg/register} ::< presence
{$grams num/@ud gaz/(list telegram)} ::< thoughts
== ::
::
::> ||
@ -64,22 +65,22 @@
::> messaging targets and their metadata.
::+|
::
++ partner (each station passport) ::< message target
++ station (pair ship knot) ::< native target
++ partner (each circle passport) ::< message target
++ circle {hos/ship nom/knot} ::< native target
++ passport ::> foreign target
$% {$twitter p/@t} ::< twitter handle
== ::
::> circle configurations.
++ cabal ::> metaconfiguration
$: loc/config ::< local config
ham/(map station config) ::< neighborhood configs
rem/(map circle config) ::< neighborhood configs
== ::
++ config ::> station config
$: sources/(set partner) ::< pulls from
caption/cord ::< description
cordon/control ::< restrictions
++ config ::> circle config
$: src/(set partner) ::< pulls from
cap/cord ::< description
con/control ::< restrictions
== ::
++ control (pair posture (set ship)) ::< access control
++ control {sec/posture ses/(set ship)} ::< access control
++ posture ::> security kind
$? $black ::< channel, blacklist
$white ::< village, whitelist
@ -87,13 +88,18 @@
$brown ::< mailbox, our r, bl w
== ::
::> participant metadata.
++ register (pair atlas (map partner atlas)) ::< our & srcs presences
++ register {loc/atlas rem/(map partner atlas)} ::< our & srcs presences
++ atlas (map ship status) ::< presence map
++ status (pair presence human) ::< participant
++ presence ?($gone $hear $talk) ::< status type
++ status {pec/presence man/human} ::< participant
++ presence ::> status type
$? $gone ::< left
$idle ::< idle
$hear ::< present
$talk ::< typing
==
++ human ::> human identifier
$: true/(unit (trel @t (unit @t) @t)) ::<TODO unused true name
hand/(unit @t) ::< handle
$: tru/(unit (trel @t (unit @t) @t)) ::<TODO unused true name
han/(unit @t) ::< handle
== ::
::
::> ||
@ -102,21 +108,21 @@
::> structures for containing main message data.
::+|
::
++ telegram (pair ship thought) ::< who thought
++ thought (trel serial audience statement) ::< which whom what
++ statement (trel @da bouquet speech) ::< when this
++ telegram {aut/ship tot/thought} ::< who thought
++ thought {uid/serial aud/audience sam/statement} ::< which whom what
++ statement {wen/@da boq/bouquet sep/speech} ::< when this
++ speech ::> narrative action
$% {$non $~} ::< no content (yo)
{$lin p/? q/@t} ::< no/@ text line
{$ire p/serial q/speech} ::< in-reply-to
{$url p/purf} ::< parsed url
{$exp p/@t} ::< hoon line
{$fat p/torso q/speech} ::< attachment
{$lan p/knot q/@t} ::< local announce
{$inv p/? q/station} ::< inv/ban for station
{$mor p/(list speech)} ::< multiplex
{$ext p/@tas q/*} ::< extended action
{$app p/@tas q/@t} ::< app message
{$lin pat/? msg/@t} ::< no/@ text line
{$ire tos/serial sep/speech} ::< in-reply-to
{$url url/purf} ::< parsed url
{$exp exp/@t} ::< hoon line
{$fat tac/torso sep/speech} ::< attachment
{$lan nom/knot msg/@t} ::< local announce
{$inv inv/? sat/circle} ::< inv/ban for circle
{$mor ses/(list speech)} ::< multiplex
{$ext nom/@tas dat/*} ::< extended action
{$app app/@tas msg/@t} ::< app message
$: $api ::< api message
service/@tas ::< service name
id/@t ::< id on the service
@ -128,7 +134,7 @@
== ::
== ::
++ torso ::> attachment
$% {$name (pair @t torso)} ::< named attachment
$% {$name nom/@t tac/torso} ::< named attachment
{$text (list @t)} ::< text lines
{$tank (list tank)} ::< tank list
== ::
@ -141,7 +147,7 @@
::
++ serial @uvH ::< unique identifier
++ audience (map partner (pair envelope delivery)) ::< destination + state
++ envelope (pair ? (unit partner)) ::< visible sender
++ envelope {vis/? sen/(unit partner)} ::< visible sender
++ delivery ::> delivery state
$? $pending ::< undelivered
$received ::< delivered