Back out the worst of the unsound nonsense
This commit is contained in:
@@ -94,108 +94,35 @@ view envelope is well-formed, and recursively validates the `baseView`, but it
|
||||
must treat the guard payload/reference as opaque executable data, not as another
|
||||
View.
|
||||
|
||||
## 4. Polymorphic and Abstract Views
|
||||
## 4. Soundness Boundary
|
||||
|
||||
View Contracts support portable polymorphism over Views. The View language is
|
||||
interpreted by the same portable checker model implemented in `tricu` terms.
|
||||
Views are descriptive boundary metadata, not types and not proofs about opaque
|
||||
Tree Calculus terms. In particular, the checker does not claim parametricity,
|
||||
representation independence, or existential abstraction.
|
||||
|
||||
Source syntax may use underscore-prefixed names as View variables inside
|
||||
annotations:
|
||||
Raw Tree Calculus observation can distinguish values by their tree
|
||||
representation. A term advertised as `Fn [A] A` can inspect its argument and
|
||||
choose a representation-dependent result; a metadata-only checker cannot rule
|
||||
that out. The same issue applies transitively through higher-order arguments and
|
||||
dynamically constructed observers.
|
||||
|
||||
```tri
|
||||
id x@_a =@_a x
|
||||
const x@_a y@_b =@_a x
|
||||
compose f@(Fn [_b] _c) g@(Fn [_a] _b) x@_a =@_c f (g x)
|
||||
```
|
||||
The checker therefore accepts only monomorphic Views. Legacy `Var`, `Forall`,
|
||||
and `Exists` tags remain reserved so old artifacts fail deterministically, but
|
||||
they are not well-formed checker inputs.
|
||||
|
||||
In the portable artifact, these lower to scoped View binders rather than
|
||||
unscoped source-name conventions. This fits the existing View encoding style:
|
||||
Views are tagged records with numeric tags and tagged fields. Polymorphic forms
|
||||
are View records such as:
|
||||
The guarantees retained here are narrower:
|
||||
|
||||
```text
|
||||
Var localId
|
||||
Forall binders body
|
||||
Exists binders body
|
||||
```
|
||||
- View and typed-program envelopes are structurally well formed.
|
||||
- Declared monomorphic Views flow consistently across explicit typed nodes.
|
||||
- Guarded Views execute their predicates at represented boundaries.
|
||||
- Artifact references bind metadata to particular stored objects.
|
||||
|
||||
The current durable encoding uses stable local binder IDs. For example,
|
||||
`id x@_a =@_a x` exports a shape equivalent to:
|
||||
|
||||
```text
|
||||
Forall [0] (Fn [Var 0] (Var 0))
|
||||
```
|
||||
|
||||
Source names like `_a` are for authoring; the artifact carries binder scope and
|
||||
local IDs rather than relying on source-name identity.
|
||||
|
||||
`Forall` supports generic contracts:
|
||||
|
||||
```tri
|
||||
map f@(Fn [_a] _b) xs@(List _a) =@(List _b) ...
|
||||
head xs@(NonEmptyList _a) =@_a ...
|
||||
```
|
||||
|
||||
At each checked use, the checker instantiates quantified variables into
|
||||
use-local internal variables and solves View compatibility constraints. The
|
||||
portable checker uses structural use-local IDs rather than expensive numeric
|
||||
freshening, and treats unconstrained variable-variable matches as constraints
|
||||
that do not create substitution cycles. Concrete observations still bind these
|
||||
variables when enough information is available. This is what lets explicitly
|
||||
annotated higher-order boundaries accept polymorphic values, for example
|
||||
`compose id id "x"`, and lets quantified values satisfy concrete requirements
|
||||
such as `Fn [String] String`. It gives useful polymorphic contracts for
|
||||
explicitly declared/imported View facts.
|
||||
|
||||
`Exists` supports checked abstraction boundaries. A module can expose a value as
|
||||
"some representation `_repr` plus capabilities over `_repr`":
|
||||
|
||||
```text
|
||||
Exists _repr.
|
||||
Pair
|
||||
(Fn [String] _repr) -- constructor
|
||||
(Fn [_repr] String) -- renderer / eliminator
|
||||
```
|
||||
|
||||
This does not make raw Tree Calculus inspection impossible. Unchecked code can
|
||||
always inspect trees. It means checked clients cannot justify
|
||||
representation-specific operations through the View system unless the package
|
||||
exports an appropriate capability or eliminator.
|
||||
|
||||
This leads to an important distinction for future checked subsets:
|
||||
|
||||
```text
|
||||
controlled observation: Bool/List/Maybe/Result/etc. eliminators with Views
|
||||
raw observation: direct tree-shape inspection through triage-like power
|
||||
```
|
||||
|
||||
Useful application code can live mostly in the controlled fragment and receive
|
||||
explicit View validation over lambdas, application, let, and typed eliminators.
|
||||
Low-level library code may still use raw intensionality, but should expose
|
||||
disciplined Views and capabilities above it. Scott-encoded constructors and
|
||||
eliminators are a natural tricu-native representation for these APIs.
|
||||
|
||||
Tree Calculus terms do not carry intrinsic principal Views, and raw intensional
|
||||
code can invalidate parametric claims. View Contracts are an explicit evidence
|
||||
and contract layer over tricu programs; limited polymorphic Views are supported
|
||||
when they are declared or imported as facts with provenance.
|
||||
|
||||
The first stdlib annotation island starts with parametric functions that do not
|
||||
inspect representation:
|
||||
|
||||
```tri
|
||||
id x@_a =@_a x
|
||||
const x@_a y@_b =@_a x
|
||||
compose f@(Fn [_b] _c) g@(Fn [_a] _b) x@_a =@_c f (g x)
|
||||
```
|
||||
|
||||
Re-export-only modules preserve imported View metadata, so these contracts flow
|
||||
through `prelude` rather than only through direct `base` imports.
|
||||
|
||||
Functions built on raw `t`/`triage` should enter the checked world through
|
||||
trusted, controlled eliminator contracts rather than by treating arbitrary raw
|
||||
inspection as parametric.
|
||||
These guarantees do not establish that an opaque payload has an unguarded
|
||||
structural View such as `List` or `Fn`. Such Views are conventions/assertions
|
||||
used to place and compose checks. Only an executed guard observes the value.
|
||||
|
||||
See [the intensionality analysis](../notes/view-contract-trust-provenance.md) for
|
||||
the rationale and remaining limitations.
|
||||
|
||||
## 5. Guards
|
||||
|
||||
@@ -259,81 +186,22 @@ A node may contain opaque executable fields. Those fields are tree terms, but
|
||||
they are not recursively decoded as view-tree nodes or Views unless the node's
|
||||
semantics explicitly says so.
|
||||
|
||||
View facts may also carry explicit per-fact trust provenance:
|
||||
View facts may carry per-fact provenance:
|
||||
|
||||
```text
|
||||
Checked -- derived by checked lowering / checker validation
|
||||
Trusted -- asserted by a trusted boundary, e.g. a primitive eliminator API
|
||||
Unchecked -- raw or assumed; no parametricity/abstraction guarantee
|
||||
Checked
|
||||
Trusted
|
||||
Unchecked
|
||||
```
|
||||
|
||||
In the portable view-tree envelope this provenance is represented as an optional
|
||||
field on `typedValue` / `typedRequire` facts. In module manifests the same
|
||||
provenance is carried beside the exported View Contract object reference so that
|
||||
imports and re-exports preserve it without relying on module-level convention.
|
||||
Absent provenance is interpreted conservatively as `Unchecked` at use sites.
|
||||
These labels are retained for artifact compatibility and auditing. They identify
|
||||
the source of an assertion; they do not prove semantic membership, parametricity,
|
||||
or abstraction. An absent label is interpreted conservatively as `Unchecked`.
|
||||
|
||||
For parametric checked definitions, the frontend now performs a conservative
|
||||
raw-intensionality dependency pass over local definitions. If a definition with
|
||||
scoped View variables depends directly or indirectly on raw `triage` / raw `t`
|
||||
construction, or on an imported `Unchecked` fact, lowering fails and asks the
|
||||
author to route observation through a trusted eliminator boundary. This is
|
||||
intentionally provenance/dependency based; it is not an attempt to decide
|
||||
whether arbitrary Tree Calculus reduction will ever reach rule 3.
|
||||
|
||||
View facts can be authored as ordinary value-level Tree Calculus metadata under
|
||||
one conventional top-level name:
|
||||
|
||||
```text
|
||||
viewFacts = [fact ...]
|
||||
fact = pair exportName (pair provenance view)
|
||||
```
|
||||
|
||||
where `exportName` is a string naming a value exported by the module,
|
||||
`provenance` is `0 = Checked`, `1 = Trusted`, or `2 = Unchecked`, and `view` is
|
||||
the same portable View record used by `view-tree` artifacts. The host evaluates
|
||||
this value and decodes the data schema; it does not infer trust from source
|
||||
syntax, AST shape, module name, or a Haskell-side catalog.
|
||||
|
||||
The initial trusted eliminator facts are authored this way in clearly separated
|
||||
stdlib `viewFacts` sections:
|
||||
|
||||
```text
|
||||
matchBool : forall r. r -> r -> Bool -> r
|
||||
matchMaybe : forall a r. r -> (a -> r) -> Maybe a -> r
|
||||
matchList : forall a r. r -> (a -> List a -> r) -> List a -> r
|
||||
```
|
||||
|
||||
The `base` module provides small `facts*` authoring helpers for this advanced
|
||||
metadata, e.g. `factsFact`, `factsChecked`, `factsTrusted`, `factsUnchecked`,
|
||||
`factsForall`, `factsFn`, `factsVar`, `factsBool`, `factsString`, `factsByte`,
|
||||
`factsUnit`, `factsMaybe`, and `factsList`. These helpers construct ordinary
|
||||
Tree data; authority comes from the exported `viewFacts` value and its explicit
|
||||
provenance tags. Loader validation rejects duplicate fact names and facts for
|
||||
names the module does not export.
|
||||
|
||||
Initial derived stdlib annotations using this trusted kernel include:
|
||||
|
||||
```text
|
||||
maybeMap : forall a b. (a -> b) -> Maybe a -> Maybe b
|
||||
maybeBind : forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
|
||||
maybeOr : forall a. a -> Maybe a -> a
|
||||
```
|
||||
|
||||
Recursive list combinators are currently published as explicit `Trusted`
|
||||
value-level facts rather than `Checked` source annotations, because their bodies
|
||||
pass through raw fixed-point machinery that the conservative parametric taint
|
||||
pass intentionally does not prove safe. This is the stabilized boundary: raw
|
||||
stdlib kernels establish conventions with explicit authority; ordinary checked
|
||||
clients consume those facts rather than re-proving the internals.
|
||||
|
||||
```text
|
||||
headMaybe / lastMaybe / nthMaybe
|
||||
append / map / filter / foldl / foldr
|
||||
length / reverse / snoc / count / all? / any? / intersect
|
||||
take / drop / splitAt / concatMap / find / partition / zipWith
|
||||
string/list-byte helpers such as strLength, startsWith?, lines, words
|
||||
```
|
||||
The former value-level polymorphic `viewFacts` catalogs and frontend
|
||||
raw-intensionality taint pass have been removed. Monomorphic imported facts may
|
||||
still be attached to exports, but consumers must treat them as assertions unless
|
||||
an executable guard enforces the relevant property.
|
||||
|
||||
## 7. Checker Semantics
|
||||
|
||||
|
||||
Reference in New Issue
Block a user