Repository navigation
client: programs run on the coeval kernel (coeval D13, roadmap item M14) - #134
Open
mark1russell7 wants to merge 2 commits into
Open
mark1russell7 wants to merge 2 commits into
mark1russell7 wants to merge 2 commits into
Conversation
A program becomes a run document of @mark1russell7/coeval (0.3.1), and one run of the kernel runs it. The program format and its rules do not change. - program.ts: the world of a program (an open world: each procedure path is a call; the control-flow kinds with the names that they bind), the desugarer from the $proc form to a run document (implicit chains, $when, $literal and the limits decide its shape), the runners of the kinds and the boundary. Each call is an effect that the host does with client.call(), so invokeProcedure() stays the authority for admission, validation, interceptors and exposure. A failed call throws the error of the host (the cause of the #CALC! value), with its message and its code. - client.exec(), execStream(), hydrateInput(), prepareRootCall(), executeRef() and the body of a defined procedure run on the kernel. The interpreter of ref.ts (hydrateValue, hydrateRef) is gone. - The control-flow procedures keep their registrations and schemas. Their logic is a runner of the kernel: a sequence that binds the step names and last, the parts at the same time with concurrency and failFast, map and reduce with the names of the item, tryCatch with error. - envelope.ts reads envelopes with the helpers of coeval (isTypeRef, typePath, ref). The literal kind is lit (coeval D12). - compiler: the name rules (unknown-name, use-before-definition) run through check() of the coeval static kit on the run document (nameDiagnostics); resolveScopes() gives the same diagnostics. - PROGRAM-FORMAT.md revision 2: section 13, programs on the kernel. The client suite, the compiler suite (with the property tests that compare the compiled closure with the interpreter) and client-dag stay green. New tests show that a program runs through prepare/run of coeval and that check() finds the names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A step of client.chain that is data is a literal document, so the sequential names of the kernel count it: $last in the step after it reads it (the site analysis found the difference; a compiler test covers it). - The desugarer makes pointers only for a check, skips the objects of primitive items, keeps the normalized call in the origin, and sets a property with an assignment (an own property only for __proto__). - rawInputRule() gives one rule for each registry, so the machine of a run comes from a cache. - compiler: the property tests of equivalence.test.ts get 30 s each. They run hundreds of programs three ways, and the names pass and the kernel run take more time on the runners of CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Programs of the client now run on the kernel of coeval (
@mark1russell7/coeval0.3.1, decision D13). The program format and its rules do not change: the existing suites define the semantics, and they stay green.What changed
One machine, one run.
packages/client/src/procedures/program.tsholds what is the program format's own:WORLD.OPEN): each procedure path is a call kind (effects: "type",deepparts). The control-flow kinds declare the names that they bind (scope rules), socheck()knows them:client.chainbinds the step names andlast(sequential),client.mapbindsitem/asandindex,client.reducebindsacc,itemandindex, andclient.tryCatchbindserror. Internal kinds:lit,ref,program.data,program.record,program.deferred,program.fail.desugarProgram()/desugarInput()change the$procform into a run document. The rules of hydration decide its shape: implicit chains,$when,$literal, the depth limit, the data depth and cycles (a lazyprogram.fail, so an error comes where the run reaches it, with the same message). The envelope form goes throughfromEnvelopeProgram()first, so the two forms share one path.performis the client's own invocation path (execInternal/ctx.client.call), soinvokeProcedure()stays THE authority for admission, validation, interceptors, effects/clearance/deadline capabilities and exposure rules. Kernel capabilities permit every call (Machine.permits): direct HTTP/MCP calls skip the kernel and get the same admission. A failed call becomes#CALC!with the error ascause; the run rethrows the cause, soInvocationErrorcodes and the normative messages of PROGRAM-FORMAT.md come out unchanged.Callers on the kernel.
client.exec()/execStream()(one run whose root document is the root call; a stream root returns its iterable through the run),hydrateInput(),prepareRootCall(),executeRef(), the body of a defined procedure (runProgram()with the scopeinput) andclient.eval(runOperand()). The interpreter ofref.ts(hydrateValue,hydrateRef, the scope plumbing) is gone;ref.tskeeps the format (types, builders, JSON helpers, the scope carrier of a raw input, the raw-input rules). Exported names that other packages use (hydrateInput,prepareRootCall,executeRef,observeHydration,withScope,scopeOf,RefScope) keep their signatures.Control flow.
client.chain,parallel,conditional,and,or,map,reduceandtryCatchkeep their registrations and schemas (MCP tools). Each handler gives its raw input to the kernel as a document of its kind (runControl(), an own entry names the runner).client.parallelusesall()of the kernel withconcurrencyandfailFast.Envelope helpers.
envelope.tsreads envelopes with coeval'sisTypeRef,typePath,refandENVELOPE_KEYSinstead of copied checks. The literal kind islit(coeval D12; PR #133'sliteralwas unreleased).Compiler (phase B). The name rules (
unknown-name,use-before-definition, the info for a deferred input) run throughcheck()of the coeval static kit on the expanded run document (nameDiagnostics()), with Issue → Diagnostic mapping by the origin pointer of eachrefdocument (RFC 6901).scopes.tskeeps only the binding resolution that code generation needs, and the warnings for the raw input ofruns-refsprocedures.resolveScopes()gives the same diagnostics as before.Kernel additions (coeval PR mark1russell7/coeval#6, released as 0.3.1)
WORLD.OPEN:World.fallback, so any procedure path is a call kind.RUN.FAIL-FAST:all(parts, { failFast }).EVAL.FILL:fill(items)on the inputs of evaluators and runners, fordeepkinds.Behavior notes
failFast, the other tasks ofclient.parallel(and the refs ofHydrateOptions.parallel) stop at their next wait; before, they went on in the background. A call that started goes on in its procedure. Recorded in Appendix A of PROGRAM-FORMAT.md.pnpm-workspace.yaml:@mark1russell7/coeval@0.3.1inminimumReleaseAgeExclude(published today).Performance
The kernel compiles a run document for each run (
prepare) and evaluates it with generators. For programs of trivial procedures, the interpreter is slower: about 120 ms against 45 ms for 500 random programs of the compiler's property tests (local, warm). A real procedure call (validation, interceptors, I/O) dominates in practice. The second commit removes the cheap overheads (pointers only for a check, a machine cache per registry rule, no wrapper objects for primitive items). The heavy property tests ofcompiler/src/equivalence.test.tsget 30 s each, because CI runners vary and the check now also runs the names pass. A follow-up for the kernel: plan caching or a cheaper compile for documents that a loop runs again (client.mapover a control-flowfn).Versions
One changeset:
@procedures/clientand@procedures/compiler, patch (fixed group). SemVer: PATCH — before 1.0.0 a feature or a fix raises PATCH; the public API only grows (new exportsrunProgram,runDocument,runControl,runOperand,programMachine,PROGRAM_WORLD,desugarProgram,desugarInput,desugarControlValue,originOf,documentAt,namesOfScope,scopeOfNames,nameKey,nameOfKey; compilernameDiagnostics,bindScopes), and the semantics of programs stay. API snapshot updated on purpose.Tests
program.test.ts(a program is oneprepare/runof coeval; control flow runs with the runner of its kind; effects carry their places; errors keep their code;check()finds unbound names and later-step reads and knows the names of map/reduce/tryCatch/body) andcompiler/src/names.test.ts.typecheck-testsfor client and compiler,lint:ste(0 errors).🤖 Generated with Claude Code