Revival, and a host that supplies real values (#61) - #64
Merged
Conversation
F-Val-Fate was unimplemented: `Host` carried descriptions of what a host
supplies and no values, so a `{__resource}` envelope had no class to become
and stayed an envelope in the namespace.
`Host` gains `values`, specifier to export name to the real value, and
F-Import binds a host-owned specifier's real exports per F-Host-Trust arm 1.
`revive.ts` walks a declarator's folded tree and replaces five of the six
envelopes: the resource is constructed by the class the folding file imports,
honouring F-Val-Arity's props/attributes against spread-args split; the
intrinsic is invoked in whichever form the envelope recorded; the helper is
invoked; the symbol resolves as a dotted chain. `{__attrRef}` passes through,
and is rejected inside a host call's arguments per F-Val-Position.
`{__compositeStep}` rejects, since there is no composite factory form here.
Two things fell out of getting this right.
Revival must not rebuild a structure that holds no envelope. The first
version returned a fresh object every time, which made X(g) a copy and
F-Memo's guarantee vacuous, exactly as J3 warns. It now returns the original
when every child came back identical.
F-Capture is stated over X(f), not over what f imported, and the previous
implementation recorded the edge at import time. That made every import of a
project-local function a capture, since a FoldableFunction is an object,
which defeats the parameter helper F-CallLeak exists to protect. Captures are
now decided by walking the produced namespace against an owner index, and
F-CallLeak's own edge is recorded at the call site.
Conformance fixtures name a host: `packages/conformance/src/host.ts` carries
one, with two entity classes covering both arities, an intrinsic tag, a
helper, and a live object the host owns outright for the leak case. Four
fixtures land on it, and F-CallLeak's shows a leaking call and a pure one in
the same file.
F-NoOwnExecution is asserted directly: a top-level side effect in a folded
file never runs, a side effect in a called body is rejected rather than
executed, and with no host a resource cannot revive and the file falls back
rather than silently keeping an envelope.
Coverage 51 to 57 of 126 rules.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RfnRhfdYHLFAZJKHwZhBYc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #61.
F-Val-Fatewas unimplemented.Hostcarried descriptions of what a host supplies and no values, so a{__resource}envelope had no class to become and stayed an envelope in the namespace.What landed
Host.values: specifier to export name to the real value.F-Importbinds a host-owned specifier's real exports, which isF-Host-Trustarm 1 and what makes revival possible at all.revive.ts, fromvalues.md. Five of the six envelopes: resource construction honouringF-Val-Arity, intrinsic invocation in both forms, helper invocation, dotted-chain symbol resolution.{__attrRef}passes through, and is rejected inside a host call's arguments perF-Val-Position.{__compositeStep}rejects — there is no composite factory form here, recorded inCAVEATS.md.packages/conformance/src/host.ts: one named host, with two entity classes covering both arities, an intrinsic tag, a helper, and a live object the host owns outright. Fixtures name the host they need with a"host"key.F-Val-Fate,F-Val-Arity,F-CallLeak,F-Val-Live. Coverage 51 to 57 of 126.Two bugs this found in what already shipped
Revival was rebuilding plain structures. The first version returned a fresh object every time, so
X(g)became a copy andF-Memo's guarantee went vacuous — precisely the failure J3 warns about, "F-Capture would record an edge to a copy, and the judgment would be vacuous". It now returns the original when every child came back identical, and the backward-taint fixture is what caught it.F-Captureis stated overX(f), not over whatfimported, and #60's implementation recorded the edge at import time. That made every import of a project-local function a capture, since aFoldableFunctionis an object — which defeats the parameter helperF-CallLeakexists to protect. Captures are now decided by walking the produced namespace against an owner index;F-CallLeak's own edge is still recorded at the call site, since the object it leaks was never in the definer's namespace.F-NoOwnExecution, asserted
Three cases in
packages/reference/src/no-own-execution.test.ts: a top-level side effect in a folded file never runs, a side effect in a called body is rejected rather than executed, and with no host a resource cannot revive so the file falls back rather than silently keeping an envelope in its namespace.🤖 Generated with Claude Code
https://claude.ai/code/session_01RfnRhfdYHLFAZJKHwZhBYc