on master help sign in
Fix checker regressions from the repository review

Run ordinary inference before keyed program recovery, canonicalize imported Hoon units through nested types and API readers, and hide private re-export labels. Add regressions that distinguish ordinary inference and canonical unit identity, and update the checker documentation.

commita211c34058b23aad6b6c76f66e3aff2b602fbc69 authoriko <mail@iko.soy> dateMon 2 Nov 2026, 19:26 (3 hours ago) parentf1bf92c
18 files changed+239−106
docs/compiler.md+7−1 docs/development.md+1−1 docs/status.md+5−1 jibb-dev/lib/jibb.hoon+93−84 tests/golden/types-prelude-ui/types.txt+1−1 tests/lib/jibb-api-paths.hoon+37−1 tests/lib/jibb-bridge.hoon+5−2 tests/lib/jibb-hole-guards.hoon+3−3 tests/lib/jibb-proj-guards.hoon+2−2 tests/lib/jibb-theme.hoon+1−1 tests/lib/jibb-todo-full.hoon+9 tests/type-api-paths/about.txt+1−1 tests/type-api-paths/expected.txt+3 tests/type-import/about.txt+4−2 tests/type-import/expected.txt+15−5 tests/type-import/source.txt+1 tests/type-todo-full/cast-init.txt+43 tools/type-todo-full-test+8−1
docs/compiler.md+7−1
@@ -72,12 +72,16 @@ A single-arm cell pattern can bind two or more positions, with its last binder c
7272
7373String interpolation infers its pieces in order and preserves substitutions and pending constraints. A piece with a known atom aura, unrestricted `@`, or a tape `(list @tD)` is accepted; an isolated decimal literal takes its normal `@ud` default. A known cell reports that it needs a printer, and an explicitly generic atom asks for an aura at its use site. Loobeans, term singletons, non-tape collections, open types and a type fixed only later remain unsupported in this fragment.
7474
75+The Hoon bridge translates imported `(unit T)` to the canonical public `unit` union when the prepared template validates as the standard mold. Without that template it retains the older opaque collection behavior. Conversion recurses through imported unions and collection arguments, and API path/diff/poke analysis uses the same prepared reader. The fixtures prove identity, `fall`, `need`, casts, union- and list-nested `need`, canonical unit-typed API full/diff marks, and a canonical direct-poke export while leaving no-prelude output unchanged.
76+
7577The Hoon bridge translates imported `*` as the any-noun type, directly or within supported nonrecursive cells. The reader may still decline a disjoint tagged union with a noun payload, and recursive imports containing `*` remain unsupported. It accepts an exact fork of the two loobean singletons as `?`, and each singleton separately as `%.y` or `%.n`, including inside supported faced cells. Contextual loobean literals specialize against a matching singleton by noun, including a proven singleton in a direct union; named loobean singletons do not silently widen to a distinct aura. Open `%f`, other values, and other forks containing loobean singletons remain unsupported; recursive Hoon molds containing flags can also fail closed.
7678
7779A bare tag that provably matches no case of a known union reports the union and tag sites. This covers casts, single-argument calls, contextual unit payloads, list items and supported branch arms, including unnamed imported unions. For syntactic tuples, ordered fit replay can identify a missing tag in a nested position; an earlier mismatch or uncertainty stops the replay instead of guessing. Existing tags whose shape or payload does not fit retain the ordinary mismatch; unresolved tags stay pending.
7880
7981A change can replace uniquely named fields on a fully known, faced record spine, including through a nested wing. Replacements receive the field type as context, substitutions and pending constraints are retained, and the resulting type remains the original record. Missing fields, empty changes and definite replacement mismatches report sites; the expected-type site is the edit, since the original field declaration location is not retained. Unknown or partly unfaced spines, ambiguous fields and repeated edits remain unsupported. A cast to a known record also supplies field context to a tuple or record initializer, including nested list and union fields. The expected-type site is the cast mold; the original field declaration location is not retained. Isolated cart-style `init` and `update` expressions infer in this fragment. The complete cart-store source fails closed because store kind and declaration scope are not yet checked.
8082
83+Nested labels of the three public re-exports are normalized recursively to `ask`, `qath` and `raw-poke`, so prepared records and instantiated types do not expose their private `.internal` suffixes. Other private names remain private.
84+
8185For supported closed unions, the type printer keeps the union’s origin separate from its displayed name. It prints an in-scope name such as `msg` or `msg.lib`, including in records and gates; an accessible imported nongeneric alias may name a transitive union. A nongeneric body-local union that escapes its scope, or an origin without an accessible name, prints its cases separated by spaces, parenthesized when nested. That case-list form is print-only. A supported generic union prints its name and all arguments, including unused arguments; when its name is unavailable, the partial printer reports that limitation instead of dropping its arguments. Two faces for the same imported origin remain compatible; compatibility between distinct union origins, including in gate types, remains unsupported. Some comparisons of generic union arguments also remain unsupported rather than deciding equality or mismatch. The Hoon bridge also translates some imported unnamed unions into this representation; unsupported cases remain errors.
8286
8387Multi-argument calls form one right-nested sample: `f a b c` supplies `[a [b c]]`, with the last argument able to be a cell itself. The fragment fits the complete sample, preserving known faces and shared variables. Known sample positions can provide list or union context to arguments; unknown sample shapes use ordinary inference and some contextual forms remain unsupported. For a definite mismatch, the diagnostic points to a specific argument when it can establish which one failed; otherwise it reports the combined sample.
@@ -140,7 +144,9 @@ The store interface adds a derived `$-([action $-((unit @t) M)] (cmd M))` poke h
140144
141145When only that program's initializer and `main` are unresolved, a bounded transactional retry can derive the initializer's expected gate from the resolved update, view and subscription components. It instantiates all schemes above the greatest variable ID in the module and prelude, reuses the source-backed positional fit and stable replay, and leaves only the initializer's data variable open. The named initializer must be a direct gate whose transparent body is a tuple ending in null. Its own sample fixes data; ordinary inference, product and whole-gate fits, pending-tag and finalization checks, and a fresh ordinary `main` inference must all succeed before the ordinary kind and graph checks publish anything. Aliases, non-main libraries, simultaneous unresolved subscriptions, nonempty subscriptions and unrelated pending tags decline.
142146
143−A component-local recovery sequence handles a recognized direct program whose context-dependent definitions cannot resolve ordinarily. Update first derives its result from its inferred two-slot sample and canonical `cmd`/`list` templates. Subscription recovery then checks the same message/model relation and the canonical fourth slot. A narrow keyed-view proof finds exactly one direct `each (turn xs mapper)` site, derives the mapper from the actual `each` and `turn` schemes, and recovers the view before the existing initializer and ordinary `main` retries. Every recovered scheme must be closed and freshly allocated above the current environment and prelude IDs. A source screen skips doomed ordinary attempts only for this keyed shape and never skips final `main` inference; non-gate views and aliases decline without crashing. Final publication still requires all module definitions, the program-mold and gate-free checks, and request-value watchability.
147+Ordinary inference runs for every component before recovery, so a keyed view no longer causes an already-valid initializer to be skipped. Recovery is a fallback for unresolved components, not a replacement for definitions that check normally. The regression uses a call-bodied annotated initializer, which is outside the tuple-bodied initializer recovery shape.
148+
149+A component-local recovery sequence handles a recognized direct program whose context-dependent definitions cannot resolve ordinarily. Update first derives its result from its inferred two-slot sample and canonical `cmd`/`list` templates. Subscription recovery then checks the same message/model relation and the canonical fourth slot. A narrow keyed-view proof finds exactly one direct `each (turn xs mapper)` site, derives the mapper from the actual `each` and `turn` schemes, and recovers the view before the existing initializer and ordinary `main` retries. Every recovered scheme must be closed and freshly allocated above the current environment and prelude IDs. Non-gate views and aliases decline without crashing. Final publication still requires all module definitions, the program-mold and gate-free checks, and request-value watchability.
144150
145151Canonical `element` composition has two tightly scoped accommodations. Recursive result context is allowed only when every recursive side has the prepared prelude's `element` origin. When ordinary list-item fitting fails, an `element` target may instead prove its message argument invariantly or select one exact literal case with a full payload fit; a successful ordinary fit always takes precedence. This covers the unchanged todo's union controls and raw constructors without opening those paths to other unions. `tools/type-todo-full-test` checks the byte-identical island through both full APIs, the exact closed `main` type, structural downstream import, and model/message/mapper/watch rejection controls. It does not execute Jibb or implement runtime watching.
146152
docs/development.md+1−1
@@ -111,7 +111,7 @@ git clone https://github.com/urbit/tools /root/src/tools
111111| `tools/type-program-update-test` | Checks transactional direct-program update result recovery, union/boolean context, exact exported/imported types and fail-closed boundaries under eval and on the ship |
112112| `tools/type-program-watch-test` | Checks direct singleton request-value watchability against merged real-todo evidence, exact types/imports and rejection boundaries under eval and on the ship |
113113| `tools/type-store-test` | Checks the unchanged cart/basket through detailed and legacy inference, exact store/derived schemes, malformed-prelude guards, structural imports, source-bound state watch evidence and rejection guards under eval and on the ship |
114−| `tools/type-todo-full-test` | Fully checks the byte-identical todo island through real readers, exact main type, structural downstream import and rejection controls under eval and on the ship |
114+| `tools/type-todo-full-test` | Fully checks the byte-identical todo island and an ordinary call-bodied annotated-initializer variant through real readers, exact main types, structural downstream import and rejection controls under eval and on the ship |
115115| `tools/type-closed-gate-guards-test` | Checks closed gate sample labels and face uncertainty under eval and on the ship |
116116| `tools/type-constructor-fit-guards-test` | Checks constructor-case uncertainty and known mismatches under eval and on the ship |
117117| `tools/type-nested-union-guards-test` | Checks nested tagged-union case selection and uncertainty under eval and on the ship |
docs/status.md+5−1
@@ -57,7 +57,11 @@ Static and direct data-page `main` checking now completes the unchanged about pa
5757
5858The prelude now has the approved `store` mold and action-checking builder. The runtime envelope is the transparent `raw-poke`; a store's local `+$ poke` remains its ordinary action mold throughout inference. Direct two-wing store mains require closed state and action molds, exact init/state and update relations, and no gate-free-state restriction. Stores export those molds plus derived generic `poke` command and state-request gates. The command helper checks the canonical `raw-poke`, `cmd` and `unit` shapes, takes an action and reply, and returns `(cmd M)` directly. Separate source-bound store certificates prove only the actual imported state member watchable; API evidence checks and page-load rejection remain intact. The unchanged cart and basket pass detailed and legacy checking with exact mains, derived schemes and structural imports, including non-keyed view and null-sample initializer recovery. Multi-action declarations, lowering and runtime execution remain unsupported.
5959
60−The component-local program recovery now covers update, subscriptions, one direct keyed `each`/`turn` mapper and its view, then the existing initializer and ordinary `main` path. Each recovered scheme is closed and freshly allocated; a keyed source screen avoids repeated doomed ordinary attempts without skipping final `main`, and non-gate views decline safely. Canonical `element` recursion and exact singleton-case list fits are narrowly guarded, with successful ordinary fits taking precedence. The byte-identical unchanged todo now passes both detailed and legacy full-module checks with an exact closed `main` type and structural downstream import. Wrong models, messages, results, mappers, keys, aliases, non-gate views and watches fail closed. This is static checking only: no Jibb execution or runtime watching is claimed.
60+Keyed programs no longer skip ordinary component inference: an annotated initializer that checks normally is accepted, with recovery reserved for definitions that still need it. The todo fixture checks a call-bodied annotated initializer outside the tuple recovery shape through detailed and legacy inference, including on the ship.
61+
62+Imported Hoon `(unit T)` now converts to the validated canonical prelude `unit` when that template is supplied, instead of remaining an incompatible collection. Conversion recurses through imported unions and collections, and API path/diff/poke analysis uses the same prepared reader. The fixtures prove identity, `fall`, `need`, `(unit @t)` casts, union- and list-nested matching, canonical unit-typed API full/diff marks and a canonical direct-poke export while preserving the no-prelude compatibility report and wrong-collection rejection. Nested public re-export labels also remain `ask`, `qath` and `raw-poke` instead of leaking their private `.internal` suffixes into printed types.
63+
64+The component-local program recovery now covers update, subscriptions, one direct keyed `each`/`turn` mapper and its view, then the existing initializer and ordinary `main` path. Each recovered scheme is closed and freshly allocated; non-gate views decline safely. Canonical `element` recursion and exact singleton-case list fits are narrowly guarded, with successful ordinary fits taking precedence. The byte-identical unchanged todo now passes both detailed and legacy full-module checks with an exact closed `main` type and structural downstream import. Wrong models, messages, results, mappers, keys, aliases, non-gate views and watches fail closed. This is static checking only: no Jibb execution or runtime watching is claimed.
6165
6266The API path analyzer can retain its source, complete prepared prelude, reader results and resolved dependencies as evidence, and classify a unique declaration as watchable, not watchable or unknown. This remains declaration evidence rather than proof about an arbitrary request value. The narrow direct-program check above composes it with final value syntax, resolved imports and merged evidence for one plain request. Prepared artifacts and reader results remain trusted host inputs.
6367
jibb-dev/lib/jibb.hoon+93−84
@@ -6449,6 +6449,11 @@
64496449++ import-to-itype
64506450 |= node=*
64516451 ^- (unit itype)
6452+ (import-to-itype-standard node ~)
6453+::
6454+++ import-to-itype-standard
6455+ |= [node=* standard=(unit ischeme)]
6456+ ^- (unit itype)
64526457 ?@ node ~
64536458 ?+ -.node ~
64546459 %noun ?:(=(node [%noun ~]) `[%noun ~] ~)
@@ -6490,18 +6495,24 @@
64906495 ?: |(=(%map name) =(%mop name) =(%jar name) =(%jug name)) 2
64916496 0
64926497 ?: =(arity 0) ~
6493− =/ args=(unit (list itype)) (import-to-itypes +>.node)
6498+ =/ args=(unit (list itype)) (import-to-itypes-standard +>.node standard)
64946499 ?~ args ~
64956500 ?. =(arity (lent u.args)) ~
64966501 =/ keyed=(unit [types=(list itype) sub=isub]) (itype-collection-keys name u.args ~)
64976502 ?~ keyed ~
6503+ ?: =(%unit name)
6504+ ?. ?=([* ~] types.u.keyed) ~
6505+ ?~ standard `[%collection name types.u.keyed]
6506+ ?. (standard-unit-template u.standard /lib/jibb/prelude/jibb) ~
6507+ =/ nil=itype [%const [%null %n 0 '~']]
6508+ `[%union ~[nil [%cell nil [%face %u i.types.u.keyed]]] `[/lib/jibb/prelude/jibb %unit] `%unit types.u.keyed]
64986509 `[%collection name types.u.keyed]
64996510 %fork
65006511 :: Hoon's ordinary ? mold is the fork of its two %f singletons.
65016512 =/ raw=* +.node
65026513 ?: |(=(raw ~[[%atom %f `0] [%atom %f `1]]) =(raw ~[[%atom %f `1] [%atom %f `0]]))
65036514 `[%flag ~]
6504− =/ cases=(unit (list itype)) (import-to-itypes raw)
6515+ =/ cases=(unit (list itype)) (import-to-itypes-standard raw standard)
65056516 ?~ cases ~
65066517 ?~ u.cases ~
65076518 ?~ t.u.cases ~
@@ -6541,10 +6552,15 @@
65416552++ import-to-itypes
65426553 |= nodes=*
65436554 ^- (unit (list itype))
6555+ (import-to-itypes-standard nodes ~)
6556+::
6557+++ import-to-itypes-standard
6558+ |= [nodes=* standard=(unit ischeme)]
6559+ ^- (unit (list itype))
65446560 ?@ nodes ?:(=(nodes 0) `~ ~)
6545− =/ first (import-to-itype -.nodes)
6561+ =/ first (import-to-itype-standard -.nodes standard)
65466562 ?~ first ~
6547− =/ rest $(nodes +.nodes)
6563+ =/ rest $(nodes +.nodes, standard standard)
65486564 ?~ rest ~
65496565 `[u.first u.rest]
65506566::
@@ -6571,9 +6587,10 @@
65716587 ?. (levy t.cases |=(t=itype =(%disjoint (union-relate first (import-type-pattern t))))) |
65726588 $(cases t.cases)
65736589::
6574−++ find-imported-mold
6575− |= [module=term name=term externals=iexternals surs=(list term)]
6590+++ find-imported-mold-prelude
6591+ |= [module=term name=term externals=iexternals surs=(list term) prelude=ifile]
65766592 ^- (unit itype)
6593+ =/ standard=(unit ischeme) (find-jibb-mold %unit prelude)
65776594 ?. (lien surs |=(n=term =(n module))) ~
65786595 =/ found=iexternals
65796596 (skim externals |=(e=[module=term name=term result=*] &(=(module module.e) =(name name.e))))
@@ -6584,13 +6601,17 @@
65846601 ?. ?=(%& -.result) ~
65856602 =/ node=* +.result
65866603 ?. (imported-faces-valid node) ~
6587− ?@ node (import-to-itype node)
6588− ?: ?=(%ref -.node) (import-to-itype node)
6604+ ?@ node (import-to-itype-standard node standard)
6605+ ?: ?=(%ref -.node) (import-to-itype-standard node standard)
65896606 =/ pattern=(unit irec-pattern) (rec-pattern node module name)
6590− ?~ pattern (import-to-itype node)
6591− ?. has.u.pattern (import-to-itype node)
6607+ ?~ pattern (import-to-itype-standard node standard)
6608+ ?. has.u.pattern (import-to-itype-standard node standard)
65926609 `[%recursive module name `(crip "{(trip name)}.{(trip module)}")]
6593−
6610+::
6611+++ find-imported-mold
6612+ |= [module=term name=term externals=iexternals surs=(list term)]
6613+ ^- (unit itype)
6614+ (find-imported-mold-prelude module name externals surs *ifile)
65946615::
65956616++ collect-sur-imports
65966617 |= imports=(list import)
@@ -6608,9 +6629,10 @@
66086629 [mark.i.imports $(imports t.imports)]
66096630 $(imports t.imports)
66106631::
6611−++ find-imported-mark
6612− |= [name=term externals=imark-externals marks=(list term)]
6632+++ find-imported-mark-prelude
6633+ |= [name=term externals=imark-externals marks=(list term) prelude=ifile]
66136634 ^- (unit itype)
6635+ =/ standard=(unit ischeme) (find-jibb-mold %unit prelude)
66146636 ?. (unique-value-name name marks) ~
66156637 =/ found=imark-externals
66166638 (skim externals |=(e=[mark=term result=*] =(name mark.e)))
@@ -6620,7 +6642,12 @@
66206642 ?@ result ~
66216643 ?. ?=(%& -.result) ~
66226644 ?. (imported-faces-valid +.result) ~
6623− (import-to-itype +.result)
6645+ (import-to-itype-standard +.result standard)
6646+::
6647+++ find-imported-mark
6648+ |= [name=term externals=imark-externals marks=(list term)]
6649+ ^- (unit itype)
6650+ (find-imported-mark-prelude name externals marks *ifile)
66246651::
66256652++ find-jibb-interface
66266653 |= [face=term imports=ijimports]
@@ -7035,12 +7062,12 @@
70357062 ?^ vars.u.found ~
70367063 `[(itype-in-import typ.u.found u.iface i.t.names.sh prelude.state) state]
70377064 =/ found=(unit itype)
7038− (find-imported-mold i.t.names.sh n externals.state surs.state)
7065+ (find-imported-mold-prelude i.t.names.sh n externals.state surs.state ?~(prelude.state *ifile u.prelude.state))
70397066 ?~ found ~
70407067 `[u.found state]
70417068 ?: (lien marks.state |=(x=term =(x n)))
70427069 ?^ (find-simple-mold n molds.state) ~
7043− =/ imported=(unit itype) (find-imported-mark n mark-externals.state marks.state)
7070+ =/ imported=(unit itype) (find-imported-mark-prelude n mark-externals.state marks.state ?~(prelude.state *ifile u.prelude.state))
70447071 ?~ imported ~
70457072 `[u.imported state]
70467073 ?: (lien active.state |=(x=term =(x n))) ~
@@ -10325,11 +10352,6 @@
1032510352 =. entry entry(source src, target dst)
1032610353 `[entry u.rest]
1032710354::
10328−++ add-supported-defs
10329− |= [ds=(list def) all-defs=(list def) checked=(map term def) heads=(unit igate-prelude-evidence) env=ienv molds=imolds globals=(list term) externals=iexternals surs=(list term) mark-externals=imark-externals marks=(list term) jimports=ijimports reserved-molds=(list term) at=path prelude=(unit ifile) artifacts=(list iwidth-definition)]
10330− ^- [env=ienv artifacts=(list iwidth-definition)]
10331− (add-supported-defs-core ds all-defs checked heads env molds globals externals surs mark-externals marks jimports reserved-molds at prelude artifacts ~)
10332−::
1033310355
1033410356+$ iresolved [env=ienv grouped=(list term) artifacts=(list iwidth-definition)]
1033510357+$ iadj (map term (list term))
@@ -10471,12 +10493,11 @@
1047110493 =? checked |(?=(%gate -.val.d) ?=(%gate-wide -.val.d)) (~(put by checked) name.d d)
1047210494 `[[[name.d [typ vars]] env] checked artifacts]
1047310495++ add-supported-defs-core
10474− |= [ds=(list def) all-defs=(list def) checked=(map term def) heads=(unit igate-prelude-evidence) env=ienv molds=imolds globals=(list term) externals=iexternals surs=(list term) mark-externals=imark-externals marks=(list term) jimports=ijimports reserved-molds=(list term) at=path prelude=(unit ifile) artifacts=(list iwidth-definition) index=(unit [at=path source=@t prelude=ifile shapes=(map term shape)])]
10496+ |= [ds=(list def) checked=(map term def) heads=(unit igate-prelude-evidence) env=ienv molds=imolds globals=(list term) externals=iexternals surs=(list term) mark-externals=imark-externals marks=(list term) jimports=ijimports reserved-molds=(list term) at=path prelude=(unit ifile) artifacts=(list iwidth-definition) index=(unit [at=path source=@t prelude=ifile shapes=(map term shape)])]
1047510497 ^- [env=ienv artifacts=(list iwidth-definition)]
1047610498 ?~ ds [env artifacts]
1047710499 =/ d=def i.ds
1047810500 ?: ?=(%mold -.d) $(ds t.ds)
10479− ?: (lien (program-recovery-names all-defs) |=(n=term =(n name.d))) $(ds t.ds)
1048010501 ?. (unique-value-name name.d globals) $(ds t.ds)
1048110502 ?^ (ienv-lookup name.d env) $(ds t.ds)
1048210503 =/ top=(list term) (turn molds |=(m=[name=term body=shape] name.m))
@@ -10531,7 +10552,7 @@
1053110552 =/ heads=(unit igate-prelude-evidence) (direct-prelude-evidence ds prelude)
1053210553 |-
1053310554 =/ next=[env=ienv artifacts=(list iwidth-definition)]
10534− (add-supported-defs-core ds ds (direct-checked-gates ds env) heads env molds globals externals surs mark-externals marks jimports reserved-molds at prelude artifacts index)
10555+ (add-supported-defs-core ds (direct-checked-gates ds env) heads env molds globals externals surs mark-externals marks jimports reserved-molds at prelude artifacts index)
1053510556 =/ initial=istate [0 ~ ~ ~ molds globals externals surs mark-externals marks jimports reserved-molds ~ ~ ~ | at top prelude ~ 256 ~ ~ ~ ~ ~ ~]
1053610557 =. grec-index.initial index
1053710558 =/ out=iresolved (add-groups ds components graph env.next grouped artifacts.next initial)
@@ -11615,9 +11636,38 @@
1161511636 ?. ?=(%tvar -.i.args.tail) |
1161611637 =(var name.i.args.tail)
1161711638::
11639+++ prelude-public-label
11640+ |= label=@t
11641+ ^- (unit @t)
11642+ ?: =(label 'ask.internal') `'ask'
11643+ ?: =(label 'qath.internal') `'qath'
11644+ ?: =(label 'raw-poke.internal') `'raw-poke'
11645+ `label
11646+::
11647+++ prelude-label-nested
11648+ |= typ=itype
11649+ ^- itype
11650+ ?- -.typ
11651+ %union
11652+ =/ label=(unit @t) ?~(label.typ ~ (prelude-public-label u.label.typ))
11653+ [%union (turn cases.typ |=(c=itype (prelude-label-nested c))) origin.typ label (turn args.typ |=(c=itype (prelude-label-nested c)))]
11654+ %grec
11655+ =/ label=(unit @t) ?~(label.typ ~ (prelude-public-label u.label.typ))
11656+ typ(label label, args (turn args.typ |=(c=itype (prelude-label-nested c))))
11657+ %jrec
11658+ =/ label=(unit @t) ?~(label.typ ~ (prelude-public-label u.label.typ))
11659+ typ(label label)
11660+ %collection [%collection name.typ (turn args.typ |=(c=itype (prelude-label-nested c)))]
11661+ %face [%face name.typ $(typ body.typ)]
11662+ %fn [%fn $(typ sample.typ) $(typ product.typ)]
11663+ %cell [%cell $(typ hed.typ) $(typ tal.typ)]
11664+ * typ
11665+ ==
11666+::
1161811667++ prelude-label
1161911668 |= [typ=itype name=term vars=(list @ud)]
1162011669 ^- itype
11670+ =. typ (prelude-label-nested typ)
1162111671 ?: ?=(%jrec -.typ) typ(label `name)
1162211672 ?: ?=(%grec -.typ)
1162311673 ?. (identity-union-parameters vars args.typ) typ(label ~)
@@ -12113,22 +12163,22 @@
1211312163+$ iapi-mark-type [name=term typ=itype]
1211412164+$ iapi-path-typed [path=iapi-path full=itype diffs=(list iapi-mark-type)]
1211512165++ api-diff-types
12116− |= [names=(list term) externals=imark-externals declared=(list term)]
12166+ |= [names=(list term) externals=imark-externals declared=(list term) prelude=ifile]
1211712167 ^- (unit (list iapi-mark-type))
1211812168 ?~ names `~
12119− =/ typ=(unit itype) (find-imported-mark i.names externals declared)
12169+ =/ typ=(unit itype) (find-imported-mark-prelude i.names externals declared prelude)
1212012170 ?~ typ ~
1212112171 =/ tail=(unit (list iapi-mark-type)) $(names t.names)
1212212172 ?~ tail ~
1212312173 `[[i.names u.typ] u.tail]
1212412174::
1212512175++ api-path-types
12126− |= [paths=(list iapi-path) externals=imark-externals declared=(list term)]
12176+ |= [paths=(list iapi-path) externals=imark-externals declared=(list term) prelude=ifile]
1212712177 ^- (unit (list iapi-path-typed))
1212812178 ?~ paths `~
12129− =/ full=(unit itype) (find-imported-mark full.i.paths externals declared)
12179+ =/ full=(unit itype) (find-imported-mark-prelude full.i.paths externals declared prelude)
1213012180 ?~ full ~
12131− =/ diffs=(unit (list iapi-mark-type)) (api-diff-types diffs.i.paths externals declared)
12181+ =/ diffs=(unit (list iapi-mark-type)) (api-diff-types diffs.i.paths externals declared prelude)
1213212182 ?~ diffs ~
1213312183 =/ tail=(unit (list iapi-path-typed)) $(paths t.paths)
1213412184 ?~ tail ~
@@ -12148,7 +12198,7 @@
1214812198 `~[u.name]
1214912199::
1215012200++ api-path-analysis
12151− |= [mod=module externals=imark-externals prelude-values=(list term) prelude-molds=(list term)]
12201+ |= [mod=module externals=imark-externals prelude-values=(list term) prelude-molds=(list term) prelude=ifile]
1215212202 ^- (unit (list iapi-path-typed))
1215312203 ?: (lien defs.mod def-has-hole) ~
1215412204 ?^ (duplicate-defs defs.mod) ~
@@ -12171,7 +12221,7 @@
1217112221 ?~ paths ~
1217212222 =/ derived-pokes=(list term) ?~(pokes ~ ~[%poke])
1217312223 ?. (api-derived-names-valid u.paths derived-pokes mod prelude-values) ~
12174− (api-path-types u.paths externals declared)
12224+ (api-path-types u.paths externals declared prelude)
1217512225::
1217612226:: Source/graph entry for path analysis only. The returned paths retain
1217712227:: reader-derived mark types and import resolution has checked reachable
@@ -12185,12 +12235,13 @@
1218512235 =/ duplicate=(unit idiag) (duplicate-defs defs.p.parsed)
1218612236 ?^ duplicate [%| (show-duplicate-fields file src u.duplicate)]
1218712237 ?~ prepared [%| 'API path analysis needs the prepared prelude']
12238+ =/ public=ifile iface.u.prepared
1218812239 =/ prelude=(unit ifile) `iface.u.prepared
1218912240 =/ deps=jimports-result
1219012241 (resolve-jibb-imports imports.p.parsed externals marks modules ~[file] values.u.prepared molds.u.prepared ~ prelude)
1219112242 ?: ?=(%| -.deps) [%| p.deps]
1219212243 =/ paths=(unit (list iapi-path-typed))
12193− (api-path-analysis p.parsed marks values.u.prepared molds.u.prepared)
12244+ (api-path-analysis p.parsed marks values.u.prepared molds.u.prepared public)
1219412245 ?~ paths [%| 'API path declaration needs unsupported analysis']
1219512246 [%& u.paths]
1219612247::
@@ -12215,7 +12266,7 @@
1221512266 (resolve-jibb-imports imports.p.parsed externals marks modules ~[file] values.u.prepared molds.u.prepared ~ `public)
1221612267 ?: ?=(%| -.deps) [%| p.deps]
1221712268 =/ paths=(unit (list iapi-path-typed))
12218− (api-path-analysis p.parsed marks values.u.prepared molds.u.prepared)
12269+ (api-path-analysis p.parsed marks values.u.prepared molds.u.prepared public)
1221912270 ?~ paths [%| 'API path declaration needs unsupported analysis']
1222012271 [%& [file src u.prepared externals marks cache.p.deps u.paths]]
1222112272:: Graph-aware variant preserves the caller active stack and cache.
@@ -12236,7 +12287,7 @@
1223612287 (resolve-jibb-imports imports.p.parsed externals marks modules active values.u.prepared molds.u.prepared cache `public)
1223712288 ?: ?=(%| -.deps) [%| p.deps]
1223812289 =/ paths=(unit (list iapi-path-typed))
12239− (api-path-analysis p.parsed marks values.u.prepared molds.u.prepared)
12290+ (api-path-analysis p.parsed marks values.u.prepared molds.u.prepared public)
1224012291 ?~ paths [%| 'API path declaration needs unsupported analysis']
1224112292 [%& [file src u.prepared externals marks cache.p.deps u.paths]]
1224212293::
@@ -12323,7 +12374,7 @@
1232312374 =/ vals=(list term) (global-value-names ordinary)
1232412375 ?: (lien vals |=(n=term =(n %main))) [%| 'API module kind needs unsupported inference']
1232512376 =/ declared=(list term) (collect-mark-imports imports.mod)
12326− =/ mark-types=(unit (list iapi-mark-type)) (api-diff-types declared marks declared)
12377+ =/ mark-types=(unit (list iapi-mark-type)) (api-diff-types declared marks declared iface.prep)
1232712378 ?~ mark-types [%| 'API declared marks need unsupported inference']
1232812379 =/ prelude=(unit ifile) `iface.prep
1232912380 =/ deps=jimports-result
@@ -12357,7 +12408,7 @@
1235712408 =/ vals=(list term) (global-value-names ordinary)
1235812409 ?: (lien vals |=(n=term =(n %main))) [%| 'API module kind needs unsupported inference']
1235912410 =/ declared=(list term) (collect-mark-imports imports.mod)
12360− =/ mark-types=(unit (list iapi-mark-type)) (api-diff-types declared marks declared)
12411+ =/ mark-types=(unit (list iapi-mark-type)) (api-diff-types declared marks declared iface.prep)
1236112412 ?~ mark-types [%| 'API declared marks need unsupported inference']
1236212413 =/ prelude=(unit ifile) `iface.prep
1236312414 =/ deps=jimports-result
@@ -12558,10 +12609,10 @@
1255812609 [%& [support u.parts interface]]
1255912610::
1256012611++ api-mark-exports
12561− |= [marks=(list term) all=(list term) externals=imark-externals]
12612+ |= [marks=(list term) all=(list term) externals=imark-externals prelude=ifile]
1256212613 ^- imold-types
1256312614 ?~ marks ~
12564− =/ t=(unit itype) (find-imported-mark i.marks externals all)
12615+ =/ t=(unit itype) (find-imported-mark-prelude i.marks externals all prelude)
1256512616 ?~ t $(marks t.marks)
1256612617 [[i.marks [u.t ~]] $(marks t.marks)]
1256712618::
@@ -12597,11 +12648,11 @@
1259712648 =/ n=term i.names.sh
1259812649 ?. (unique-value-name n marks) ~
1259912650 ?: |((lien prelude-values |=(x=term =(n x))) (lien prelude-molds |=(x=term =(n x)))) ~
12600− =/ mark=(unit itype) (find-imported-mark n mark-externals marks)
12651+ =/ mark=(unit itype) (find-imported-mark-prelude n mark-externals marks u.prelude)
1260112652 ?~ mark ~
1260212653 =/ sc=(unit ischeme) (derived-poke-command-scheme u.prelude u.mark)
1260312654 ?~ sc ~
12604− `[~[[%poke u.sc]] (api-mark-exports marks marks mark-externals) at ~[[n i.t.t.at n]] ~ ~ ~ ~]
12655+ `[~[[%poke u.sc]] (api-mark-exports marks marks mark-externals u.prelude) at ~[[n i.t.t.at n]] ~ ~ ~ ~]
1260512656::
1260612657:: Source-proven ordinary helpers validate each selected /sur dependency.
1260712658:: Unused or less direct cores remain unsupported by this first interface.
@@ -13186,48 +13237,6 @@
1318613237 ?~ mapper ~
1318713238 `[xs u.mapper]
1318813239::
13189−++ program-recovery-names
13190− |= ds=(list def)
13191− ^- (list term)
13192− =/ main=(unit def) (program-main-def ds)
13193− ?~ main ~
13194− =/ parts=(unit [init=term update=term view=term subs=term])
13195− (program-main-parts u.main)
13196− ?~ parts ~
13197− =/ views=(list def)
13198− (skim ds |=(d=def &(?=(%value -.d) =(view.u.parts name.d))))
13199− ?. ?=([* ~] views) ~
13200− =/ view-def=def i.views
13201− ?> ?=(%value -.view-def)
13202− =/ written=(unit sample) (direct-gate-sample view-def)
13203− ?~ written ~
13204− =/ body=expr
13205− ?- -.val.view-def
13206− %gate body.val.view-def
13207− %gate-wide body.val.view-def
13208− * !!
13209− ==
13210− =/ sites=(unit (list iview-site)) (program-view-sites body ~)
13211− ?~ sites ~
13212− ?. ?=([* ~] u.sites) ~
13213− =/ mapper=term mapper.i.u.sites
13214− =/ components=(list term)
13215− :~ init.u.parts
13216− update.u.parts
13217− view.u.parts
13218− subs.u.parts
13219− ==
13220− ?: (lien components |=(n=term =(n mapper))) ~
13221− =/ mappers=(list def)
13222− (skim ds |=(d=def &(?=(%value -.d) =(mapper name.d))))
13223− ?. ?=([* ~] mappers) ~
13224− :~ init.u.parts
13225− update.u.parts
13226− view.u.parts
13227− subs.u.parts
13228− mapper
13229− ==
13230−::
1323113240++ program-sample-binders
1323213241 |= sam=sample
1323313242 ^- (list term)
@@ -13967,7 +13976,7 @@
1396713976 ?~ error ~
1396813977 ?. ?=(%union -.typ.u.raw) ~
1396913978 =/ poke-case=itype
13970− [%cell [%const [%term %tas %poke '%poke']] [%cell [%face %p typ.u.raw(label `'raw-poke.internal')] [%face %reply [%fn u.error [%var m]]]]]
13979+ [%cell [%const [%term %tas %poke '%poke']] [%cell [%face %p typ.u.raw(label `'raw-poke')] [%face %reply [%fn u.error [%var m]]]]]
1397113980 =/ go-case=itype
1397213981 [%cell [%const [%term %tas %go '%go']] [%face %url [%atom %t]]]
1397313982 =/ wait-case=itype
@@ -14111,7 +14120,7 @@
1411114120 ?~ heads resolution
1411214121 =/ checked=(map term def) (direct-checked-gates ds env.resolution)
1411314122 =/ completed=[env=ienv artifacts=(list iwidth-definition)]
14114− (add-supported-defs-core ~[main] ds checked heads env.resolution molds.initial globals.initial externals.initial surs.initial mark-externals.initial marks.initial jimports.initial reserved-molds.initial at.initial prelude.initial artifacts.resolution grec-index.initial)
14123+ (add-supported-defs-core ~[main] checked heads env.resolution molds.initial globals.initial externals.initial surs.initial mark-externals.initial marks.initial jimports.initial reserved-molds.initial at.initial prelude.initial artifacts.resolution grec-index.initial)
1411514124 [env.completed grouped.resolution artifacts.completed]
1411614125::
1411714126:: A static main may retain a generic element message in its ordinary
tests/golden/types-prelude-ui/types.txt+1−1
@@ -82,4 +82,4 @@ partial inference; module not checked
8282 ^
8383++ load: $-(@t (ask [count=@ud]))
8484++ page-view: $-([count=@ud] (element !!))
85−++ static-page: [load=$-(@t (ask.internal [count=@ud])) view=$-([count=@ud] (element !!))]
85+++ static-page: [load=$-(@t (ask [count=@ud])) view=$-([count=@ud] (element !!))]
tests/lib/jibb-api-paths.hoon+37−1
@@ -51,6 +51,32 @@
5151 =/ params=tape
5252 (zing (turn segments.info |=(s=pseg:jibb ?:(?=(%typed -.s) " {(trip name.s)}=@{(trip aura.s)}" ""))))
5353 (crip "{(trip name.info)}: full={(show-itype:jibb full.item ~)} diffs:{diff-text} parameters:{params}")
54+++ standard-unit
55+ |= typ=itype:jibb
56+ ^- ?
57+ ?. ?=(%union -.typ) |
58+ ?. =(origin.typ `[/lib/jibb/prelude/jibb %unit]) |
59+ ?. =(label.typ `%unit) |
60+ =(args.typ ~[[%atom %t]])
61+++ unit-detail
62+ |= result=(each (list iapi-path-typed:jibb) @t)
63+ ^- @t
64+ ?: ?=(%| -.result) 'unit marks: rejected'
65+ ?. ?=([* ~] p.result) 'unit marks: wrong path count'
66+ =/ item=iapi-path-typed:jibb i.p.result
67+ ?. ?=([* ~] diffs.item) 'unit marks: wrong diff count'
68+ ?: &((standard-unit full.item) (standard-unit typ.i.diffs.item))
69+ 'unit marks: canonical'
70+ 'unit marks: opaque'
71+++ unit-poke-detail
72+ |= interface=(unit ifile:jibb)
73+ ^- @t
74+ ?~ interface 'unit poke: rejected'
75+ =/ mark=(unit ischeme:jibb) (find-jibb-mold:jibb %unit-full u.interface)
76+ ?~ mark 'unit poke: missing export'
77+ ?. ?=(~ vars.u.mark) 'unit poke: generic export'
78+ ?: (standard-unit typ.u.mark) 'unit poke: canonical'
79+ 'unit poke: opaque'
5480++ scry-detail
5581 |= result=(each (list iapi-path-typed:jibb) @t)
5682 ^- @t
@@ -78,6 +104,15 @@
78104 =/ duplicate=(list [mark=term result=*]) [[%todos mt] marks]
79105 =/ file=path /ui/api/todo/jibb
80106 =/ ok (api-path-analysis-source:jibb file api ~ marks ~ prepared)
107+ =/ unit-node=* [%apply %unit ~[[%atom %t ~]]]
108+ =/ unit-marks=imark-externals:jibb ~[[%unit-full [%& unit-node]] [%unit-diff [%& unit-node]]]
109+ =/ unit-api=@t '/% %unit-full\0a/% %unit-diff\0a+$ paths [%items /items (facts unit-full unit-diff)]\0a'
110+ =/ unit-ok (api-path-analysis-source:jibb /ui/api/unit/jibb unit-api ~ unit-marks ~ prepared)
111+ =/ unit-poke-source=@t '/% %unit-full\0a+$ poke unit-full\0a'
112+ =/ unit-poke-parsed=(each module:jibb error:jibb) (parse:jibb /ui/api/unit/jibb unit-poke-source)
113+ =/ unit-poke=(unit ifile:jibb)
114+ ?: ?=(%| -.unit-poke-parsed) ~
115+ (api-poke-interface:jibb /ui/api/unit/jibb p.unit-poke-parsed unit-marks values.u.prepared molds.u.prepared `iface.u.prepared)
81116 =/ miss (api-path-analysis-source:jibb file api ~ missing ~ prepared)
82117 =/ dup (api-path-analysis-source:jibb file api ~ duplicate ~ prepared)
83118 =/ undeclared (api-path-analysis-source:jibb file missing-decl ~ marks ~ prepared)
@@ -100,5 +135,6 @@
100135 (show-result 'todo' ok)
101136 ==
102137 =. lines ?:(?=(%& -.ok) (weld lines (turn p.ok show-path)) lines)
103− (weld lines ~[(show-result 'missing mark' miss) (show-result 'duplicate mark' dup) (show-result 'undeclared mark' undeclared) (show-result 'value collision' clash) (show-result 'poke collision' poke) (show-result 'scry matching parameters' scry-ok) (scry-detail scry-ok) (show-result 'scry unknown parameter' scry-bad) (show-result 'wrong path' wrong) (show-result 'missing prelude' unprepared) (show-result 'private import' private) (show-result 'indirect private import' indirect) (show-result 'cycle' cycle)])
138+ =. lines ?:(?=(%& -.unit-ok) (weld lines (turn p.unit-ok show-path)) lines)
139+ (weld lines ~[(unit-detail unit-ok) (unit-poke-detail unit-poke) (show-result 'missing mark' miss) (show-result 'duplicate mark' dup) (show-result 'undeclared mark' undeclared) (show-result 'value collision' clash) (show-result 'poke collision' poke) (show-result 'scry matching parameters' scry-ok) (scry-detail scry-ok) (show-result 'scry unknown parameter' scry-bad) (show-result 'wrong path' wrong) (show-result 'missing prelude' unprepared) (show-result 'private import' private) (show-result 'indirect private import' indirect) (show-result 'cycle' cycle)])
104140--
tests/lib/jibb-bridge.hoon+5−2
@@ -129,6 +129,8 @@
129129 [%fixture %texts (read %texts)]
130130 [%fixture %numbers (read %numbers)]
131131 [%fixture %maybe (read %maybe)]
132+ [%fixture %unit-choice [%& [%fork ~[[%atom %n [~ 0]] [%cell [%atom %tas [~ %some]] [%apply %unit ~[[%atom %t ~]]]]]]]]
133+ [%fixture %unit-list [%& [%apply %list ~[[%apply %unit ~[[%atom %t ~]]]]]]]
132134 [%fixture %tagged-list (read %tagged-list)]
133135 [%fixture %buckets (read %buckets)]
134136 [%fixture %collection-rec (read %collection-rec)]
@@ -159,9 +161,10 @@
159161 =/ prelude=@t (crip "++ prelude-id |= x x\0a")
160162 =/ modules=(list [at=path source=@t]) ~[[~[%ui %helper %jibb] dep]]
161163 =/ hidden=@t (golden-types-with-prelude:jibb /ui/main/jibb root external ~ modules prelude)
162− =/ unit-prelude=@t (crip "+$ unit |$ [A]\0a ~\0a [~ u=A]\0a")
164+ =/ unit-prelude=@t
165+ (crip "+$ list |$ [A]\0a ~\0a [i=A t=(list A)]\0a+$ unit |$ [A]\0a ~\0a [~ u=A]\0a++ fall |= args=[(unit A) A]\0a ?- args\0a [maybe fallback]\0a ?- maybe\0a ~ fallback\0a [~ value] value\0a++ need |= maybe=(unit A)\0a ?- maybe\0a ~ !!\0a [~ value] value\0a")
163166 =/ unit-client=@t
164− (crip "/- fixture\0a++ canonical ^- (unit @t) `\"hi\"\0a++ lookalike ^- zero-lookalike.fixture `\"hi\"\0a")
167+ (crip "/- fixture\0a++ canonical ^- (unit @t) `\"hi\"\0a++ canonical-fall |= x=(unit @t) (fall x \"fallback\")\0a++ canonical-need |= x=(unit @t) (need x)\0a++ canonical-cast |= x=(unit @t) ^- (unit @t) x\0a++ maybe-id |= x=maybe.fixture x\0a++ maybe-fall |= x=maybe.fixture (fall x \"fallback\")\0a++ maybe-need |= x=maybe.fixture (need x)\0a++ maybe-cast |= x=maybe.fixture ^- (unit @t) x\0a++ unit-choice-need |= x=unit-choice.fixture\0a ?- x\0a ~ \"empty\"\0a [%some maybe] (need maybe)\0a++ unit-list-need |= xs=unit-list.fixture\0a ?- xs\0a ~ \"empty\"\0a [maybe rest] (need maybe)\0a++ lookalike ^- zero-lookalike.fixture `\"hi\"\0a")
165168 =/ unit-report=@t
166169 (golden-types-with-prelude:jibb /ui/unit-client/jibb unit-client external ~ ~ unit-prelude)
167170 (cat 3 report (cat 3 (crip "\0areader-collapsed: {(show-result:jibb-import (read %collapsed))}\0areader-mixed-zero: {(show-result:jibb-import (read %mixed-zero))}\0areader-separate-tags: {(show-result:jibb-import (read %separate-tags))}\0areader-separate-terms: {(show-result:jibb-import (read %separate-terms))}\0a") (cat 3 hidden (cat 3 '\0a' (cat 3 unit-report (cat 3 '\0a' (cat 3 noun-synthetic (cat 3 '\0a' (cat 3 recursive-list-synthetic (cat 3 '\0a' named-recursive-synthetic))))))))))
tests/lib/jibb-hole-guards.hoon+3−3
@@ -48,11 +48,11 @@
4848 ?. &(?=(%& -.g) ?=(%& -.b) ?=(%& -.v))
4949 ["API path control sources did not parse" failures]
5050 =/ ext=imark-externals:jibb ~[[%todo [%& [%atom %t ~]]]]
51− =? failures ?=(~ (api-path-analysis:jibb p.g ext ~ ~))
51+ =? failures ?=(~ (api-path-analysis:jibb p.g ext ~ ~ *ifile:jibb))
5252 ["a valid API path was rejected" failures]
53− =? failures ?=(^ (api-path-analysis:jibb p.b ext ~ ~))
53+ =? failures ?=(^ (api-path-analysis:jibb p.b ext ~ ~ *ifile:jibb))
5454 ["an API path ignored an unused mold hole" failures]
55− =? failures ?=(^ (api-path-analysis:jibb p.v ext ~ ~))
55+ =? failures ?=(^ (api-path-analysis:jibb p.v ext ~ ~ *ifile:jibb))
5656 ["an API path ignored an unused value hole" failures]
5757 =/ prepared=(unit iprelude:jibb) (prepare-prelude-with-internal:jibb real-prelude real-internal)
5858 ?~ prepared ["actual prelude was not prepared" failures]
tests/lib/jibb-proj-guards.hoon+2−2
@@ -46,8 +46,8 @@
4646 ?: |(?=(%| -.valid) ?=(%| -.clash) ?=(%| -.poke)) ~["API reservation controls did not parse"]
4747 =/ todo=imark-externals:jibb ~[[%todo [%& [%atom %t ~]]]]
4848 =/ proj-mark=imark-externals:jibb ~[[%proj [%& [%atom %t ~]]]]
49− =/ good=(unit (list iapi-path-typed:jibb)) (api-path-analysis:jibb p.valid todo ~ ~)
50− =/ bad=(unit (list iapi-path-typed:jibb)) (api-path-analysis:jibb p.clash todo ~ ~)
49+ =/ good=(unit (list iapi-path-typed:jibb)) (api-path-analysis:jibb p.valid todo ~ ~ *ifile:jibb)
50+ =/ bad=(unit (list iapi-path-typed:jibb)) (api-path-analysis:jibb p.clash todo ~ ~ *ifile:jibb)
5151 ?~ good ~["a literal /proj path was rejected"]
5252 ?^ bad ~["an API-derived proj path name was accepted"]
5353 =/ prepared=(unit iprelude:jibb) (prepare-prelude-with-internal:jibb real-prelude real-internal)
tests/lib/jibb-theme.hoon+1−1
@@ -63,7 +63,7 @@
6363 =/ prepared=(unit iprelude:jibb)
6464 (prepare-prelude-with-internal:jibb public private)
6565 ?~ prepared ~["theme prelude did not prepare"]
66− =/ expected=tape "[space=[s1=@t [s2=@t s3=@t]] [tones=[normal=@t [background=@t [accent=@t [danger=@t muted=@t]]]] [wide=@t [lang=@t [zone=@t [font=(unit qath.internal) dark=(unit [tones=[normal=@t [background=@t [accent=@t [danger=@t muted=@t]]]]])]]]]]]"
66+ =/ expected=tape "[space=[s1=@t [s2=@t s3=@t]] [tones=[normal=@t [background=@t [accent=@t [danger=@t muted=@t]]]] [wide=@t [lang=@t [zone=@t [font=(unit qath) dark=(unit [tones=[normal=@t [background=@t [accent=@t [danger=@t muted=@t]]]]])]]]]]]"
6767 =/ negatives=(list [label=tape src=@t])
6868 :~ ["wrong nested aura" wrong-nested-aura]
6969 ["missing required field" missing-field]
tests/lib/jibb-todo-full.hoon+9
@@ -17,6 +17,7 @@
1717/* alias %txt /tests/type-todo-full/alias/txt
1818/* wrong-watch %txt /tests/type-todo-full/wrong-watch/txt
1919/* non-gate-view %txt /tests/type-todo-full/non-gate-view/txt
20+/* cast-init %txt /tests/type-todo-full/cast-init/txt
2021/* expected %txt /tests/type-todo-full/expected/txt
2122|%
2223++ text
@@ -130,6 +131,14 @@
130131 (todo-full-legacy-report prelude internal (text sur) (text action) (text todos) (text update) (text item) (text api) (text source))
131132 ?. =((to-wain:format (cat 3 legacy '\0a')) expected)
132133 ~[leaf+"legacy full todo report differs"]
134+ =/ cast-report=@t
135+ (todo-full-report prelude internal (text sur) (text action) (text todos) (text update) (text item) (text api) (text cast-init))
136+ ?. =((to-wain:format (cat 3 cast-report '\0a')) expected)
137+ ~[leaf+"ordinary annotated initializer was rejected"]
138+ =/ cast-legacy=@t
139+ (todo-full-legacy-report prelude internal (text sur) (text action) (text todos) (text update) (text item) (text api) (text cast-init))
140+ ?. =((to-wain:format (cat 3 cast-legacy '\0a')) expected)
141+ ~[leaf+"legacy ordinary annotated initializer was rejected"]
133142 =/ imported=@t
134143 (todo-full-import-report prelude internal (text sur) (text action) (text todos) (text update) (text item) (text api) (text source))
135144 ?. =(imported 'downstream import accepted')
tests/type-api-paths/about.txt+1−1
@@ -1,3 +1,3 @@
11source: Overview, Agent APIs: a path names a request, a route and a mark for full state; `facts` supplies diff marks and an optional scry path. Imports: Hoon marks are read at their declared names.
2−tests: Partial path analysis uses the actual todo `/sur` and Ford-style mark samples, preserving the full and diff types and typed path parameter. Matching scry parameters are accepted; unknown scry parameters, missing, duplicate and undeclared marks, value and derived-name collisions, an invalid module path, a missing prelude, private imports and an import cycle fail closed. This does not check the module or derive request gates.
2+tests: Partial path analysis uses the actual todo `/sur` and Ford-style mark samples, preserving the full and diff types and typed path parameter. Synthetic full and diff marks containing Hoon units must retain the canonical prelude union in path analysis and a direct poke export, not merely print like it. Matching scry parameters are accepted; unknown scry parameters, missing, duplicate and undeclared marks, value and derived-name collisions, an invalid module path, a missing prelude, private imports and an import cycle fail closed. This does not check the module or derive request gates.
33expect: partial path metadata or an unsupported/error report
tests/type-api-paths/expected.txt+3
@@ -3,6 +3,9 @@ todo: accepted 3 path cases
33todos: full=(list [id=@ud [done=? text=@t]]) diffs: parameters:
44changes: full=(list [id=@ud [done=? text=@t]]) diffs: todo-update=[%added item=[id=@ud [done=? text=@t]]] [%toggled id=@ud] parameters:
55todo-by-id: full=[id=@ud [done=? text=@t]] diffs: parameters: id=@ud
6+items: full=(unit @t) diffs: unit-diff=(unit @t) parameters:
7+unit marks: canonical
8+unit poke: canonical
69missing mark: API path declaration needs unsupported analysis
710duplicate mark: API path declaration needs unsupported analysis
811undeclared mark: API path declaration needs unsupported analysis
tests/type-import/about.txt+4−2
@@ -12,8 +12,10 @@ as `?`, including in either supplied order. Open `%f`, out-of-range values,
1212duplicates, overlapping zero constants, extra or faced cases and malformed
1313forks stay unsupported. A structurally unit-like import does not gain unit
1414construction even when a canonical prelude unit is supplied; constructing
15−that canonical unit succeeds. It covers matching and
16−mismatched collections, nested union arguments, and malformed collection names
15+that canonical unit succeeds. With the validated canonical template, the
16+same imported unit fits identity, `fall`, `need` and `(unit @t)` casts, including
17+when nested in an imported union. It covers matching and mismatched collections,
18+nested union arguments, and malformed collection names
1719and arities. An imported `*` can widen a value, while malformed nouns,
1820overlapping direct or nested union cases, and unknown gate or empty cases
1921stay unsupported. Distinct tagged cases with a noun payload remain disjoint.
tests/type-import/expected.txt+15−5
@@ -53,6 +53,7 @@ partial inference; module not checked
5353/test.jibb:32:45: argument has type (unit @t)
5454++ wrong-kind |= x=maybe.fixture (text-list x)
5555 ^
56+++ maybe-id: $-((unit @t) (unit @t))
5657++ bad-kind: sample mold is not supported by partial inference
5758++ bad-arity: sample mold is not supported by partial inference
5859++ bad-argument: sample mold is not supported by partial inference
@@ -63,10 +64,10 @@ partial inference; module not checked
6364++ chain-again: $-(chain.fixture chain.fixture)
6465++ other-id: $-(other.fixture other.fixture)
6566++ chain-mismatch: call's sample and argument types do not unify
66−/test.jibb:42:39: called gate has type $-(chain.fixture chain.fixture)
67+/test.jibb:43:39: called gate has type $-(chain.fixture chain.fixture)
6768++ chain-mismatch |= x=other.fixture (chain-id x)
6869 ^
69−/test.jibb:42:48: argument has type other.fixture
70+/test.jibb:43:48: argument has type other.fixture
7071++ chain-mismatch |= x=other.fixture (chain-id x)
7172 ^
7273++ recursive-field: field is not available to partial inference
@@ -77,10 +78,10 @@ partial inference; module not checked
7778++ raw-ref: sample mold is not supported by partial inference
7879++ raw-null: $-(~ ~)
7980++ cross-module: call's sample and argument types do not unify
80−/test.jibb:50:36: called gate has type $-(chain.fixture chain.fixture)
81+/test.jibb:51:36: called gate has type $-(chain.fixture chain.fixture)
8182++ cross-module |= x=chain.second (chain-id x)
8283 ^
83−/test.jibb:50:45: argument has type chain.second
84+/test.jibb:51:45: argument has type chain.second
8485++ cross-module |= x=chain.second (chain-id x)
8586 ^
8687++ chain-pattern: recursive pattern is not supported by partial inference
@@ -105,7 +106,7 @@ partial inference; module not checked
105106++ flag-faced: sample mold is not supported by partial inference
106107++ flag-malformed: sample mold is not supported by partial inference
107108++ mixed-zero: Hoon union cases overlap
108−/test.jibb:81:20: invalid imported mold
109+/test.jibb:82:20: invalid imported mold
109110++ mixed-zero |= x=mixed-zero.fixture x
110111 ^
111112++ separate-tags: $-(([%left [%$ @t]] [%right [? @t]]) ([%left [%$ @t]] [%right [? @t]]))
@@ -118,6 +119,15 @@ partial inference; module not checked
118119++ use: recursive mold name is not available in this scope
119120partial inference; module not checked
120121++ canonical: (unit @t)
122+++ canonical-fall: $-((unit @t) @t)
123+++ canonical-need: $-((unit @t) @t)
124+++ canonical-cast: $-((unit @t) (unit @t))
125+++ maybe-id: $-((unit @t) (unit @t))
126+++ maybe-fall: $-((unit @t) @t)
127+++ maybe-need: $-((unit @t) @t)
128+++ maybe-cast: $-((unit @t) (unit @t))
129+++ unit-choice-need: $-((~ [%some (unit @t)]) @t)
130+++ unit-list-need: $-((list (unit @t)) @t)
121131++ lookalike: cast constraint is not supported by partial inference
122132noun: *
123133malformed: unsupported
tests/type-import/source.txt+1
@@ -30,6 +30,7 @@
3030++ same-list |= x=texts.fixture (text-list x)
3131++ wrong-item |= x=numbers.fixture (text-list x)
3232++ wrong-kind |= x=maybe.fixture (text-list x)
33+++ maybe-id |= x=maybe.fixture x
3334++ bad-kind |= x=bad-kind.fixture x
3435++ bad-arity |= x=bad-arity.fixture x
3536++ bad-argument |= x=bad-argument.fixture x
tests/type-todo-full/cast-init.txtnew file+43
@@ -0,0 +1,43 @@
1+/= todo /ui/api/todo
2+
3+++ main (program init update view subs)
4+
5++$ model [todos=(list item.todo) draft=@t error=(unit @t)]
6++$ msg
7+ [%typed text=@t]
8+ %submit
9+ [%toggled id=@ud]
10+ [%got todos=(list item.todo)]
11+ [%acked err=(unit @t)]
12+
13+++ make-model |= ts=(list item.todo)
14+ ^- model [ts "" ~]
15+
16+++ init |= ts=(list item.todo)
17+ ^- model (make-model ts)
18+
19+++ update |= [=msg m=model]
20+ ?- msg
21+ [%typed t]
22+ ?- (gth (lent (tuba (trip t))) 80)
23+ %.y [m(draft=t error=`"Too long") ~]
24+ %.n [m(draft=t error=~) ~]
25+ %submit [m(draft="") ~[(poke.todo [%add draft.m] |=%acked)]]
26+ [%toggled id] [m ~[(poke.todo [%toggle id] |=%acked)]]
27+ [%got ts] [m(todos=ts) ~]
28+ [%acked err] [m(error=err) ~]
29+
30+++ subs |= m=model
31+ ~[[%watch (todos.todo |=%got)]]
32+
33+++ view |= m=model
34+ column ~[gap+%s2] ~[
35+ heading 2 "Todos"
36+ each (turn todos.m row-of)
37+ row ~[gap+%s1] ~[
38+ el ~[width+[%fill 1]] (field "New todo" draft.m |=%typed)
39+ button "Add" %submit
40+ el ~[tone+%danger] (text (fall error.m ""))
41+
42+++ row-of |= t=item.todo
43+ [id.t (toggle done.t text.t [%toggled id.t])]
tools/type-todo-full-test+8−1
@@ -32,7 +32,7 @@ suites = {'detailed': shared + tests[report_at:legacy_at] + '\n--\n',
3232 'negative': shared + tests[negative_at:test_at] + '\n--\n'}
3333names = ('sur', 'action', 'todos', 'update', 'item', 'api', 'source',
3434 'wrong-model', 'wrong-message', 'wrong-result', 'ambiguous-mapper',
35− 'open-key', 'alias', 'wrong-watch', 'non-gate-view', 'expected')
35+ 'open-key', 'alias', 'wrong-watch', 'non-gate-view', 'cast-init', 'expected')
3636prefix = ('=/ jibb .\n=/ jibb-import\n' + reader + '\n' +
3737 ''.join('=/ ' + name + '=wain (to-wain:format ' + name + '-text)\n'
3838 for name in names) + '=/ suite\n')
@@ -46,6 +46,7 @@ fixtures = {'sur': 'tests/type-api-paths/todo-sur.txt',
4646 **{name: f'tests/type-todo-full/{name}.txt'
4747 for name in ('wrong-model', 'wrong-message', 'wrong-result',
4848 'ambiguous-mapper', 'open-key', 'alias', 'wrong-watch', 'non-gate-view')},
49+ 'cast-init': 'tests/type-todo-full/cast-init.txt',
4950 'expected': 'tests/type-todo-full/expected.txt'}
5051
5152def evaluate(expression, kind):
@@ -79,6 +80,12 @@ if legacy != expected:
7980 legacy.decode().splitlines(keepends=True),
8081 fromfile='expected.txt', tofile='legacy'))
8182 sys.exit('legacy full todo report differs')
83+for expression, label in (('todo-full-report', 'detailed cast initializer'),
84+ ('todo-full-legacy-report', 'legacy cast initializer')):
85+ cast = evaluate(f'({expression}:suite prelude internal sur-text action-text todos-text update-text item-text api-text cast-init-text)', 'detailed' if expression == 'todo-full-report' else 'legacy')
86+ if cast != expected:
87+ sys.stderr.buffer.write(cast)
88+ sys.exit(label + ' was rejected')
8289imported = evaluate('(todo-full-import-report:suite prelude internal sur-text action-text todos-text update-text item-text api-text source-text)', 'import')
8390if imported != b'downstream import accepted\n':
8491 sys.stderr.buffer.write(imported)