---
title: "Branch · Interpreter Constructs Analysis"
description: "Branch · Interpreter Constructs Analysis - URL: https://chatgpt.com/c/6a5e1c8b-779c-83ea-80ab-cf68e7cb8e00 - Created: 2026-07-20T13:03:08.643Z --- Study https://github.com/go-go-golems/tiny-idp/tre…"
doc_version: 1
last_updated: 2026-10-17
canonical_url: "http://parc.yolo.scapegoat.dev/note/transcripts/2026/07/21/chatgpt-transcript-branch-interpreter-constructs-analysis-v1-tiny-idp-goja"
---

# Branch · Interpreter Constructs Analysis

Branch · Interpreter Constructs Analysis - URL: https://chatgpt.com/c/6a5e1c8b-779c-83ea-80ab-cf68e7cb8e00 - Created: 2026-07-20T13:03:08.643Z --- > Study https://github.com/go-go-golems/tiny-idp/tre…

## Content

The Markdown source is unavailable; this fallback is derived from the rendered note HTML.

```html
<h1 id="branch--interpreter-constructs-analysis">Branch · Interpreter Constructs Analysis</h1>
<ul>
<li>URL: <a href="https://chatgpt.com/c/6a5e1c8b-779c-83ea-80ab-cf68e7cb8e00">https://chatgpt.com/c/6a5e1c8b-779c-83ea-80ab-cf68e7cb8e00</a></li>
<li>Created: 2026-07-20T13:03:08.643Z</li>
</ul>
<hr />
<blockquote>
<p>Study <a href="https://github.com/go-go-golems/tiny-idp/tree/task/prod-tiny-idp">https://github.com/go-go-golems/tiny-idp/tree/task/prod-tiny-idp</a> and write a textbook / report / analysis about all the interesting interpreter and goja constructs introduced to properly implement this, things like serialized continuations and invocation capabilities and deterministic callback registration and many more. There is a lot of interesting novel / rigorous interpreter work in there in say pkg/idp script and workflow and such , work done as part of ttmp TINYIDP-GOJA-001 .</p>
</blockquote>
<details><summary>💭 Thinking</summary>
<p><strong>Evaluating project scope</strong></p>
<p>I’m considering how to respond to a task involving a GitHub repo. The user likely wants a detailed report or analysis, possibly in markdown or PDF. I’ll clarify their preferred format.</p>
<p><strong>Evaluated project scope</strong></p>
</details>
<p>I’ll trace the branch architecture, commit history, and TINYIDP-GOJA-001 changes across <code>pkg/idp</code>, then produce a structured technical report emphasizing concrete code references and invariants.</p>
<details><summary>💭 Thinking</summary>
<p><strong>Retrieved GitHub repository metadata and fetched README file</strong></p>
</details>
<pre><code class="language-unknown">bash -lc rm -rf /mnt/data/tiny-idp &amp;&amp; git clone --branch task/prod-tiny-idp --single-branch https://github.com/go-go-golems/tiny-idp.git /mnt/data/tiny-idp &amp;&amp; git -C /mnt/data/tiny-idp rev-parse HEAD &amp;&amp; git -C /mnt/data/tiny-idp status --short
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Cloned branch and fetched updates</strong></p>
</details>
<pre><code class="language-json">{&quot;open&quot;:[{&quot;ref_id&quot;:&quot;https://api.github.com/repos/go-go-golems/tiny-idp/git/trees/task/prod-tiny-idp?recursive=1&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched the web</strong></p>
<p><strong>Searched GitHub repo for specific ticket content</strong></p>
<p><strong>Researching GitHub files</strong></p>
<p>I’m exploring how to dig deeper into a project by examining files, likely from a Git branch. I’ll gather details, focusing on specific package scripts and documentation or design analysis.</p>
<p><strong>Researched GitHub files</strong></p>
<p><strong>Searched files for package declarations and fetched design documents</strong></p>
<p><strong>Searched for package references, classes, and functions in repository</strong></p>
</details>
<p>The branch reveals a lambda-first workflow machine: Goja-free serialized IR uses stable callback IDs, while browser waits persist versioned continuations that resume fresh, capability-bounded invocations.</p>
<details><summary>💭 Thinking</summary>
<p><strong>Fetched commit metadata, diffs, and related file content</strong></p>
<p><strong>Evaluated Goja interpreter architecture and searched recent commits</strong></p>
<p><strong>Organizing file citation</strong></p>
<p>I’m planning to fetch and organize files from GitHub, keeping track of line numbers for proper citations. I'll create a markdown report, using permanent links for sources and commit references.</p>
<p><strong>Organized file citation</strong></p>
<p><strong>Fetched file content and calculated line count</strong></p>
<p><strong>Fetched and validated files and code from repository</strong></p>
<p><strong>Fetched value.go, providers.go, and diagnostics.go files</strong></p>
<p><strong>Fetched file and module content, built workflow components</strong></p>
<p><strong>Fetched compiler and runtime factory file content from repository</strong></p>
<p><strong>Fetched and analyzed files and capabilities for settlement tracking</strong></p>
<p><strong>Fetched continuation types and file content from repository</strong></p>
<p><strong>Preparing report on TINYIDP</strong></p>
<p>I’m synthesizing findings from GitHub, focusing on constructs like serialized continuations, invocation capabilities, and callback registration. The report will include precise file citations and reflect the clinical tone required.</p>
<p><strong>Preparing tiny-idp monograph</strong></p>
<p>I’m planning to write a detailed Markdown monograph analyzing TINYIDP's interpreter constructs, callback registration, and continuations. I’ll focus on code references and keep citations accurate, considering PDF output later.</p>
<p><strong>Prepared report and monograph on TINYIDP</strong></p>
<p><strong>Fetched files and content from GitHub for analysis and submission</strong></p>
<p><strong>Fetched file content from GitHub repository</strong></p>
<p><strong>Fetched and inspected repository files for implementation details</strong></p>
<p><strong>Fetched and evaluated GitHub files for advanced Goja analysis</strong></p>
</details>
<pre><code class="language-unknown">bash -lc cat /home/oai/skills/pdfs/SKILL.md
</code></pre>
<p>The key enforcement pattern is now clear: deterministic registration is checked across isolated runtimes, while opaque JavaScript executes within declared schemas, budgets, capabilities, outcomes, and native-committed effects.</p>
<details><summary>💭 Thinking</summary>
<p><strong>Read skill from PDF and checked required installations</strong></p>
<p><strong>Fetched commit metadata and inspected go.mod for version</strong></p>
</details>
<pre><code class="language-unknown">bash -lc cat &gt; /mnt/data/tiny-idp-goja-interpreter-monograph.md &lt;&lt;'EOF'
---
title: &quot;Interpreting Identity Safely&quot;
subtitle: &quot;A Technical Monograph on Tiny-IDP's Goja Microkernel, Explicit Continuations, Invocation Capabilities, and Assurance-Oriented Runtime&quot;
author: &quot;Source analysis prepared from TINYIDP-GOJA-001&quot;
date: &quot;2026-07-20&quot;
lang: en-US
---

# Scope and source snapshot

This report studies the `task/prod-tiny-idp` branch of `go-go-golems/tiny-idp` at commit [`d164ae59408bdd8bc21516274b446339b1761b1e`](https://github.com/go-go-golems/tiny-idp/commit/d164ae59408bdd8bc21516274b446339b1761b1e), dated 2026-07-20. The principal implementation and design sources are:

- the active lambda-first design, [`design-doc/03-lambda-first-tiny-idp-javascript-api-with-explicit-browser-continuations.md`](https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/design-doc/03-lambda-first-tiny-idp-javascript-api-with-explicit-browser-continuations.md);
- the assurance-oriented synthesis, [`design-doc/02-assurance-oriented-core-grammar-and-codebase-refactoring-proposal.md`](https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/design-doc/02-assurance-oriented-core-grammar-and-codebase-refactoring-proposal.md);
- the implementation ledger and status record in [`tasks.md`](https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/tasks.md) and [`changelog.md`](https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/changelog.md);
- the runtime-independent contract in [`pkg/idpprogram`](https://github.com/go-go-golems/tiny-idp/tree/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram);
- the Goja compiler, runtime, capability bridge, and worker pool in [`pkg/idpscript`](https://github.com/go-go-golems/tiny-idp/tree/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript);
- the native Goja module in [`internal/gojamodules/tinyidp`](https://github.com/go-go-golems/tiny-idp/tree/d164ae59408bdd8bc21516274b446339b1761b1e/internal/gojamodules/tinyidp);
- durable workflow state in [`pkg/idpcontinuation`](https://github.com/go-go-golems/tiny-idp/tree/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpcontinuation);
- typed browser projection and request-scoped secret handling in [`pkg/idpworkflow`](https://github.com/go-go-golems/tiny-idp/tree/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpworkflow);
- the production signup integration in [`pkg/idpsignup`](https://github.com/go-go-golems/tiny-idp/tree/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpsignup) and [`internal/fositeadapter/scripted_signup.go`](https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/internal/fositeadapter/scripted_signup.go);
- typed policy/provider adapters, native challenge evidence, verification plans, and the assurance vocabulary.

The analysis is source-based. The repository's own ticket records extensive unit, race, conformance, and integration test runs. Those records are described where relevant, but this report does not present them as independently re-executed results.

The word *novel* is used here in the engineering sense: an unusual and rigorous synthesis within this codebase. It is not a claim of academic priority.

# Executive synthesis

The significant achievement is not that Tiny-IDP embeds JavaScript. The significant achievement is that it refuses to make JavaScript the identity provider.

The branch implements a staged interpreter architecture in which JavaScript is allowed to author and execute narrowly typed policy fragments, while Go retains protocol authority, persistence authority, secret authority, HTTP authority, and atomic commit authority. The result is best understood as four related machines:

1. **A definition-time compiler.** Trusted JavaScript registers named lambdas and serializable workflow/provider contracts. It produces a pure-Go intermediate representation plus a VM-local callback registry.
2. **An activation verifier.** The same compiled source is materialized in independent owned runtimes. Program, schema, and callback fingerprints must agree before workers are accepted.
3. **A request-time lambda interpreter.** A worker receives a frozen, JSON-derived input object and only the capabilities declared by the selected lambda. It may perform bounded in-request asynchronous work and must return one member of a closed outcome algebra.
4. **A durable native workflow interpreter.** Browser-spanning control flow is not a suspended Promise or Goja heap. It is an explicit, versioned continuation record containing a handler label, typed public carry, exact generation identity, replay revision, and native references. Go validates and advances that record, renders pages, verifies challenges, and commits effects.

The architecture can be summarized as follows:

```text
                 definition time
 trusted JS  --------------------------&gt;  pure Program IR
     |                                          |
     | VM-local closures                       | canonical validation
     v                                          v
 callback registry  &lt;---- fingerprint ----  activation identity
     |
     | one exclusive owned runtime
     v
 frozen invocation context + declared capabilities
     |
     | sync result or bounded Promise
     v
 closed Outcome algebra
     |
     +--&gt; present/challenge --&gt; durable continuation record
     |
     +--&gt; commit -----------&gt; native effect validator + atomic transaction
     |
     +--&gt; complete/deny/etc -&gt; native protocol orchestration
</code></pre>
<p>Several interpreter ideas reinforce each other:</p>
<ul>
<li><strong>Defunctionalization.</strong> Durable continuations are represented by stable handler IDs and a schema-checked environment instead of serializing closures or stacks.</li>
<li><strong>A runtime type-and-effect discipline.</strong> Each lambda declares input and output schemas, allowed outcomes, required capabilities, permitted effects, timeout, call budget, and output budget.</li>
<li><strong>Nominal branding in an untyped language.</strong> Blank Goja objects are recognized by object identity in Go maps, making lambda, field, action, and secret handles unforgeable inside the VM.</li>
<li><strong>Object-capability style authority.</strong> A capability exists only because the host inserted it into one invocation, and it becomes inactive when the invocation ends.</li>
<li><strong>Algebraic-effect style commits.</strong> JavaScript returns inert effect plans. Native Go code validates the exact sequence and applies the effects in a named atomic operation.</li>
<li><strong>Fail-stop worker leasing.</strong> A runtime is returned to the pool only after a fully valid result and complete asynchronous settlement. Timeout, cancellation, exception, malformed output, or uncertain interruption causes disposal and replacement.</li>
<li><strong>Generation-aware resumption.</strong> A continuation is pinned to executable source plus semantic program identity. Hot reload creates a new generation rather than reinterpreting old state under new code.</li>
<li><strong>Separate production and verification languages.</strong> Production lambdas receive bounded policy capabilities. Verification JavaScript can only compile data-only scenarios, which are materialized against an explicit native step registry before execution.</li>
</ul>
<p>This is a practical answer to a difficult question: how can an identity system gain expressive scripting without turning protocol correctness into a property of arbitrary script behavior?</p>
<h1 id="part-i---the-interpreter-problem">Part I - The interpreter problem</h1>
<h2 id="1-why-identity-scripting-is-unusually-dangerous">1. Why identity scripting is unusually dangerous</h2>
<p>A general embedded language normally seeks convenience: expose services, let scripts call them, and translate values. In an identity provider, that approach collapses several distinct authorities into one dynamic layer:</p>
<ul>
<li>protocol validation and OAuth/OIDC state transitions;</li>
<li>browser request parsing, CSRF and origin handling, cookies, redirects, and response writing;</li>
<li>password, one-time-code, invitation, and signing-key handling;</li>
<li>transaction boundaries and one-time consumption;</li>
<li>account, credential, session, consent, and token issuance;</li>
<li>policy selection and presentation customization.</li>
</ul>
<p>If all of those become ordinary methods on a script-visible host object, the scripting API becomes an alternate identity provider. Every script path must then preserve every protocol and storage invariant. Static review becomes difficult because authority is ambient, data types are open, and errors can accidentally change security meaning.</p>
<p>The active design takes the opposite route. JavaScript may choose among host-defined operations and return host-defined values, but it cannot own the transition that makes an identity assertion true. The design document explicitly excludes Fosite objects, stores, SQL transactions, keys, cookies, passwords, raw codes, and network clients from the script surface. See the design's authority table and core execution model in <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/design-doc/03-lambda-first-tiny-idp-javascript-api-with-explicit-browser-continuations.md#L300-L531"><code>design-doc/03</code>, sections 4-6</a>.</p>
<p>The central security move is therefore architectural rather than syntactic:</p>
<blockquote>
<p>Script expressiveness is permitted only inside a native envelope whose inputs, outputs, capabilities, effects, time, size, lifetime, and continuation points are explicit.</p>
</blockquote>
<h2 id="2-four-stages-not-one-interpreter">2. Four stages, not one interpreter</h2>
<p>It is tempting to describe the system as &quot;Go executes JavaScript callbacks.&quot; That misses most of the design. There are four different stages with different state and authority.</p>
<h3 id="21-stage-a-definition-time-evaluation">2.1 Stage A: definition-time evaluation</h3>
<p>The top level of a source file executes in an isolated Goja runtime. It calls <code>require(&quot;tinyidp&quot;).v1</code>, constructs named lambdas, registers workflows/providers/tests, and exports the value returned by <code>A.program(...)</code>.</p>
<p>At this stage:</p>
<ul>
<li>Goja functions exist, but only inside the runtime's collector;</li>
<li>the exported contract is data-only;</li>
<li>no request, store, network, provider, or protocol object is present;</li>
<li>source size and definition time are bounded;</li>
<li>ambient module loading is disabled.</li>
</ul>
<h3 id="22-stage-b-activation-materialization">2.2 Stage B: activation materialization</h3>
<p>A compiled <code>*goja.Program</code> is loaded into multiple independent owned runtimes. Each runtime reconstructs the program and callback registry. The host compares canonical program data and fingerprints. If one materialization differs, activation fails.</p>
<p>This stage is a form of reproducible linking: named callback references in the IR must resolve to the same VM-local registry in every worker.</p>
<h3 id="23-stage-c-request-time-invocation">2.3 Stage C: request-time invocation</h3>
<p>For one handler invocation, the host:</p>
<ul>
<li>validates the JSON input against the handler's schema;</li>
<li>leases one runtime exclusively;</li>
<li>installs only the handler's declared capability bindings;</li>
<li>creates request-scoped secret and evidence handles;</li>
<li>builds and freezes a plain JavaScript context;</li>
<li>invokes the named closure on the runtime owner;</li>
<li>awaits a bounded Promise if returned;</li>
<li>validates the resulting outcome;</li>
<li>releases or destroys the worker.</li>
</ul>
<h3 id="24-stage-d-native-transition-interpretation">2.4 Stage D: native transition interpretation</h3>
<p>The JavaScript outcome is not the final protocol action. Go interprets it:</p>
<ul>
<li><code>present</code> becomes a validated native page plus a durable continuation;</li>
<li><code>challenge</code> becomes a native challenge record and delivery operation;</li>
<li><code>commit</code> becomes a revalidated effect sequence and atomic transaction;</li>
<li><code>complete</code>, <code>deny</code>, <code>skip</code>, and <code>error</code> are normalized by the relevant native provider or protocol seam.</li>
</ul>
<p>This fourth stage is what preserves the identity microkernel. The script proposes; the native transition commits.</p>
<h2 id="3-the-semantic-firewall-pkgidpprogram">3. The semantic firewall: <code>pkg/idpprogram</code></h2>
<p>The first hard boundary is a package with no Goja dependency. <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/program.go#L1-L57"><code>pkg/idpprogram/program.go</code></a> defines a serializable <code>Program</code> containing workflows, providers, lambda specifications, schemas, capability descriptors, and tests. A lambda specification stores a callback ID, never a function.</p>
<p>This package is more than a DTO collection. It is the semantic firewall between two worlds:</p>
<pre><code class="language-text">Goja world                              durable/native world
----------                              --------------------
closures                                callback IDs
objects with identity                   stable string IDs
Promises                                outcome records
host functions                          capability requirements
mutable JS state                        canonical JSON
runtime-local values                    pure Go values
</code></pre>
<p>The separation creates three useful proof obligations:</p>
<ol>
<li><strong>Closure locality:</strong> no Goja value can enter a <code>Program</code> or continuation.</li>
<li><strong>Reference totality:</strong> every callback ID in the IR must be present in each runtime's registry.</li>
<li><strong>Interpretation closure:</strong> every possible handler result belongs to a finite native outcome family.</li>
</ol>
<h1 id="part-ii---definition-time-language-and-activation">Part II - Definition-time language and activation</h1>
<h2 id="4-a-runtime-type-and-effect-system">4. A runtime type-and-effect system</h2>
<p><a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/lambda.go#L20-L39"><code>LambdaSpec</code></a> assigns each callback a contract:</p>
<pre><code class="language-text">LambdaSpec =
  callback identity
  + lambda kind
  + input schema
  + output schema
  + allowed outcome set
  + required capability set
  + allowed effect set
  + timeout
  + maximum capability calls
  + maximum output bytes
</code></pre>
<p>This resembles a dynamic type-and-effect system.</p>
<ul>
<li>The input and output schemas are value types.</li>
<li><code>AllowedOutcomes</code> is a row of legal control effects.</li>
<li><code>RequiredCapabilities</code> is the authority context.</li>
<li><code>AllowedEffects</code> is the commit-effect context.</li>
<li><code>Budget</code> is a resource effect bound.</li>
</ul>
<p>The contract is enforced twice. <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/validate.go#L30-L258"><code>idpprogram.Validate</code></a> checks it before activation. <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/codec.go#L15-L38"><code>pkg/idpscript/codec.go</code></a> checks actual inputs and outputs at invocation.</p>
<p>A useful way to read a handler declaration is:</p>
<pre><code class="language-text">under capability environment C,
within resource budget B,
this callback maps values of schema I
into one of outcome kinds O,
whose value conforms to schema R,
and whose commit plan may contain effects E.
</code></pre>
<p>That is far more reviewable than a generic <code>func(ctx map[string]any) any</code>.</p>
<h2 id="5-closed-schemas-and-information-flow-labels">5. Closed schemas and information-flow labels</h2>
<p><a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/schema.go#L5-L46"><code>pkg/idpprogram/schema.go</code></a> defines a deliberately small schema language: object, string, boolean, integer, and bytes, with byte and length bounds. Object fields refer to named schemas. The validator rejects cycles and missing references.</p>
<p>Two design choices matter.</p>
<p>First, object schemas are closed by default. <code>Additional: false</code> makes unknown fields an error. This prevents a browser form, capability result, or script result from smuggling data into a handler that never declared it.</p>
<p>Second, fields carry a <code>Sensitive</code> marker. <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/value.go#L41-L65"><code>ValidatePublicJSON</code></a> traverses a value under the destination schema and rejects sensitive fields. The same schema therefore serves two related purposes:</p>
<ul>
<li>structural typing for an ephemeral invocation; and</li>
<li>an information-flow policy for durable public carry.</li>
</ul>
<p>The continuation environment is not merely JSON that happens not to contain a password. It is JSON proven against a schema path that forbids sensitive fields.</p>
<h2 id="6-the-outcome-algebra">6. The outcome algebra</h2>
<p><a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/outcomes.go#L11-L117"><code>pkg/idpprogram/outcomes.go</code></a> defines a closed sum type:</p>
<ul>
<li><code>continue</code> - immediate native dispatch to another handler;</li>
<li><code>present</code> - native UI plus a durable continuation;</li>
<li><code>challenge</code> - native proof mechanism plus a durable continuation;</li>
<li><code>commit</code> - inert effect plan for native validation and transaction;</li>
<li><code>complete</code> - terminal typed value;</li>
<li><code>deny</code> - valid negative policy result;</li>
<li><code>skip</code> - explicitly inapplicable provider/branch;</li>
<li><code>error</code> - infrastructure or internal failure.</li>
</ul>
<p>The distinctions are security-relevant. A thrown exception is not a denial. <code>undefined</code> is not a skip. A rejected credential is not an invitation to silently try a weaker factor. The design document calls out this semantic discipline directly in <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/design-doc/03-lambda-first-tiny-idp-javascript-api-with-explicit-browser-continuations.md#L389-L407"><code>design-doc/03</code></a>.</p>
<p>This is algebraic in the practical sense: the host performs exhaustive interpretation over a finite family. A new security-significant result requires a native enum, validation rule, interpreter branch, tests, and usually an effect or provider contract. It cannot arrive as an accidental JavaScript object shape.</p>
<h2 id="7-static-workflow-validation-as-finite-state-analysis">7. Static workflow validation as finite-state analysis</h2>
<p>A workflow is a map of handler IDs plus explicit continuation edges. The validator performs more than reference checking:</p>
<ul>
<li>handler and lambda IDs must agree;</li>
<li>entry handlers must exist;</li>
<li>every edge must name a legal source outcome;</li>
<li>edge input schemas must agree with destination lambda schemas;</li>
<li>all handlers must be reachable from the entry;</li>
<li>schemas must be acyclic;</li>
<li>capabilities and effects must be declared and versioned;</li>
<li>providers must declare coherent state, replay, and revocation semantics;</li>
<li>tests must target existing lambdas and legal expected outcomes.</li>
</ul>
<p>The reachability walk is deterministic because map keys are sorted before traversal. Diagnostics are also sorted by path, diagnostic ID, and message in <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/diagnostics.go#L7-L47"><code>diagnostics.go</code></a>. Deterministic diagnostics matter operationally: activation systems and CI should not produce order-dependent output from Go map iteration.</p>
<p>The resulting <code>Program</code> is a finite, statically reviewable transition graph even though handler bodies remain dynamic. Static analysis can prove where control may resume and which effect families may be requested without interpreting arbitrary callback code.</p>
<h2 id="8-the-native-module-as-a-nominal-type-system">8. The native module as a nominal type system</h2>
<p>The native module in <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/internal/gojamodules/tinyidp/module.go"><code>internal/gojamodules/tinyidp/module.go</code></a> uses a particularly effective Goja technique: blank object handles branded by VM object identity.</p>
<p>When <code>A.lambda(id, spec)</code> is called, the loader:</p>
<ol>
<li>validates the arguments;</li>
<li>extracts the callback as a <code>goja.Callable</code>;</li>
<li>records the callable in the collector under the stable ID;</li>
<li>creates a blank JavaScript object;</li>
<li>stores <code>collector.lambdas[object] = id</code>;</li>
<li>returns the blank object to JavaScript.</li>
</ol>
<p>Workflow registration accepts only an object present in that identity map. An attacker cannot forge a lambda by constructing <code>{id: &quot;signup.start&quot;}</code> because properties are irrelevant. The nominal brand is the <code>*goja.Object</code> pointer known to Go.</p>
<p>The same mechanism is used for:</p>
<ul>
<li>host-defined field descriptors;</li>
<li>host-defined action descriptors;</li>
<li>invocation-scoped secret handles.</li>
</ul>
<p>This gives an untyped language several nominal types without exposing a forgeable tag or a private symbol. It also makes misuse errors local and precise: a presentation field must be the exact object returned by the module, not an object with similar data.</p>
<h3 id="81-why-blank-objects-are-stronger-than-frozen-tagged-objects">8.1 Why blank objects are stronger than frozen tagged objects</h3>
<p>A frozen tagged object such as <code>{kind: &quot;lambda&quot;, id: &quot;x&quot;}</code> is immutable but forgeable. A JavaScript <code>Symbol</code> narrows accidental collisions but can still be copied if exposed. A Go-side identity table gives the host an unforgeable membership test for the lifetime of the runtime.</p>
<p>The pattern can be stated generally:</p>
<pre><code class="language-text">brand(v, T)  := hostMap[T].contains(objectIdentity(v))
</code></pre>
<p>It is a useful bridge pattern whenever an embedded language needs opaque, nominal references to host-approved declarations.</p>
<h2 id="9-a-closed-commonjs-world">9. A closed CommonJS world</h2>
<p><a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/runtime_factory.go#L40-L50"><code>NewRuntimeFactory</code></a> disables implicit default modules, data-only default modules, and the ambient loader. The only registered native module is <code>tinyidp</code>.</p>
<p>Negative tests attempt to load filesystem, process, execution, database, network, OS, and arbitrary project modules. See <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/invoke_test.go#L271-L290"><code>pkg/idpscript/invoke_test.go</code></a>.</p>
<p>This is a closed-world language profile:</p>
<pre><code class="language-text">JavaScript syntax and standard built-ins
+ require(&quot;tinyidp&quot;)
- filesystem
- process
- OS
- network
- database
- project module loader
</code></pre>
<p>The design correctly describes this as authority reduction, not a claim that hostile code is safely sandboxed in-process. The scripts are operator-trusted. The runtime profile constrains accidental and exploit-oriented authority but does not replace process isolation for adversarial code.</p>
<h2 id="10-deterministic-callback-registration">10. Deterministic callback registration</h2>
<p>The core registration problem is subtle. A serializable program can contain the ID <code>signup.submitted</code>, but the executable closure exists only inside a specific Goja runtime. A worker pool therefore needs a reproducible linking rule:</p>
<pre><code class="language-text">Program callback ID  &lt;-&gt;  exact closure registered in this runtime
</code></pre>
<p>Tiny-IDP solves this by re-executing the same compiled source in every worker and checking several identities.</p>
<h3 id="101-canonical-identities">10.1 Canonical identities</h3>
<p><a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/canonical.go#L14-L60"><code>ComputeFingerprints</code></a> computes independent hashes for:</p>
<ul>
<li>source text;</li>
<li>canonical program IR;</li>
<li>sorted callback registry IDs;</li>
<li>canonical schema registry.</li>
</ul>
<p>The separate hashes answer different questions:</p>
<table>
<thead>
<tr>
<th>Fingerprint</th>
<th>What it detects</th>
</tr>
</thead>
<tbody>
<tr>
<td>Source</td>
<td>Any executable source change, including callback bodies</td>
</tr>
<tr>
<td>Program</td>
<td>Any semantic registration/contract change</td>
</tr>
<tr>
<td>Callback registry</td>
<td>Missing, extra, or renamed VM-local closures</td>
</tr>
<tr>
<td>Schemas</td>
<td>Host/schema drift even when callback IDs are unchanged</td>
</tr>
</tbody>
</table>
<h3 id="102-re-materialization-checks">10.2 Re-materialization checks</h3>
<p>During compilation, <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/compiler.go#L38-L78"><code>compiler.go</code></a> compiles the source, loads it into an isolated runtime, validates the resulting program, computes fingerprints, and stores an immutable artifact.</p>
<p>During worker loading, <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/runtime_factory.go#L73-L188"><code>runtime_factory.go</code></a>:</p>
<ol>
<li>creates a fresh owned runtime;</li>
<li>installs a runtime-local collector;</li>
<li>executes the compiled program under the owner;</li>
<li>JSON-encodes <code>module.exports</code>;</li>
<li>obtains the collector's program independently;</li>
<li>requires canonical equality between the two;</li>
<li>validates the program again;</li>
<li>recomputes program, callback, and schema fingerprints;</li>
<li>compares them with the artifact;</li>
<li>requires a one-to-one callback-ID/lambda-spec set.</li>
</ol>
<p>This is deterministic registration as an activation invariant, not as a coding convention.</p>
<h3 id="103-what-this-does-and-does-not-prove">10.3 What this does and does not prove</h3>
<p>It proves that definition-time observable registration is reproducible across workers. It catches a program that conditionally registers different handlers based on time, random values, or runtime-dependent state if that difference reaches the program or callback registry.</p>
<p>It does not prove that callback behavior is deterministic for every input. A callback may intentionally depend on a declared capability, and a reused runtime may retain ordinary module state. Source identity and capability scoping make such behavior reviewable, but registration equality is not full semantic equivalence.</p>
<h2 id="11-moduleexports-as-an-anti-ambiguity-check">11. <code>module.exports</code> as an anti-ambiguity check</h2>
<p>The runtime does not merely trust the collector. It also requires that <code>module.exports</code> be canonically equal to the value returned by <code>tinyidp.v1.program</code>. See <a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/runtime_factory.go#L97-L151"><code>runtime_factory.go</code>, lines 97-151</a>.</p>
<p>This prevents several ambiguous module patterns:</p>
<ul>
<li>registering one program while exporting another;</li>
<li>exporting an unrelated object after registration;</li>
<li>relying on hidden collector side effects that are not visible in the module contract;</li>
<li>accidentally omitting the program export.</li>
</ul>
<p>The program has one authoritative public representation and one authoritative private callback registry, and activation checks that they correspond.</p>
<h2 id="12-immutable-artifacts-and-defensive-copies">12. Immutable artifacts and defensive copies</h2>
<p><a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/artifact.go#L14-L62"><code>Artifact</code></a> stores:</p>
<ul>
<li>source text;</li>
<li>a compiled <code>*goja.Program</code> reusable by independent runtimes;</li>
<li>canonical program JSON;</li>
<li>fingerprints.</li>
</ul>
<p><code>Artifact.Program()</code> decodes a fresh copy from canonical JSON. <code>RuntimeImage.Program()</code> similarly produces a deep copy. This removes a common embedded-runtime hazard: a caller cannot mutate the activation contract after validation by retaining a map or slice reference.</p>
<p>The artifact is therefore a reproducible recipe for runtime images, not a live runtime itself.</p>
<p>EOF</p>
<pre><code>
&lt;details&gt;&lt;summary&gt;💭 Thinking&lt;/summary&gt;

**Created and drafted technical monograph with design details**

**Organizing textbook/report structure**

I’m working through the structure for a comprehensive textbook on TINYIDP, focusing on its unique constructs, including continuations and callback registration. I’ll cross-check citations carefully and use relevant files.

**Processing document output**

I’m working through the monograph’s structure, checking the references and formatting. I’ll adjust the DOCX and PDF output for styling, margins, and page size before finalizing and inspecting each page.

**Organized textbook/report structure and processed document output**

&lt;/details&gt;

```unknown
bash -lc sed -n '1,260p' /home/oai/skills/docx/SKILL.md &amp;&amp; printf '\n---PDF---\n' &amp;&amp; sed -n '1,320p' /home/oai/skills/pdfs/SKILL.md
</code></pre>
<p>The full textbook draft is complete and undergoing layout checks. It distinguishes registry determinism from callback-state determinism and implemented guarantees from residual assurance gaps.</p>
<details><summary>💭 Thinking</summary>
<p><strong>Read documentation, inspected content, and analyzed images for PDF creation</strong></p>
</details>
<pre><code class="language-unknown">bash -lc cp /mnt/data/_qa_docx_final/tiny-idp-goja-interpreter-monograph.pdf /mnt/data/tiny-idp-goja-interpreter-monograph.pdf
rm -rf /mnt/data/_qa_pdf_final &amp;&amp; mkdir -p /mnt/data/_qa_pdf_final
python /home/oai/skills/pdfs/scripts/render_pdf.py /mnt/data/tiny-idp-goja-interpreter-monograph.pdf --out_dir /mnt/data/_qa_pdf_final --dpi 200
pdfinfo /mnt/data/tiny-idp-goja-interpreter-monograph.pdf | sed -n '1,40p'
python /home/oai/skills/pdfs/scripts/pdf_preflight.py /mnt/data/tiny-idp-goja-interpreter-monograph.pdf || true
python /home/oai/skills/pdfs/scripts/pdf_inspect.py /mnt/data/tiny-idp-goja-interpreter-monograph.pdf | sed -n '1,180p' || true
unzip -t /mnt/data/tiny-idp-goja-interpreter-monograph.docx | tail -5
sha256sum /mnt/data/tiny-idp-goja-interpreter-monograph.md /mnt/data/tiny-idp-goja-interpreter-monograph.docx /mnt/data/tiny-idp-goja-interpreter-monograph.pdf
ls -lh /mnt/data/tiny-idp-goja-interpreter-monograph.*

</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Verified and analyzed PDF files and document details</strong></p>
</details>
<pre><code class="language-json">{&quot;paths&quot;:[&quot;GitHub&quot;],&quot;query&quot;:&quot;repository&quot;}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn8&quot;,&quot;query&quot;:&quot;pkg/idp&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn13&quot;,&quot;query&quot;:&quot;filename&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn13&quot;,&quot;start_line&quot;:1,&quot;num_lines&quot;:40}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn15&quot;,&quot;start_line&quot;:160,&quot;num_lines&quot;:220}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn15&quot;,&quot;query&quot;:&quot;Step 17&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;paths&quot;:[&quot;GitHub&quot;],&quot;query&quot;:&quot;tree&quot;}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn70&quot;,&quot;query&quot;:&quot;pkg/memorystore&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn70&quot;,&quot;query&quot;:&quot;package memorystore&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn18&quot;,&quot;start_line&quot;:1,&quot;num_lines&quot;:35}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn8&quot;,&quot;query&quot;:&quot;## 5.&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn8&quot;,&quot;start_line&quot;:300,&quot;num_lines&quot;:250}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn8&quot;,&quot;query&quot;:&quot;## 8.&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn8&quot;,&quot;query&quot;:&quot;## 9.&quot;,&quot;start_line&quot;:1}
</code></pre>
<pre><code class="language-json">{&quot;uri&quot;:&quot;/response/turn8&quot;,&quot;query&quot;:&quot;## 10.&quot;,&quot;start_line&quot;:1}
</code></pre>
<h1 id="interpreting-identity-safely">Interpreting Identity Safely</h1>
<p>A 12,390-word technical monograph, rendered as a 42-page report, is complete.</p>
<ul>
<li><a href="sandbox:/mnt/data/tiny-idp-goja-interpreter-monograph.pdf">Read the PDF</a></li>
<li><a href="sandbox:/mnt/data/tiny-idp-goja-interpreter-monograph.docx">Download the editable DOCX</a></li>
<li><a href="sandbox:/mnt/data/tiny-idp-goja-interpreter-monograph.md">View the Markdown source</a></li>
</ul>
<p>The analysis is pinned to branch commit <code>d164ae59408bdd8bc21516274b446339b1761b1e</code> from July 20, 2026. fileciteturn73file0L1-L3</p>
<h2 id="central-conclusion">Central conclusion</h2>
<p>The implementation is better understood as a <strong>collection of deliberately small interpreters around a Go identity microkernel</strong>, rather than as an application that happens to embed JavaScript.</p>
<p>The report develops that interpretation through:</p>
<ul>
<li><strong>Definition-time staging:</strong> trusted JavaScript constructs a pure, serializable <code>idpprogram.Program</code>, while Goja closures remain confined to a runtime-local callback registry. <code>pkg/idpprogram</code> intentionally has no Goja dependency and stores callback identifiers rather than functions. fileciteturn11file0L3-L20</li>
<li><strong>Deterministic callback linking:</strong> the compiled source is re-executed in independently owned runtimes, and workers are accepted only when exported program data, collected program data, callback sets, schema sets, and fingerprints agree. fileciteturn35file0L97-L179</li>
<li><strong>Invocation capabilities:</strong> each lambda receives only declared, versioned, byte-bounded and call-bounded native operations. Promise settlement is routed back through the runtime owner, and retained capability functions lose authority when the invocation ends.</li>
<li><strong>Transactional worker leasing:</strong> a runtime is reusable only after a positive safety proof—valid output, no uncertain interruption, and complete asynchronous settlement. Timeouts, exceptions, malformed results, cancellation races, and late settlements cause disposal and replacement. fileciteturn37file0L42-L176</li>
<li><strong>Serialized continuations through defunctionalization:</strong> browser waits do not serialize a Goja Promise, closure, stack, or heap. They persist a pure-Go record containing a resume-handler label, typed public environment, generation identity, revision, bindings, and native references. fileciteturn40file0L3-L84</li>
<li><strong>Nominal branding by Goja object identity:</strong> lambdas, fields, actions, and secrets are represented by blank JavaScript objects recognized through host-side identity maps, rather than forgeable object properties.</li>
<li><strong>Typed presentation and exact POST projection:</strong> scripts select host-registered UI descriptors; Go owns HTML names, normalization, sensitivity, redisplay policy, request parsing, CSRF handling, and rendering.</li>
<li><strong>Opaque, request-scoped secret capabilities:</strong> passwords are native byte buffers referenced by unforgeable Goja handles, not ordinary JavaScript strings.</li>
<li><strong>Algebraic-effect-style commits:</strong> JavaScript returns inert effect plans. Named native committers revalidate the exact effect sequence and apply identity, credential, continuation, session, invitation, and authorization changes atomically.</li>
<li><strong>Native evidence:</strong> verification codes and authoritative proof state remain native; scripts receive bounded evidence projections that they cannot manufacture themselves.</li>
<li><strong>Generation-pinned semantic time:</strong> continuations resume under the exact retained source and program generation that created them, rather than being silently reinterpreted after hot reload.</li>
<li><strong>A separate verification interpreter:</strong> test JavaScript compiles data-only scenario plans, which must be materialized through finite native step registries before execution.</li>
<li><strong>Critical evaluation:</strong> the report distinguishes implemented guarantees from remaining concerns such as persistent module state in reused workers, declared versus behavioral nondeterminism, generation-retention alignment, key rotation, mail-delivery transaction boundaries, and unfinished assurance consolidation.</li>
</ul>
<p>The active design itself draws the essential line between in-request asynchronous work and browser-spanning durable control flow: ordinary <code>await</code> remains local to one invocation, while browser waits create explicit persisted continuations and later invoke a fresh handler. fileciteturn8file0L44-L91</p>
<p>The implementation ledger records the principal lambda-first runtime phases as complete, while cross-phase assurance consolidation and the final completion gate remain open. The report preserves that distinction rather than presenting the branch as a completed formal-verification system. fileciteturn65file0L103-L116</p>
<p>The PDF is the primary reading edition. The DOCX contains a static linked table of contents, verified page numbers, embedded fonts in the PDF export, 147 outline entries, and source hyperlinks pinned to the analyzed commit. Test claims in the text are attributed to repository records; the repository test suite was not independently re-executed in this environment.</p>
<hr />
<blockquote>
<p>Research and brainstorm how having access to the goja interpreter or in fact creating our own js interpreter / compiler would influence such a design and potentially make it more usable / elegant / robust / verified / allow new software design patterns both on the implementation of the idp framework and on the side of the plugin/script writers.</p>
<p>One could also imagine making the js interpreter / compiler malleable and extensible, so that one could extend it in different ways for different projects, not just tiny-idp .</p>
<p>Write a similar doc</p>
</blockquote>
<p>I’ll map Goja’s extension boundaries, compare deeper integration, forked-Goja, compiler-front-end, and purpose-built runtime options, then derive Tiny-IDP patterns, cross-project architecture, risks, and a staged roadmap.</p>
<pre><code class="language-unknown">bash -lc set -e
cat /home/oai/skills/docx/SKILL.md
printf '\n---PDF SKILL---\n'
cat /home/oai/skills/pdfs/SKILL.md
printf '\n---REPO---\n'
if [ -d /mnt/data/tiny-idp/.git ]; then git -C /mnt/data/tiny-idp rev-parse --abbrev-ref HEAD; git -C /mnt/data/tiny-idp rev-parse HEAD; else echo 'repo missing'; fi
printf '\n---EXISTING REPORT---\n'
ls -lh /mnt/data/tiny-idp-goja-interpreter-monograph.* 2&gt;/dev/null || true
printf '\n---GOJA VERSION---\n'
if [ -f /mnt/data/tiny-idp/go.mod ]; then grep -n 'goja' /mnt/data/tiny-idp/go.mod /mnt/data/tiny-idp/go.sum | head -20; fi
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Verified repo and Goja version, cloned repositories and inspected dependencies</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:github.com/go-go-golems/tiny-idp \&quot;task/prod-tiny-idp\&quot; TINYIDP-GOJA-001&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja README compiler parser Runtime Interrupt Promise&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;type Runtime\&quot; \&quot;Interrupt\&quot;&quot;},{&quot;q&quot;:&quot;site:github.com/endojs/endo SES compartments hardened JavaScript official&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched 33 webpages</strong></p>
</details>
<pre><code class="language-json">{&quot;open&quot;:[{&quot;ref_id&quot;:&quot;https://github.com/go-go-golems/tiny-idp/archive/refs/heads/task/prod-tiny-idp.zip&quot;},{&quot;ref_id&quot;:&quot;https://github.com/dop251/goja/archive/refs/heads/master.zip&quot;}],&quot;response_length&quot;:&quot;short&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched the web</strong></p>
<p><strong>Fetched and analyzed files and commits from GitHub repository</strong></p>
</details>
<pre><code class="language-json">{&quot;click&quot;:[{&quot;ref_id&quot;:&quot;turn799126view0&quot;,&quot;id&quot;:80}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched the web</strong></p>
<p><strong>Fetched files and content from GitHub repository</strong></p>
<p><strong>Planning monograph structure</strong></p>
<p>I’m outlining a monograph, aiming for around 15k words and diverse topics. It’ll cover Go ja’s architecture, public/private access, design opportunities, and potential optimizations related to parsing, concurrency, and memory checks.</p>
<p><strong>Planned monograph structure</strong></p>
<p><strong>Fetched Goja README content and inspected source code functions</strong></p>
</details>
<pre><code class="language-json">{&quot;find&quot;:[{&quot;ref_id&quot;:&quot;turn799126view3&quot;,&quot;pattern&quot;:&quot;func Compile(&quot;},{&quot;ref_id&quot;:&quot;turn799126view3&quot;,&quot;pattern&quot;:&quot;func CompileAST(&quot;},{&quot;ref_id&quot;:&quot;turn799126view3&quot;,&quot;pattern&quot;:&quot;ParseFile&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;type Runtime struct&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;func (r *Runtime) Interrupt&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;SetMaxCallStackSize&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched 6 webpages</strong></p>
<p><strong>Fetched runtime struct, job queue data, and vm.go content</strong></p>
</details>
<pre><code class="language-json">{&quot;open&quot;:[{&quot;ref_id&quot;:&quot;https://github.com/dop251/goja/blob/master/vm.go&quot;}],&quot;response_length&quot;:&quot;short&quot;}
</code></pre>
<p>The central question is whether ownership, branding, metering, resumability, finite registries, and exact codecs remain host conventions or become intrinsic semantics without creating a monolithic trusted runtime.</p>
<details><summary>💭 Thinking</summary>
<p><strong>Searched the web and GitHub</strong></p>
<p><strong>Fetched file content and searched for function definitions in GitHub</strong></p>
<p><strong>Gathering external sources</strong></p>
<p>I'm considering how to fetch data from GitHub, but it seems tricky without getting full content. I’m planning to turn to external research for relevant documents on ECMAScript, continuations, and functional programming.</p>
<p><strong>Gathered external sources</strong></p>
<p><strong>Fetched Goja parser code for AST export</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:pkg.go.dev/github.com/dop251/goja CompileAST goja&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;CompileAST\&quot;&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;func Compile\&quot; \&quot;parser.ParseFile\&quot;&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched pkg.go.dev</strong></p>
<p><strong>Inspected Goja promise behavior and resolved issues</strong></p>
<p><strong>Searched web for Goja CompileAST function</strong></p>
<p><strong>Fetched lines from Promise documentation section</strong></p>
</details>
<pre><code class="language-json">{&quot;find&quot;:[{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;jobQueue&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;func (r *Runtime) leave()&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;ClearInterrupt&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;SetAsyncContextTracker&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;SetTimeSource&quot;},{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;SetRandSource&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched the web and GitHub</strong></p>
<p><strong>Planning external research</strong></p>
<p>I’m focusing on gathering primary research about various topics like Go ja internals, ECMAScript job queues, and temporal durable execution. I’ll explore papers on language design, memory limits, and compiler APIs.</p>
<p><strong>Planned external research</strong></p>
<p><strong>Designing interpreter architecture</strong></p>
<p>I’m working on building an interpreter with a multi-backend system. I plan to provide extension points like custom syntax, static passes, and static verification while preserving security. I'll also incorporate effects, concurrency, and capability attunement.</p>
<p><strong>Inspected Goja VM interrupt methods and searched repository</strong></p>
</details>
<pre><code class="language-json">{&quot;find&quot;:[{&quot;ref_id&quot;:&quot;turn799126view2&quot;,&quot;pattern&quot;:&quot;Interrupt(v interface{})&quot;},{&quot;ref_id&quot;:&quot;turn266159view0&quot;,&quot;pattern&quot;:&quot;Interrupt(v interface{})&quot;},{&quot;ref_id&quot;:&quot;turn266159view0&quot;,&quot;pattern&quot;:&quot;ClearInterrupt()&quot;},{&quot;ref_id&quot;:&quot;turn266159view0&quot;,&quot;pattern&quot;:&quot;checkInterrupt&quot;},{&quot;ref_id&quot;:&quot;turn266159view0&quot;,&quot;pattern&quot;:&quot;interrupted&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched the web and GitHub</strong></p>
</details>
<pre><code class="language-unknown">bash -lc ls -la /mnt/data | sed -n '1,120p' &amp;&amp; find /mnt/data -maxdepth 2 -type f -printf '%p
' | sed -n '1,200p'
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Listed and inspected existing files</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:tc39.es/ecma262 execution contexts job queues host hooks ECMAScript specification&quot;},{&quot;q&quot;:&quot;site:docs.temporal.io workflow deterministic constraints replay official&quot;},{&quot;q&quot;:&quot;site:github.com/bazelbuild/starlark deterministic hermetic specification&quot;},{&quot;q&quot;:&quot;site:docs.wasmtime.dev fuel epoch interruption resource limiter official&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched web, GitHub, docs, and papers for frameworks and tools</strong></p>
<p><strong>Fetched file content from GitHub repository</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:docs.racket-lang.org guide languages macros create languages Racket&quot;},{&quot;q&quot;:&quot;site:plt.cs.northwestern.edu publications language-oriented programming Racket paper PDF&quot;},{&quot;q&quot;:&quot;site:www2.ccs.neu.edu/racket/pubs language-oriented programming paper&quot;},{&quot;q&quot;:&quot;site:github.com/nanopass/nanopass-framework README compiler passes&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched for Racket, Nanopass, eBPF, WebAssembly, and related resources</strong></p>
<p><strong>Searched Goja repository for CompileAST function</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:pkg.go.dev/github.com/dop251/goja CompileAST Parse Program&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;func CompileAST\&quot;&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;func Parse(\&quot; \&quot;CompileAST\&quot;&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched web for library functions, references, and research papers</strong></p>
<p><strong>Research and platform design</strong></p>
<p>I’m planning to build a Malleable JavaScript Platform. It'll focus on creating a JS/TS-compatible frontend, thorough analysis, verified backends, and runtime kernels supporting realms, schedulers, and memory quotas. The strategy avoids an immediate full JS engine rewrite.</p>
<p><strong>Researched and designed platform</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:pkg.go.dev github.com/dop251/goja CompileAST Program SetTimeSource SetRandSource SetMaxCallStackSize&quot;},{&quot;q&quot;:&quot;QuickJS official documentation JS_SetMemoryLimit JS_SetInterruptHandler bytecode version&quot;},{&quot;q&quot;:&quot;Temporal official deterministic workflow replay side effect versioning documentation&quot;},{&quot;q&quot;:&quot;Wasmtime official fuel epoch interruption resource limiter documentation&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched multiple websites and documentation sources for information</strong></p>
<p><strong>Searched GitHub repository for CompileAST function</strong></p>
</details>
<pre><code class="language-unknown">bash -lc ls -la /mnt/data | sed -n '1,80p'; test -d /mnt/data/tiny-idp &amp;&amp; echo HAS_TINY || true; test -d /mnt/data/goja &amp;&amp; echo HAS_GOJA || true
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Checked and cloned repositories and directories</strong></p>
</details>
<pre><code class="language-json">{&quot;open&quot;:[{&quot;ref_id&quot;:&quot;https://api.github.com/repos/dop251/goja/git/trees/af2ceb9156d7?recursive=1&quot;},{&quot;ref_id&quot;:&quot;https://api.github.com/repos/go-go-golems/tiny-idp/git/trees/d164ae59408bdd8bc21516274b446339b1761b1e?recursive=1&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched the web</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;CompileAST creates\&quot;&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;type instruction interface\&quot;&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;SetAsyncContextTracker\&quot;&quot;},{&quot;q&quot;:&quot;site:github.com/dop251/goja \&quot;func (r *Runtime) leave\&quot; jobQueue&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched Goja internals, runtime API, and GitHub docs</strong></p>
</details>
<pre><code class="language-unknown">bash -lc sed -n '1,260p' /home/oai/skills/docx/SKILL.md &amp;&amp; printf '\n--- create/edit ---\n' &amp;&amp; sed -n '1,260p' /home/oai/skills/docx/tasks/create_edit.md &amp;&amp; printf '\n--- verify ---\n' &amp;&amp; sed -n '1,300p' /home/oai/skills/docx/tasks/verify_render.md &amp;&amp; printf '\n--- pdf ---\n' &amp;&amp; sed -n '1,320p' /home/oai/skills/pdfs/SKILL.md
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Read doc and PDF skills</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;site:docs.temporal.io workflow determinism versioning replay official&quot;},{&quot;q&quot;:&quot;site:docs.wasmtime.dev fuel epoch interruption resource limiter official&quot;},{&quot;q&quot;:&quot;site:component-model.bytecodealliance.org WIT resources owned borrowed official&quot;},{&quot;q&quot;:&quot;site:docs.ebpf.io verifier state pruning abstract interpretation official&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched multiple sources for technical documentation and papers</strong></p>
<p><strong>Fetched and searched Goja runtime and async code for analysis</strong></p>
</details>
<pre><code class="language-unknown">bash -lc which pandoc || true; which libreoffice || true; python - &lt;&lt;'PY'
import docx,sys
print('python-docx',docx.__version__)
PY
</code></pre>
<p>The recommendation is converging on owning a typed/effect IR, verifier, and durable-control lowering, while retaining Goja as a compatibility oracle and forking only where essential.</p>
<details><summary>💭 Thinking</summary>
<p><strong>Checked required tools for document conversion</strong></p>
<p><strong>Fetched references, file content, and design documents for report</strong></p>
</details>
<pre><code class="language-json">{&quot;search_query&quot;:[{&quot;q&quot;:&quot;Defunctionalization at Work Danvy Nielsen official PDF abstract&quot;},{&quot;q&quot;:&quot;Capability Myths Demolished official paper object capabilities&quot;},{&quot;q&quot;:&quot;Effekt capability passing effect system official paper&quot;},{&quot;q&quot;:&quot;Koka compiling with evidence passing effect handlers official paper&quot;}],&quot;response_length&quot;:&quot;long&quot;}
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Searched research papers and resources on language frameworks and compilers</strong></p>
</details>
<pre><code class="language-unknown">bash -lc cat &gt; /mnt/data/malleable-js-tiny-idp-monograph.md &lt;&lt;'EOF'
---
title: &quot;Making JavaScript Malleable&quot;
subtitle: &quot;Compiler and Runtime Co-Design for Tiny-IDP, Durable Capability Workflows, and Reusable Embedded Language Platforms&quot;
author: &quot;Technical research and architecture report&quot;
date: &quot;2026-07-20&quot;
lang: en-US
---

# Scope and source snapshot {.unnumbered}

This report studies a counterfactual extension of the architecture implemented in `go-go-golems/tiny-idp` under ticket `TINYIDP-GOJA-001`: what changes if the framework can modify Goja itself, or replace Goja with a JavaScript-compatible compiler and interpreter designed around Tiny-IDP's assurance requirements?

The Tiny-IDP source baseline is commit [`d164ae59408bdd8bc21516274b446339b1761b1e`](https://github.com/go-go-golems/tiny-idp/commit/d164ae59408bdd8bc21516274b446339b1761b1e), dated 2026-07-20. The Goja baseline used by that commit is [`af2ceb9156d7`](https://github.com/dop251/goja/commit/af2ceb9156d7), as recorded in Tiny-IDP's `go.mod`. The report treats the existing system as a successful first architecture, not as something to discard.

The investigation has four goals:

1. Identify which current invariants are implemented around Goja because Goja does not expose the required semantic hooks.
2. Determine what could become simpler, stronger, or statically checkable if the compiler and runtime were malleable.
3. Derive new programming models for framework implementers and script authors, especially direct-style durable workflows, typed capabilities, affine secrets, deterministic structured concurrency, replay, and migration.
4. Generalize the result into a project-neutral embedded-language platform rather than a Tiny-IDP-specific fork.

The word *verified* is used precisely. Static checking, bytecode verification, translation validation, model checking, differential testing, and machine-checked proof are different assurance levels. The recommended plan deliberately separates them.

The word *novel* is used in the engineering sense: a distinctive synthesis and application of known interpreter and programming-language techniques. It is not a claim of academic priority.

```{=openxml}
&lt;w:p&gt;&lt;w:r&gt;&lt;w:br w:type=&quot;page&quot;/&gt;&lt;/w:r&gt;&lt;/w:p&gt;
</code></pre>
<h1 id="executive-synthesis-unnumbered">Executive synthesis {.unnumbered}</h1>
<p>Tiny-IDP already made the decisive architectural move: JavaScript does not become the identity provider. It produces bounded policy decisions and data-only plans inside a native protocol kernel. Lambdas have schemas, allowed outcomes, capability requirements, effect permissions, time limits, call limits, and output limits. Browser waits become explicit pure-Go continuation records rather than retained Goja heaps. Runtime workers are leased exclusively and discarded after uncertain failure. These are interpreter design decisions even though most are implemented outside the interpreter.</p>
<p>Owning the compiler or interpreter would change the location and strength of those decisions.</p>
<p>Today, Tiny-IDP must infer safety from a collection of external mechanisms:</p>
<ul>
<li>callback identity is reconstructed by re-running module initialization in every runtime;</li>
<li>nominal types are simulated with blank objects branded in Go-side identity maps;</li>
<li>capabilities are ordinary native functions whose authority is revoked by host-side lifetime flags;</li>
<li>execution is bounded primarily by wall-clock interruption and host-call budgets;</li>
<li>pending asynchronous work is tracked by a parallel host-side settlement counter;</li>
<li>immutable inputs are produced through JSON round-tripping and recursive freezing;</li>
<li>result values are copied back through JSON and checked after execution;</li>
<li>browser-spanning control flow is written manually as handler maps and explicit resume labels;</li>
<li>static capability and effect contracts are declared separately from the body that uses them;</li>
<li>the host cannot inspect or verify Goja bytecode because Goja's instruction representation is private.</li>
</ul>
<p>A malleable runtime could make many of these properties semantic rather than conventional:</p>
<ul>
<li>callback IDs and durable checkpoint IDs could be assigned by the compiler;</li>
<li>capabilities, secrets, evidence, and native resources could be dedicated VM value kinds with nominal type, generation, owner, and lifetime metadata;</li>
<li>the compiler could infer capability and effect requirements from code and reject undeclared authority;</li>
<li>instruction fuel, allocation quotas, microtask quotas, stack quotas, and host-call costs could be enforced at exact interpreter safe points;</li>
<li>the scheduler could know the complete task tree instead of relying on Promise polling and a separate settlement census;</li>
<li>direct-style <code>durable await</code> could compile to explicit state machines and serialized continuation frames;</li>
<li>liveness analysis could prove that secrets, capabilities, closures, and other ephemeral values do not cross durable checkpoints;</li>
<li>nondeterministic operations could be unavailable by default or recorded as replay events;</li>
<li>hot reload could be checked against stable semantic IDs and continuation-frame schemas;</li>
<li>a small typed core IR could be verified before any backend executes it;</li>
<li>the same frontend and core could support Goja, a custom interpreter, WebAssembly, static Go generation, symbolic execution, and model-checking backends.</li>
</ul>
<p>The strongest recommendation is <strong>not</strong> to begin by implementing all of ECMAScript. The strategic asset is the semantic seam between JavaScript authoring and trusted execution. The recommended platform is:</p>
<pre><code class="language-text">JavaScript / TypeScript-shaped source
        |
        v
parser + source-preserving expansion
        |
        v
resolved Assured HIR
        |
        +--&gt; type / effect / authority / sensitivity analysis
        +--&gt; durable-control-flow lowering
        +--&gt; determinism and migration analysis
        |
        v
small verified Core IR + manifest
        |
        +--&gt; Goja backend, initially
        +--&gt; custom interpreter, later
        +--&gt; Wasm/component backend, optionally
        +--&gt; symbolic and test backends
</code></pre>
<p>The project-neutral abstraction is a <strong>host profile</strong>. A profile declares value types, outcome variants, capabilities, effects, handle kinds, durability rules, resource costs, permitted nondeterminism, and native bindings. Tiny-IDP would be one profile. Other profiles could target approval workflows, deployment orchestration, policy engines, document pipelines, game logic, automation, or agent tool runtimes.</p>
<p>The recommended implementation sequence is:</p>
<ol>
<li>Build a source analyzer and stable Assured HIR above public Goja APIs.</li>
<li>Generate callback registries, contracts, manifests, source maps, and continuation state machines at compile time.</li>
<li>Maintain a small Goja fork or upstreamable hook layer for fuel, scheduler events, allocation accounting, host-value kinds, and deterministic runtime configuration.</li>
<li>Introduce a project-neutral Core IR and verifier; execute it through a Goja adapter first.</li>
<li>Add a native Core IR interpreter for the assured subset when its semantics and workload are stable.</li>
<li>Prove selected critical properties of the Core IR, verifier, durable lowering, and effect boundary. Do not condition progress on proving full JavaScript.</li>
</ol>
<p>This path preserves JavaScript usability while moving the trusted semantics into a smaller, explicit, reusable layer.</p>
<h1 id="part-i---what-ownership-of-the-interpreter-changes">Part I - What ownership of the interpreter changes</h1>
<h2 id="1-tiny-idp-is-already-an-interpreter-architecture">1. Tiny-IDP is already an interpreter architecture</h2>
<p>A superficial description of Tiny-IDP says that Go embeds JavaScript. A more accurate description is that Tiny-IDP implements a staged language system around Goja.</p>
<p>At definition time, trusted source executes in an isolated runtime and registers a pure serializable program plus VM-local callbacks. At activation time, the same compiled source is materialized independently in every worker and compared against canonical fingerprints. At request time, one owned worker receives frozen inputs and an invocation-specific capability environment. The returned value is decoded into a closed native outcome family. Finally, Go interprets that outcome as presentation, challenge, commit, completion, denial, skip, or error.</p>
<p><code>LambdaSpec</code> is already a dynamic type-and-effect contract. It records input and output schemas, allowed outcomes, required capabilities, allowed effects, and resource budgets; it intentionally does not contain the callback function itself. [TINY-LAMBDA] The outcome family is closed, and effect plans are inert requests that JavaScript never applies directly. [TINY-OUTCOME]</p>
<p>The browser continuation is already defunctionalized. It records a resume handler ID and typed carry rather than a closure. The durable record explicitly forbids Goja values, functions, Promises, and goroutine-local state, and includes executable generation identity, request binding, presentation state, secret and evidence references, revision, expiry, and status. [TINY-CONT]</p>
<p>The active design states the key distinction explicitly: in-request <code>await</code> may keep one HTTP request and one runtime invocation alive, but a browser boundary returns normally and persists a continuation. It also anticipates that a future compiler could transform restricted browser-spanning <code>await</code> syntax into the same explicit representation. [TINY-DESIGN]</p>
<p>Thus the question is not whether Tiny-IDP should become interpreter-driven. It already is. The question is whether interpreter semantics should remain encoded in host conventions or become first-class compiler and runtime mechanisms.</p>
<h2 id="2-the-current-semantic-envelope-around-stock-goja">2. The current semantic envelope around stock Goja</h2>
<p>The existing implementation obtains strong behavior through disciplined composition.</p>
<h3 id="21-closed-runtime-construction">2.1 Closed runtime construction</h3>
<p>The runtime factory disables implicit default modules, data modules, and the ambient loader, then registers only the Tiny-IDP module. Each runtime is independently created and populated. [TINY-RUNTIME]</p>
<h3 id="22-reproducible-registration">2.2 Reproducible registration</h3>
<p>The artifact is executed in each runtime. <code>module.exports</code> is copied through JSON, while the collector independently yields the registered program and callback registry. Canonical program equality, program fingerprints, callback fingerprints, schema fingerprints, and one-to-one callback membership are checked before a runtime is accepted. [TINY-RUNTIME]</p>
<p>This is a dynamic linker with reproducibility checks. It is rigorous, but it exists because callback identity is not represented in a compile-time artifact that Goja and Tiny-IDP jointly understand.</p>
<h3 id="23-exclusive-ownership-and-fail-stop-reuse">2.3 Exclusive ownership and fail-stop reuse</h3>
<p>A runtime is not goroutine-safe, so Tiny-IDP wraps it in an owner and leases it exclusively. Invocation cancellation uses <code>Runtime.Interrupt</code>. The worker is marked reusable only after the result is valid and all capability settlements have completed. Any uncertain interruption, exception, malformed output, or settlement ambiguity causes disposal and replacement. [TINY-INVOKE] [TINY-POOL]</p>
<h3 id="24-invocation-capabilities">2.4 Invocation capabilities</h3>
<p>Only declared capability names at exact versions are installed. Every call checks invocation lifetime, argument count, call budget, input size, output size, and context cancellation. Native work runs outside the VM, then schedules Promise settlement back through the runtime owner. A retained function becomes powerless when the invocation closes. [TINY-CAP]</p>
<h3 id="25-copy-boundaries">2.5 Copy boundaries</h3>
<p>Inputs are JSON-validated, parsed inside Goja, and recursively frozen. Results are copied back and validated against the lambda contract. These boundaries avoid exposing reflection-based Go host objects and prevent Goja values from entering durable state. [TINY-INVOKE]</p>
<p>Each mechanism is soundly motivated. The cost is that the framework has a shadow interpreter: Goja executes JavaScript, while Tiny-IDP separately tracks ownership, lifetime, pending work, capability authority, callback identity, schemas, outcomes, effects, and durability.</p>
<h2 id="3-what-public-goja-exposes---and-what-it-hides">3. What public Goja exposes - and what it hides</h2>
<p>Goja is unusually suitable for this work because it is written in pure Go, has a reusable compiled <code>Program</code>, exposes a parser and AST, permits custom time and random sources, supports interruption, and delegates event-loop policy to the embedder. It is also explicit that a <code>Runtime</code> is not goroutine-safe and that JavaScript objects cannot move between runtimes. [GOJA-README]</p>
<p>The public compiler seam is meaningful. <code>Parse</code> returns an AST and <code>CompileAST</code> compiles an AST into a runtime-independent <code>Program</code> reusable by multiple runtimes. [GOJA-COMPILE] This already permits an analyzer or source-to-source transform before Goja compilation.</p>
<p>The public runtime seam is narrower. An embedder can configure time, randomness, parser options, maximum call-stack depth, Promise rejection tracking, and asynchronous-context tracking. [GOJA-RUNTIME] It can interrupt a running VM. It can create native functions and Promises. It cannot, through public APIs:</p>
<ul>
<li>inspect or rewrite the compiled instruction stream;</li>
<li>charge fuel per instruction or basic block;</li>
<li>receive a callback for every allocation or object growth;</li>
<li>define a new primitive or VM-level nominal value kind;</li>
<li>replace the Promise job queue and its drain policy;</li>
<li>enumerate all outstanding Promises or asynchronous roots;</li>
<li>checkpoint a validated subset of execution state;</li>
<li>attach effect, secrecy, ownership, or durability metadata to values;</li>
<li>verify a <code>Program</code> against a project-specific bytecode policy.</li>
</ul>
<p>The boundary is visible in the source. <code>Program</code> contains a private instruction slice. The VM dispatch loop repeatedly calls private <code>instruction.exec</code> methods, checking only profiler and interrupt state. [GOJA-COMPILER] [GOJA-VM] Promise jobs are appended to a private runtime queue and drained when top-level execution leaves normally; abrupt interruption clears the queue. [GOJA-PROMISE-QUEUE]</p>
<p>Goja also already implements in-memory suspension for generators and async functions. Its suspended <code>execCtx</code> contains the current program, environment stashes, private environment, program counter, stack base, arguments, value stack, try stack, iterator stack, and reference stack. Async functions are implemented through generator-like suspension and Promise reactions. [GOJA-ASYNC]</p>
<p>That implementation is evidence that Goja has the right control points internally. It is also evidence that serializing raw VM continuations would be the wrong durable abstraction. The captured state contains runtime-local values, object identity, environment pointers, iterators, references, and code positions. Persisting it would bind continuations to heap layout, engine version, bytecode layout, garbage-collector assumptions, and possibly secret-bearing objects.</p>
<h3 id="31-the-first-major-conclusion">3.1 The first major conclusion</h3>
<p>Access to Goja internals is valuable primarily because it permits <strong>instrumentation and semantic hooks</strong>, not because Tiny-IDP should dump and restore Goja heaps.</p>
<p>The useful internal changes are:</p>
<ul>
<li>deterministic safe points and fuel charging in the dispatch loop;</li>
<li>explicit scheduler and task-tree hooks around Promise jobs and host calls;</li>
<li>project-defined VM value kinds for opaque handles;</li>
<li>allocation and collection accounting;</li>
<li>compiler metadata and stable semantic IDs;</li>
<li>program inspection and verification;</li>
<li>source-level and IR-level tracing;</li>
<li>cheap realm reset or fresh-realm creation.</li>
</ul>
<p>Durable continuation state should remain compiler-generated, first-order, typed, and independent of VM internals.</p>
<h2 id="4-five-levels-of-ownership">4. Five levels of ownership</h2>
<p>There is no binary choice between &quot;stock Goja&quot; and &quot;write a JavaScript engine.&quot; There is a useful five-level spectrum.</p>
<table>
<thead>
<tr>
<th>Level</th>
<th>What is owned</th>
<th>Main gain</th>
<th>Main limitation</th>
</tr>
</thead>
<tbody>
<tr>
<td>0. Host wrapper</td>
<td>Runtime factory, modules, owner, pool, codecs</td>
<td>Low maintenance; current design</td>
<td>Safety properties remain external and partly duplicated</td>
</tr>
<tr>
<td>1. Frontend/analyzer</td>
<td>Goja parser AST, resolver, type/effect analysis, source transform</td>
<td>Compile-time manifests, diagnostics, durable lowering</td>
<td>VM scheduling, memory, and fuel remain opaque</td>
</tr>
<tr>
<td>2. Hooked Goja</td>
<td>Small fork or upstreamable hooks in compiler/VM/runtime</td>
<td>Exact fuel, task census, host values, tracing, reset</td>
<td>Fork maintenance and Goja internals enter TCB</td>
</tr>
<tr>
<td>3. Assured Core VM</td>
<td>Own typed IR, verifier, interpreter; JS frontend remains</td>
<td>Small semantics, precise quotas, replay, proof target</td>
<td>Supports a deliberate JS subset, not arbitrary ECMAScript</td>
</tr>
<tr>
<td>4. Full JS engine</td>
<td>Parser through GC, built-ins, JIT/interpreter</td>
<td>Total control</td>
<td>Enormous compatibility, security, performance, and maintenance burden</td>
</tr>
</tbody>
</table>
<p>The recommended destination is not necessarily Level 4. A strong system can combine Level 1, a narrow Level 2, and Level 3. JavaScript remains the authoring language, while the assured subset executes in a smaller machine.</p>
<h1 id="part-ii---the-proposed-malleable-javascript-platform">Part II - The proposed malleable JavaScript platform</h1>
<h2 id="5-own-the-semantic-seam-not-the-language-brand">5. Own the semantic seam, not the language brand</h2>
<p>The strategic objective should be stated narrowly:</p>
<blockquote>
<p>Accept familiar JavaScript or TypeScript-shaped programs, compile them into an explicit project-neutral semantic core, verify that core against a versioned host profile, and execute it through one of several controlled backends.</p>
</blockquote>
<p>The platform should not promise that every npm package or every metaprogramming trick will work. It should promise that supported code has clear authority, resource, durability, and replay semantics.</p>
<p>A possible architecture is:</p>
<pre><code class="language-text">+------------------------------- Authoring -------------------------------+
| JavaScript | TypeScript annotations | JSDoc | project syntax extensions |
+-----------------------------------+-------------------------------------+
                                    |
                                    v
+------------------------------ Frontend --------------------------------+
| Parse | resolve names | expand trusted macros | preserve source maps     |
+-----------------------------------+-------------------------------------+
                                    |
                                    v
+---------------------------- Assured HIR -------------------------------+
| explicit bindings | nominal types | effects | capabilities | labels      |
| sensitivity | ownership | async regions | source provenance             |
+------------------+----------------+----------------+---------------------+
                   |                |                |
                   v                v                v
             static checks    durable lowering   manifest generation
                   |                |                |
                   +----------------+----------------+
                                    |
                                    v
+------------------------------ Core IR ---------------------------------+
| first-order CFG | typed values | host-call opcodes | checkpoints         |
| structured tasks | closed outcomes | explicit traps | cost annotations    |
+-----------------------------------+-------------------------------------+
                                    |
                          verifier + signer
                                    |
                                    v
+------------------------------- Bundle ---------------------------------+
| code | schemas | fingerprints | authority manifest | migrations | maps  |
+---------+--------------------------+----------------------------+--------+
          |                          |                            |
          v                          v                            v
   Goja backend               native Core VM                Wasm backend
</code></pre>
<p>This structure separates three concerns that are entangled in ordinary embedded JavaScript:</p>
<ul>
<li><strong>surface compatibility</strong>: familiar syntax, modules, functions, promises, editor support;</li>
<li><strong>semantic assurance</strong>: authority, effects, lifetimes, durability, determinism, resource bounds;</li>
<li><strong>execution technology</strong>: Goja, a custom interpreter, Wasm, static Go, or symbolic execution.</li>
</ul>
<p>The separation is what makes the system reusable across projects.</p>
<h2 id="6-host-profiles-as-the-project-neutral-extension-boundary">6. Host profiles as the project-neutral extension boundary</h2>
<p>Tiny-IDP-specific semantics should not be compiled into the generic interpreter. They should be supplied by a versioned host profile.</p>
<p>A host profile is analogous to a typed interface description plus a semantic policy. WIT is a useful comparison: WIT defines component contracts and includes records, variants, results, functions, interfaces, worlds, and owned or borrowed resource handles, while deliberately not defining component behavior. [WIT] The proposed profile adds interpreter-specific policies that WIT does not attempt to express.</p>
<p>A profile should declare:</p>
<pre><code class="language-text">Profile
  identity and semantic version
  source-language feature set
  value and schema types
  nominal handle kinds
  capability signatures and versions
  effect constructors and commit domains
  outcome variants
  sensitivity labels and flow rules
  ownership / borrowing / lifetime rules
  durable value rules
  determinism classes
  cost model and quotas
  host-call retry / idempotency semantics
  native binding identifiers
  migration rules
  diagnostic catalog
</code></pre>
<p>An illustrative profile fragment:</p>
<pre><code class="language-yaml">profile: tinyidp.assured/v2

handles:
  PasswordSecret:
    sensitivity: secret
    ownership: affine
    durable: false
  ChallengeEvidence:
    sensitivity: restricted
    ownership: borrowed
    durable: reference-only

capabilities:
  account.lookup@1:
    input: IdentityLookup
    output: option&lt;IdentityCandidate&gt;
    effects: [account.read]
    determinism: recorded
    cost: 25
  password.verify@1:
    input: { subject: SubjectRef, password: PasswordSecret }
    output: VerificationResult
    effects: [credential.verify]
    determinism: native-evidence
    cost: 100

outcomes:
  - continue
  - present
  - challenge
  - commit
  - complete
  - deny
  - skip
  - error

checkpoints:
  max-public-frame-bytes: 8192
  forbid-live-labels: [secret, capability, transient]
</code></pre>
<p>Generated bindings would expose idiomatic project APIs while the profile remains language-neutral. A Tiny-IDP package could generate TypeScript declarations, Go dispatch stubs, schema codecs, documentation, test fixtures, and verifier tables from the same source.</p>
<h3 id="61-why-profiles-are-more-important-than-custom-syntax">6.1 Why profiles are more important than custom syntax</h3>
<p>A custom keyword is visible but local. A profile determines what a program can mean. It makes extension auditable and portable:</p>
<ul>
<li>two projects can share the compiler while exposing different authority;</li>
<li>a project can upgrade capability implementations without changing the language core;</li>
<li>tooling can explain exactly which operations and effects a plugin requires;</li>
<li>artifact fingerprints can include the profile version;</li>
<li>a verifier can reject a bundle compiled for the wrong host;</li>
<li>alternate backends can share the same contract.</li>
</ul>
<h2 id="7-the-assured-hir">7. The Assured HIR</h2>
<p>The central design artifact should be a high-level intermediate representation, not Goja bytecode.</p>
<p>The Assured HIR should preserve enough structure for diagnostics and analysis while removing JavaScript ambiguity. It should include:</p>
<ul>
<li>resolved lexical bindings rather than name lookup;</li>
<li>explicit function and closure capture sets;</li>
<li>explicit records, variants, lists, options, results, and nominal handles;</li>
<li>explicit conversions at dynamic boundaries;</li>
<li>capability calls as distinguished nodes, not generic property calls;</li>
<li>effect plans as typed constructors;</li>
<li>sensitivity and ownership labels on values;</li>
<li>structured task regions and cancellation edges;</li>
<li>durable checkpoint labels;</li>
<li>source spans and expansion provenance;</li>
<li>explicit exceptional exits;</li>
<li>finite outcome types.</li>
</ul>
<p>A normalized function might look like:</p>
<pre><code class="language-text">function signup.submitted(
    input: SignupPost,
    cap accountLookup: cap&lt;account.lookup@1&gt;,
    cap passwordPolicy: cap&lt;password.policy@1&gt;
) -&gt; Outcome&lt;SignupResult&gt;
requires { account.read, password.policy }
budget { fuel: 25000, hostCost: 200, outputBytes: 8192 }
{
entry:
    email = project input.email
    existing = host.call accountLookup(email)
    branch isSome(existing), already_exists, check_password

already_exists:
    return deny(&quot;account_exists&quot;)

check_password:
    verdict = host.call passwordPolicy(input.password)
    branch verdict.accepted, propose_commit, weak_password

weak_password:
    return deny(verdict.code)

propose_commit:
    plan = effects [
        identity.create(email, input.displayName),
        credential.password.set(input.password)
    ]
    return commit(plan)
}
</code></pre>
<p>This is not intended as user syntax. It is the analyzable meaning after JavaScript features are elaborated.</p>
<h3 id="71-why-not-analyze-ordinary-goja-bytecode-directly">7.1 Why not analyze ordinary Goja bytecode directly?</h3>
<p>Goja bytecode is an implementation representation. It contains many instructions specialized for ECMAScript semantics and is private. Building project assurance directly on it would couple the verifier to Goja internals and make source-level concepts difficult to recover.</p>
<p>The HIR should instead be stable under backend changes. Goja code generation is one lowering. A custom Core VM is another. A symbolic interpreter is a third.</p>
<h3 id="72-small-passes-and-many-irs">7.2 Small passes and many IRs</h3>
<p>The compiler should prefer explicit small passes over a single large transformation. The Nanopass approach emphasizes many intermediate representations and small passes to reduce boilerplate and make compilers easier to understand and maintain. [NANOPASS]</p>
<p>A possible pass sequence is:</p>
<pre><code class="language-text">JS AST
  -&gt; module-normalized AST
  -&gt; resolved AST
  -&gt; project-expanded AST
  -&gt; typed/effected HIR
  -&gt; ownership-checked HIR
  -&gt; async-region HIR
  -&gt; durable state-machine HIR
  -&gt; first-order Core IR
  -&gt; verified bundle
</code></pre>
<p>Each pass should have a narrow contract and deterministic output. Important passes can use translation validation: after transformation, an independent checker validates the relation between input and output rather than trusting the transformer alone.</p>
<h2 id="8-javascript-compatibility-profiles">8. JavaScript compatibility profiles</h2>
<p>A reusable platform should offer at least two authoring profiles.</p>
<h3 id="81-compatible-profile">8.1 Compatible profile</h3>
<p>The compatible profile remains valid JavaScript or TypeScript. It uses imports, decorators, tagged builders, JSDoc, or generic functions to carry semantic metadata.</p>
<pre><code class="language-typescript">import { workflow, cap, outcome, durable } from &quot;@tinyidp/assured&quot;;

export const signup = workflow&lt;SignupStart, SignupResult&gt;({
  id: &quot;signup&quot;,
  capabilities: [cap.account.lookup.v1, cap.mail.challenge.v1],
  effects: [&quot;identity.create&quot;, &quot;credential.password.set&quot;],
  budget: { fuel: 80_000, hostCost: 500 }
}, durable(async ctx =&gt; {
  const form = await ctx.browser.present(SignupForm);
  const existing = await ctx.account.lookup({ email: form.email });
  if (existing) return outcome.deny(&quot;account_exists&quot;);

  const proof = await ctx.challenge.email({ address: form.email });
  if (!proof.verified) return outcome.deny(&quot;email_unverified&quot;);

  return outcome.commit(ctx.effects.signup({
    email: form.email,
    displayName: form.displayName,
    password: form.password,
    evidence: proof.evidence
  }));
}));
</code></pre>
<p>The function appears direct-style, but only selected awaitable operations are durable. The compiler distinguishes in-request capability calls from browser-spanning checkpoints through nominal return types.</p>
<p>Benefits:</p>
<ul>
<li>standard parsers and editor ecosystems remain usable;</li>
<li>generated <code>.d.ts</code> files can provide types without designing a full parser;</li>
<li>code can often be linted and unit-tested outside the production runtime;</li>
<li>source remains recognizable JavaScript.</li>
</ul>
<p>Costs:</p>
<ul>
<li>some semantic distinctions are encoded through APIs rather than syntax;</li>
<li>TypeScript erasure means the production compiler must perform its own checks;</li>
<li>dynamic features may need explicit rejection.</li>
</ul>
<h3 id="82-js-shaped-dialect">8.2 JS-shaped dialect</h3>
<p>A dialect may add a small number of high-value forms:</p>
<pre><code class="language-javascript">export durable async function signup(ctx: SignupContext)
  uses account.lookup@1, challenge.email@1
  commits identity.create, credential.password.set
  budget fuel 80000, host 500
{
  const form = durable await present SignupForm;
  const existing = await ctx.account.lookup({ email: form.email });
  if (existing) deny &quot;account_exists&quot;;

  const proof = durable await challenge.email(form.email);
  commit signupAccount(form, proof);
}
</code></pre>
<p>New syntax is justified only when it exposes a semantic distinction that ordinary JavaScript hides. <code>durable await</code>, <code>uses</code>, <code>commits</code>, <code>budget</code>, exhaustive <code>match</code>, and explicit sensitivity annotations meet that threshold. Cosmetic syntax does not.</p>
<p>Racket's language architecture provides a useful warning: ordinary macros can extend syntax but cannot reliably restrict surrounding syntax or change its meaning; complete language variants require control over reader and expansion phases. [RACKET] A malleable JavaScript platform should likewise distinguish library combinators from true language profiles.</p>
<h3 id="83-recommended-policy">8.3 Recommended policy</h3>
<p>Start with the compatible profile. Add dialect syntax only after several real projects demonstrate repeated semantic friction. Both profiles must lower to the same HIR and pass the same verifier.</p>
<h1 id="part-iii---direct-style-durable-workflows">Part III - Direct-style durable workflows</h1>
<h2 id="9-the-opportunity-hidden-in-explicit-continuations">9. The opportunity hidden in explicit continuations</h2>
<p>Tiny-IDP's explicit handler map is the correct runtime contract but not necessarily the best source notation. The compiler can offer direct style without serializing the VM.</p>
<p>Consider a browser workflow written manually:</p>
<pre><code class="language-javascript">const start = A.lambda(&quot;signup.start&quot;, specStart, ctx =&gt;
  ctx.present.signup({ resume: &quot;signup.submitted&quot; })
);

const submitted = A.lambda(&quot;signup.submitted&quot;, specSubmitted, async ctx =&gt; {
  const found = await ctx.cap.account.lookup({ email: ctx.input.email });
  if (found) return ctx.deny(&quot;account_exists&quot;);
  return ctx.challenge.email({
    address: ctx.input.email,
    resume: &quot;signup.email_verified&quot;,
    carry: { email: ctx.input.email, displayName: ctx.input.displayName }
  });
});

const emailVerified = A.lambda(&quot;signup.email_verified&quot;, specVerified, ctx =&gt;
  ctx.commit.signup(/* ... */)
);
</code></pre>
<p>The explicit code is reviewable, but plugin authors manually maintain:</p>
<ul>
<li>handler IDs;</li>
<li>edge wiring;</li>
<li>carry projections;</li>
<li>input schemas for each resumed handler;</li>
<li>stable generation and migration identity;</li>
<li>restrictions on values crossing boundaries.</li>
</ul>
<p>A compiler can derive these while preserving the explicit runtime model.</p>
<h2 id="10-cps-plus-defunctionalization">10. CPS plus defunctionalization</h2>
<p>The appropriate lowering is a combination of control-flow normalization, continuation-passing style, liveness analysis, and defunctionalization.</p>
<p>Defunctionalization is a whole-program transformation from higher-order functions to a first-order data type plus an apply function. [DEFUNC] Applied selectively to durable control flow, it converts &quot;what to do after the browser returns&quot; from an implicit continuation into a finite checkpoint label and a typed environment.</p>
<p>A simplified transformation:</p>
<pre><code class="language-javascript">export const signup = durable(async ctx =&gt; {
  const form = await ctx.browser.present(SignupForm);
  const member = await ctx.account.lookup({ email: form.email });
  if (member) return ctx.deny(&quot;account_exists&quot;);
  const proof = await ctx.challenge.email(form.email);
  return ctx.commit.signup(form, proof);
});
</code></pre>
<p>becomes conceptually:</p>
<pre><code class="language-text">handler signup#entry(startInput):
    return present(SignupForm,
        continuation = { checkpoint: signup#after-form, frame: {} })

handler signup#after-form(formInput):
    member = await-in-request account.lookup(formInput.email)
    if member:
        return deny(&quot;account_exists&quot;)
    return challenge.email(formInput.email,
        continuation = {
            checkpoint: signup#after-email,
            frame: publicProjection(formInput)
        })

handler signup#after-email(frame, challengeInput, evidenceRef):
    return commit signup(frame, evidenceRef)
</code></pre>
<p>The generated continuation record remains first-order:</p>
<pre><code class="language-text">ContinuationFrame {
  artifact_digest
  profile_digest
  workflow_id
  function_id
  checkpoint_id
  frame_schema_digest
  public_frame
  native_references
  revision
  expiry
}
</code></pre>
<h3 id="101-liveness-at-checkpoints">10.1 Liveness at checkpoints</h3>
<p>The compiler computes which values are live after each durable await. Only those values need to enter the frame.</p>
<p>For each live value, the checker asks:</p>
<ol>
<li>Is its type serializable under the profile?</li>
<li>Is its sensitivity label allowed in public carry?</li>
<li>Is it an owned or borrowed host handle?</li>
<li>May it cross a durable boundary by value, by stable native reference, or not at all?</li>
<li>Is its schema bounded?</li>
<li>Is its representation stable across compatible upgrades?</li>
</ol>
<p>This removes the need for plugin authors to hand-copy carry objects and makes a crucial security property statically visible.</p>
<h3 id="102-stable-checkpoint-identity">10.2 Stable checkpoint identity</h3>
<p>A checkpoint ID must not be a raw bytecode offset or line number. Edits would invalidate it unpredictably. The compiler should use explicit or semantically derived labels:</p>
<pre><code class="language-typescript">const form = await checkpoint(&quot;collect-signup-form&quot;,
  ctx.browser.present(SignupForm));
</code></pre>
<p>or a source annotation:</p>
<pre><code class="language-javascript">/** @checkpoint signup.collect-form */
const form = await ctx.browser.present(SignupForm);
</code></pre>
<p>The artifact records:</p>
<ul>
<li>stable checkpoint ID;</li>
<li>source location;</li>
<li>frame schema;</li>
<li>continuation successors;</li>
<li>required resume event type;</li>
<li>migration compatibility metadata.</li>
</ul>
<p>An unlabeled checkpoint may receive a generated ID during development, but production activation should warn or reject workflows whose durable identities are not explicit.</p>
<h3 id="103-why-raw-goja-suspension-remains-wrong">10.3 Why raw Goja suspension remains wrong</h3>
<p>Goja's generator suspension captures a complete execution context containing stack values, lexical environments, references, iterator state, try state, and a program counter. [GOJA-ASYNC] This is appropriate for in-memory JavaScript semantics. It is inappropriate for durable identity workflows because:</p>
<ul>
<li>a value stack can retain secrets and capabilities;</li>
<li>object identity cannot be reconstructed portably;</li>
<li>closures may capture arbitrary module state;</li>
<li>program counters are tied to compiler output;</li>
<li>iterators, proxies, and native host objects may be nonserializable;</li>
<li>engine upgrades may change instruction layout;</li>
<li>persisted heaps enlarge the attack and migration surface;</li>
<li>audit tools cannot easily explain the state.</li>
</ul>
<p>Compiler-generated continuation frames preserve only semantically live, policy-approved values.</p>
<h2 id="11-durable-operations-as-an-effect-class">11. Durable operations as an effect class</h2>
<p>The language should distinguish at least three classes of asynchronous operation:</p>
<table>
<thead>
<tr>
<th>Class</th>
<th>Example</th>
<th>Lifetime</th>
<th>Replay behavior</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pure/in-memory async</td>
<td>local Promise composition</td>
<td>invocation</td>
<td>not persisted</td>
</tr>
<tr>
<td>In-request host call</td>
<td>account lookup</td>
<td>HTTP invocation</td>
<td>result copied/recorded as policy permits</td>
</tr>
<tr>
<td>Durable suspension</td>
<td>browser form, external approval, timer</td>
<td>days or restarts</td>
<td>continuation persisted and resumed</td>
</tr>
</tbody>
</table>
<p>Ordinary <code>await</code> should not silently become durable. The awaited expression has a type such as:</p>
<pre><code class="language-text">Promise&lt;T&gt;                 // in-memory
HostCall&lt;T, effect-set&gt;    // bounded in-request capability
Durable&lt;T, checkpoint-k&gt;   // compiler-lowered suspension
</code></pre>
<p>This type distinction prevents an accidental <code>await fetch(...)</code> from creating an undefined persistence model.</p>
<h2 id="12-direct-style-without-hidden-protocol-authority">12. Direct style without hidden protocol authority</h2>
<p>Ergonomics must not reverse the microkernel boundary. A direct-style workflow still cannot own HTTP, OAuth, credentials, transactions, or token issuance. The compiler-generated state machine returns the same closed outcomes and inert plans as the current system.</p>
<p>The lowering rule is:</p>
<pre><code class="language-text">source convenience
    -&gt; explicit outcome / checkpoint / effect IR
    -&gt; native validation and commit
</code></pre>
<p>not:</p>
<pre><code class="language-text">source convenience
    -&gt; serialized arbitrary JavaScript runtime
</code></pre>
<p>This distinction is central. The compiler makes explicit continuations easier to author; it does not remove them from the architecture.</p>
<h1 id="part-iv---capabilities-effects-handles-and-secrets">Part IV - Capabilities, effects, handles, and secrets</h1>
<h2 id="13-from-declared-capabilities-to-inferred-authority">13. From declared capabilities to inferred authority</h2>
<p>Tiny-IDP currently requires a lambda to declare capability requirements and checks that only those bindings are installed. This is already object-capability style authority: a callback can invoke only operations represented by references given to it. Capability systems are particularly useful for least privilege and avoiding confused deputies. [OCAP]</p>
<p>A compiler can improve this in three ways.</p>
<h3 id="131-infer-the-capability-set">13.1 Infer the capability set</h3>
<p>Every host call is a distinguished HIR node. The compiler computes the required capability row:</p>
<pre><code class="language-text">used(signup.submitted) = {
  account.lookup@1,
  password.policy@1,
  challenge.email@1
}
</code></pre>
<p>The source declaration can serve as a maximum authority budget:</p>
<pre><code class="language-text">inferred capabilities subset-of declared capabilities
</code></pre>
<p>Unused declared authority becomes a warning or error. Undeclared use is an error. This prevents metadata drift.</p>
<h3 id="132-capability-passing-as-the-effect-model">13.2 Capability passing as the effect model</h3>
<p>Effect systems can describe effects as capabilities required from a context rather than merely as labels attached to functions. The Effekt work demonstrates this design point and translates it to explicit capability-passing style. [EFFEKT]</p>
<p>For the proposed platform:</p>
<pre><code class="language-text">Gamma ; C ; E |- expression : T
</code></pre>
<p>means that under value environment <code>Gamma</code>, capability environment <code>C</code>, and permitted commit-effect set <code>E</code>, the expression produces <code>T</code>.</p>
<p>A function type may carry requirements:</p>
<pre><code class="language-text">(Input) -&gt; Outcome&lt;Result&gt;
  requires { account.lookup@1, challenge.email@1 }
  proposes { identity.create, credential.password.set }
</code></pre>
<p>Compilation can elaborate implicit <code>ctx</code> property access into explicit capability parameters in HIR. This makes authority flow visible and supports attenuation.</p>
<h3 id="133-attenuation-and-scoped-delegation">13.3 Attenuation and scoped delegation</h3>
<p>A capability can be narrowed before being passed to helper code:</p>
<pre><code class="language-typescript">const lookupByEmail = ctx.account.lookup.attenuate({
  fields: [&quot;subject&quot;, &quot;status&quot;],
  maxCalls: 1
});

return evaluateEligibility(lookupByEmail, input.email);
</code></pre>
<p>The attenuation is either a statically known wrapper or a host-created child capability with a smaller policy. Helpers can be polymorphic over a capability interface without receiving the whole invocation context.</p>
<p>This creates a new plugin design pattern: <strong>authority-oriented modularity</strong>. Functions are reusable because they state the exact powers they require.</p>
<h2 id="14-effects-as-inert-typed-commands">14. Effects as inert, typed commands</h2>
<p>Tiny-IDP's commit outcome already resembles an algebraic effect request. JavaScript constructs an effect plan; Go handles it in a native transaction.</p>
<p>A compiler can make this algebra explicit:</p>
<pre><code class="language-typescript">return ctx.commit.atomic(&quot;signup-account&quot;, effects =&gt; {
  const subject = effects.identity.create({ email, displayName });
  effects.credential.password.set({ subject, password });
  effects.evidence.consume(emailEvidence);
  effects.continuation.consume(ctx.continuation);
});
</code></pre>
<p>The source does not execute those operations. It constructs a typed command program. The HIR might contain:</p>
<pre><code class="language-text">commit &quot;signup-account&quot; {
  %subject = effect identity.create(%email, %displayName)
  effect credential.password.set(%subject, %password)
  effect evidence.consume(%emailEvidence)
  effect continuation.consume(%continuation)
}
</code></pre>
<p>The native committer verifies:</p>
<ul>
<li>the commit operation is allowed in this workflow slot;</li>
<li>the exact effect sequence matches a registered transaction contract;</li>
<li>handles belong to the invocation and generation;</li>
<li>consumed resources are active and not replayed;</li>
<li>all payloads satisfy schemas and sensitivity rules;</li>
<li>the storage transaction is atomic.</li>
</ul>
<p>The compiler can check the shape before runtime, while native code remains authoritative.</p>
<h3 id="141-effect-handlers-without-general-delimited-control">14.1 Effect handlers without general delimited control</h3>
<p>The platform does not need to expose unrestricted algebraic effect handlers to plugin code. Internally, effect compilation techniques such as explicit capability passing or evidence passing are useful implementation models. [KOKA]</p>
<p>For plugin authors, a finite set of project-defined commands is safer and easier to explain. General handlers can remain a trusted language-extension feature.</p>
<h2 id="15-vm-level-nominal-handles">15. VM-level nominal handles</h2>
<p>The current identity-branding technique - blank JavaScript objects stored in Go-side identity maps - is clever and unforgeable within one runtime. A malleable VM can represent the concept directly.</p>
<pre><code class="language-text">HostHandle {
  kind: HandleKind
  id: opaque integer or pointer
  owner: invocation / realm / generation
  lifetime: active | consumed | revoked
  sensitivity: public | restricted | secret
  transfer: nontransferable | borrowable | movable
  durability: never | native-reference-only | serializable
}
</code></pre>
<p>The VM exposes no user-constructible constructor. Property access can be disabled or restricted to safe metadata. The handle participates in equality only according to host policy. Exporting it through JSON, string coercion, reflection, or structured cloning fails.</p>
<p>This removes several layers:</p>
<ul>
<li>no identity side map for every branded object;</li>
<li>no accidental enumeration or prototype behavior;</li>
<li>direct kind checks in opcodes and verifier;</li>
<li>direct lifetime invalidation;</li>
<li>direct sensitivity propagation;</li>
<li>cheaper detection of cross-runtime or cross-generation misuse.</li>
</ul>
<p>WIT's distinction between owned and borrowed resource handles provides a useful interface analogy. A borrow is valid for one call; dropping an owned handle transfers or destroys responsibility. [WIT]</p>
<h2 id="16-affine-secrets-and-evidence">16. Affine secrets and evidence</h2>
<p>Password and evidence handling can become substantially stronger if the language has affine or linear host values.</p>
<p>An affine value may be used at most once; a linear value must be used exactly once. Full linear typing may be too heavy for a JavaScript-facing language, but targeted affine rules are practical:</p>
<pre><code class="language-text">PasswordSecret:
  cannot be copied
  cannot be compared by script
  cannot be converted to string or bytes
  cannot be stored in objects or arrays unless explicitly permitted
  cannot cross durable checkpoints
  cannot be returned
  may be passed to password-policy or commit constructors
  is zeroized or invalidated when invocation ends

EvidenceHandle:
  may be borrowed by policy checks
  must be consumed by an authorized commit or explicitly abandoned
  cannot be forged or serialized by value
</code></pre>
<p>The compiler performs escape analysis. The verifier checks use counts and lifetime regions. The runtime enforces owner and active-state checks.</p>
<p>This permits a useful source style:</p>
<pre><code class="language-typescript">const form = await ctx.browser.present(SignupForm);
// form.password has type Secret&lt;Password&gt;, not string.
const verdict = await ctx.password.policy(form.password.borrow());
if (!verdict.accepted) return ctx.deny(verdict.code);

return ctx.commit.signup({
  public: form.publicFields,
  password: form.password.move(),
  evidence: emailEvidence.move()
});
</code></pre>
<p><code>borrow()</code> and <code>move()</code> can be compiler concepts rather than actual methods. The syntax communicates ownership to authors and reviewers.</p>
<h2 id="17-sensitivity-as-an-information-flow-dimension">17. Sensitivity as an information-flow dimension</h2>
<p>Tiny-IDP already marks sensitive schema fields and forbids them in public continuation carry. A compiler can propagate sensitivity through expressions.</p>
<p>A small lattice is often enough:</p>
<pre><code class="language-text">public &lt;= restricted &lt;= secret
</code></pre>
<p>Operations have flow rules:</p>
<ul>
<li>concatenating a secret with a public string yields secret;</li>
<li>hashing may produce restricted, not automatically public;</li>
<li>a native redaction or tokenization capability may explicitly declassify;</li>
<li>logging accepts only public values unless a trusted sink policy says otherwise;</li>
<li>durable public frames accept only public values;</li>
<li>diagnostics must not format secret values;</li>
<li>exception objects cannot contain restricted or secret payloads.</li>
</ul>
<p>The compiler should report paths, not generic errors:</p>
<pre><code class="language-text">TIDP-SENS-0042: secret value `form.password`
flows into durable checkpoint `signup.email-proof`
through object field `pending.password`.
Move the secret directly into an immediate commit, or redesign the flow so
password entry occurs after the durable challenge.
</code></pre>
<p>This type of diagnostic makes the assurance model usable rather than punitive.</p>
<h1 id="part-v---deterministic-scheduling-and-structured-concurrency">Part V - Deterministic scheduling and structured concurrency</h1>
<h2 id="18-the-hidden-scheduler-problem">18. The hidden scheduler problem</h2>
<p>Goja does not provide a browser or Node event loop. Promise jobs are maintained in a private queue and drained when top-level execution returns normally. Native Promise resolvers are not goroutine-safe; settlement must be routed onto the VM owner. [GOJA-PROMISE]</p>
<p>Tiny-IDP correctly adds an owner and a separate capability settlement tracker. However, the host and VM maintain overlapping notions of asynchronous state:</p>
<pre><code class="language-text">VM: Promise jobs and async runners
Host: pending capability calls and owner queue
Pool: worker safety and replacement state
Context: deadline and cancellation state
</code></pre>
<p>A malleable runtime can unify these into one invocation scheduler.</p>
<h2 id="19-structured-concurrency-as-a-language-rule">19. Structured concurrency as a language rule</h2>
<p>The runtime should not permit detached asynchronous work. Every spawned task belongs to a lexical task region or nursery.</p>
<pre><code class="language-typescript">const result = await ctx.tasks.scope(async scope =&gt; {
  const identity = scope.start(() =&gt; ctx.account.lookup(input.email));
  const invitation = scope.start(() =&gt; ctx.invitation.inspect(input.code));
  return decide(await identity, await invitation);
});
</code></pre>
<p>The scheduler guarantees:</p>
<ul>
<li>child tasks are registered before they execute;</li>
<li>cancellation propagates from parent to children;</li>
<li>the scope cannot exit while children remain active;</li>
<li>unobserved rejection is an invocation error;</li>
<li>capability leases remain valid only inside the owning region;</li>
<li>the worker is reusable only when the root task tree is terminal;</li>
<li>task count and queued-job count are explicit quotas.</li>
</ul>
<p>This replaces the heuristic question &quot;have all Promises probably settled?&quot; with a structural invariant:</p>
<pre><code class="language-text">invocation complete iff
  root task is terminal
  and task tree has no live child
  and job queue is empty
  and no host settlement token is outstanding
</code></pre>
<h3 id="191-deterministic-race-semantics">19.1 Deterministic race semantics</h3>
<p><code>Promise.race</code> and concurrent host completions introduce order sensitivity. A deterministic profile can define tie-breaking:</p>
<ul>
<li>events receive monotonically increasing registration IDs;</li>
<li>host completions are enqueued with recorded logical timestamps;</li>
<li>equal-time events are ordered by registration ID;</li>
<li>cancellation and timeout are represented as scheduled events;</li>
<li>replay uses the recorded event order.</li>
</ul>
<p>Projects that do not require replay may select a nondeterministic scheduler profile, but the choice is explicit and fingerprinted.</p>
<h2 id="20-deterministic-sources">20. Deterministic sources</h2>
<p>Goja already allows custom time and random sources. [GOJA-RUNTIME] A controlled runtime should go further:</p>
<ul>
<li><code>Date.now</code>, <code>new Date</code>, and timers read a logical clock;</li>
<li>randomness comes from a seeded or recorded capability;</li>
<li>locale, timezone, collation, and Unicode data versions are fixed by the artifact;</li>
<li>module resolution is closed and canonical;</li>
<li>host-call results are classified as deterministic, recorded, native-evidence, or forbidden during replay;</li>
<li>enumeration order and canonical encoding are specified;</li>
<li>concurrency ordering is scheduler-defined;</li>
<li>diagnostics and traces use stable IDs.</li>
</ul>
<p>SES compartments omit ambient time and randomness by default because they can reveal authority and act as communication channels; powers are added explicitly. [SES] The same deny-by-default principle fits assured plugins.</p>
<h2 id="21-replay-as-an-optional-execution-mode">21. Replay as an optional execution mode</h2>
<p>Tiny-IDP's explicit continuations do not require replaying a whole workflow from its beginning. That is a strength. Still, deterministic traces are valuable for debugging, migration testing, and audit.</p>
<p>A trace could contain:</p>
<pre><code class="language-text">InvocationStart {
  artifact, profile, handler, input_digest, budgets
}
HostCallRequested { seq, capability, input_digest, cost }
HostCallSettled   { seq, result_digest, classification }
CheckpointCreated { checkpoint, frame_digest, revision }
OutcomeReturned   { kind, value_digest }
InvocationEnd     { fuel_used, peak_heap, task_count }
</code></pre>
<p>Sensitive values are not recorded directly. The trace records hashes, stable codes, or encrypted audit payloads under native policy.</p>
<p>Temporal demonstrates one durable execution model: deterministic workflow code is replayed from an event-sourced history, while side effects are separated into activities. [TEMPORAL] Tiny-IDP need not adopt full replay, but it can borrow three ideas:</p>
<ul>
<li>classify and record nondeterminism;</li>
<li>validate new code against historical traces;</li>
<li>pin version decisions so old executions retain old meaning.</li>
</ul>
<h3 id="211-three-distinct-determinisms">21.1 Three distinct determinisms</h3>
<p>The report uses three terms separately:</p>
<ol>
<li><strong>Compilation determinism</strong>: the same source, compiler, profile, and dependencies produce the same bundle.</li>
<li><strong>Execution determinism</strong>: the same bundle and same sequence of host results produce the same trace and outcome.</li>
<li><strong>Replay compatibility</strong>: a newer bundle can consume an older recorded history or continuation without semantic divergence.</li>
</ol>
<p>A system may provide the first two without the third. Hot-reload policy must say which guarantee applies.</p>
<h1 id="part-vi---exact-resource-control">Part VI - Exact resource control</h1>
<h2 id="22-from-timeout-to-a-multidimensional-budget">22. From timeout to a multidimensional budget</h2>
<p>Wall-clock timeouts are necessary but insufficient. They are nondeterministic, depend on machine load, and do not distinguish computation from blocked host work. A malleable runtime can enforce a budget vector:</p>
<pre><code class="language-text">Budget {
  instruction_fuel
  host_call_cost
  wall_deadline
  call_stack_depth
  heap_bytes
  object_count
  property_count
  string_bytes
  array_elements
  microtask_count
  live_task_count
  pending_host_calls
  output_bytes
  continuation_frame_bytes
  trace_bytes
}
</code></pre>
<h3 id="221-instruction-fuel">22.1 Instruction fuel</h3>
<p>Goja's dispatch loop has a central instruction fetch and <code>exec</code> call. A fork can charge fuel before each instruction or at basic-block entries. [GOJA-VM]</p>
<p>A cost model should distinguish:</p>
<ul>
<li>simple stack and arithmetic instructions;</li>
<li>property lookup and prototype traversal;</li>
<li>regular expressions;</li>
<li>string and BigInt operations proportional to input size;</li>
<li>JSON parsing and encoding;</li>
<li>array growth and sorting;</li>
<li>host calls with profile-defined costs.</li>
</ul>
<p>A deterministic fuel budget gives reproducible failure. A wall deadline remains a secondary safety net for expensive native operations or runtime bugs.</p>
<p>Wasmtime makes the same distinction: fuel can deterministically bound execution, while epoch interruption is coarser and nondeterministic; resource limiters cover memory-like resources separately. [WASMTIME]</p>
<h3 id="222-safe-points-and-cancellation">22.2 Safe points and cancellation</h3>
<p>The interpreter should check:</p>
<ul>
<li>fuel;</li>
<li>cancellation epoch;</li>
<li>wall deadline;</li>
<li>pending memory limit;</li>
<li>debugger or trace requests;</li>
</ul>
<p>at specified safe points. A safe point can occur per instruction in the interpreter and less frequently in optimized backends. Long-running built-ins must cooperate by charging work or polling safe points internally.</p>
<h3 id="223-memory-accounting">22.3 Memory accounting</h3>
<p>Strict per-runtime memory limits are harder in Goja because values are ordinary Go allocations managed by the Go garbage collector. A small fork can implement logical accounting at object, string, backing-store, map, array, and Promise creation, but it will not perfectly attribute runtime overhead.</p>
<p>There are three levels:</p>
<ol>
<li><strong>Logical quota</strong>: count semantically relevant allocations and container growth. Cheap and useful, but approximate.</li>
<li><strong>Dedicated heap layer</strong>: store guest objects in an interpreter-owned heap with explicit sizes and tracing. More work, more precise.</li>
<li><strong>Process isolation</strong>: enforce operating-system memory limits around the runtime. Strongest availability boundary for hostile code.</li>
</ol>
<p>QuickJS illustrates what a runtime-owned heap can expose: explicit memory limits, stack limits, interrupt handlers, custom allocation, and opaque native classes. It is a useful design comparison, although its serialized bytecode is engine-version dependent and should not be treated as a stable untrusted format. [QUICKJS]</p>
<h3 id="224-failure-classification">22.4 Failure classification</h3>
<p>Resource exhaustion must be a stable native error family:</p>
<pre><code class="language-text">FuelExhausted
WallDeadlineExceeded
HeapLimitExceeded
StackLimitExceeded
MicrotaskLimitExceeded
HostCallBudgetExceeded
OutputLimitExceeded
ContinuationFrameLimitExceeded
</code></pre>
<p>It must never be reinterpreted as a policy denial or skip. The worker's reuse policy can depend on whether the runtime reached a known clean safe point.</p>
<h1 id="part-vii---hot-reload-generations-and-migration">Part VII - Hot reload, generations, and migration</h1>
<h2 id="23-semantic-generation-identity">23. Semantic generation identity</h2>
<p>Tiny-IDP currently fingerprints source, program IR, callbacks, and schemas, and pins continuations to program identity. A compiler-owned bundle can make the identity more complete:</p>
<pre><code class="language-text">ArtifactIdentity = hash(
  source tree,
  dependency lock,
  frontend version,
  extension set,
  host profile,
  HIR schema,
  Core IR,
  verifier version,
  backend version,
  cost model,
  Unicode/locale data,
  generated bindings
)
</code></pre>
<p>Not every component needs to invalidate every kind of state. The artifact should expose both a full digest and semantic sub-digests:</p>
<ul>
<li>executable digest;</li>
<li>workflow graph digest;</li>
<li>checkpoint schema digest;</li>
<li>capability/effect contract digest;</li>
<li>UI descriptor digest;</li>
<li>cost-model digest.</li>
</ul>
<p>This enables precise compatibility decisions.</p>
<h2 id="24-compile-time-continuation-compatibility">24. Compile-time continuation compatibility</h2>
<p>Given old and new bundles, a migration checker can compare every live checkpoint:</p>
<pre><code class="language-text">old checkpoint ID exists in new bundle
old resume event type is accepted
old frame schema is readable by new handler or has a migration
new handler does not require unavailable capabilities
new handler's effect authority is not silently broader
native reference kinds remain compatible
expiry and replay rules remain valid
</code></pre>
<p>Compatibility can be classified:</p>
<ul>
<li><code>identical</code>: resume directly;</li>
<li><code>backward-compatible</code>: resume under new code after schema validation;</li>
<li><code>requires-migration</code>: execute named pure migration;</li>
<li><code>retain-old-generation</code>: old runtime must remain available;</li>
<li><code>revoke</code>: continuation cannot safely proceed.</li>
</ul>
<h3 id="241-pure-migration-functions">24.1 Pure migration functions</h3>
<p>A migration function should run in a stricter profile:</p>
<pre><code class="language-typescript">export const migrateCollectFormV1toV2 = migration({
  from: &quot;signup.collect-form@1&quot;,
  to: &quot;signup.collect-form@2&quot;
}, old =&gt; ({
  email: old.email,
  displayName: old.displayName,
  marketingConsent: false
}));
</code></pre>
<p>It receives only old public frame data, has no capabilities or nondeterminism, and produces the new frame schema. The compiler can prove termination only for a restricted language or enforce a small fuel budget.</p>
<h3 id="242-stable-ids-as-part-of-source-design">24.2 Stable IDs as part of source design</h3>
<p>Callback and checkpoint IDs should be explicit public API, like database schema names. Refactoring tools must preserve them unless the author intentionally creates a migration boundary.</p>
<p>This changes plugin development practice: source names are not just local implementation details; some are durable protocol names.</p>
<h1 id="part-viii---new-patterns-for-plugin-authors">Part VIII - New patterns for plugin authors</h1>
<h2 id="25-typed-workflow-modules-instead-of-registration-side-effects">25. Typed workflow modules instead of registration side effects</h2>
<p>Current callback registration requires executing trusted top-level JavaScript in every runtime. A compiler can extract and generate the registry without evaluating arbitrary initialization code.</p>
<p>Source:</p>
<pre><code class="language-typescript">export const submitted = handler({
  id: &quot;signup.submitted&quot;,
  input: SignupPost,
  output: SignupDecision
}, async ctx =&gt; { /* ... */ });
</code></pre>
<p>Generated manifest:</p>
<pre><code class="language-json">{
  &quot;callbacks&quot;: [{
    &quot;id&quot;: &quot;signup.submitted&quot;,
    &quot;symbol&quot;: &quot;module/signup.ts#submitted&quot;,
    &quot;input&quot;: &quot;SignupPost&quot;,
    &quot;output&quot;: &quot;SignupDecision&quot;,
    &quot;capabilities&quot;: [&quot;account.lookup@1&quot;],
    &quot;outcomes&quot;: [&quot;deny&quot;, &quot;challenge&quot;, &quot;error&quot;],
    &quot;fuel&quot;: 30000
  }]
}
</code></pre>
<p>The runtime links a compile-time function index to the VM-local closure. It no longer discovers the program by top-level collector side effects. Re-execution fingerprint checks can remain as defense in depth for the Goja backend.</p>
<h2 id="26-exhaustive-outcome-handling">26. Exhaustive outcome handling</h2>
<p>A typed <code>match</code> prevents accidental fallthrough among denial, skip, and error:</p>
<pre><code class="language-typescript">return match(candidate, {
  found: value =&gt; ctx.complete.identity(value),
  notFound: () =&gt; ctx.skip(&quot;not_found&quot;),
  disabled: reason =&gt; ctx.deny(reason),
  error: err =&gt; ctx.error(err.code)
});
</code></pre>
<p>The compiler checks exhaustiveness and that the lambda's declared outcome row contains every branch. In a custom dialect, this may use a dedicated <code>match</code> form. In compatible TypeScript, generated discriminated unions and a compiler plugin can provide the same semantics.</p>
<h2 id="27-capability-polymorphic-helpers">27. Capability-polymorphic helpers</h2>
<p>Helpers should be parameterized by exact authority:</p>
<pre><code class="language-typescript">async function findEligibleMember&lt;C extends LookupMember &amp; ReadPolicy&gt;(
  cap: C,
  email: EmailAddress
): Promise&lt;Option&lt;Member&gt;&gt; requires C {
  const member = await cap.lookup(email);
  if (!member) return none;
  return (await cap.policy(member)).eligible ? some(member) : none;
}
</code></pre>
<p>The helper can be tested with a pure model capability, executed with a production capability, or symbolically interpreted. It cannot accidentally call mail, database, or commit APIs because those references are absent from its capability environment.</p>
<h2 id="28-deterministic-nurseries">28. Deterministic nurseries</h2>
<p>Plugin authors can perform bounded parallel reads without leaking work:</p>
<pre><code class="language-typescript">const [member, invite] = await ctx.tasks.all({
  member: () =&gt; ctx.member.lookup(email),
  invite: () =&gt; ctx.invite.inspect(code)
}, { concurrency: 2, cancelOnError: true });
</code></pre>
<p>The profile gives <code>tasks.all</code> deterministic key order, exact call and task costs, and cancellation semantics.</p>
<h2 id="29-recorded-nondeterminism">29. Recorded nondeterminism</h2>
<p>A workflow that genuinely needs randomness or current time uses an explicit operation:</p>
<pre><code class="language-typescript">const bucket = await ctx.nondeterminism.recorded(
  &quot;signup-experiment-bucket&quot;,
  source =&gt; source.randomInt(0, 99)
);
</code></pre>
<p>The result is captured in the invocation trace or durable history. Replay returns the recorded value. A reviewer can search all nondeterminism sites.</p>
<h2 id="30-effect-oriented-transactions">30. Effect-oriented transactions</h2>
<p>Plugins can define named transaction constructors while native code owns execution:</p>
<pre><code class="language-typescript">const signupCommit = defineCommit(&quot;signup.account@2&quot;, effects =&gt; ({
  input: SignupCommitInput,
  build(input) {
    const subject = effects.identity.create(input.profile);
    effects.credential.password.set(subject, input.password.move());
    effects.evidence.consume(input.emailEvidence.move());
    effects.session.establish(subject);
  }
}));
</code></pre>
<p>The constructor is compiled into a finite effect template. A native committer can require the exact template ID rather than accepting an arbitrary sequence.</p>
<h2 id="31-local-simulation-and-explanation">31. Local simulation and explanation</h2>
<p>Because host calls and outcomes are typed, a generated test harness can run a handler with model capabilities:</p>
<pre><code class="language-typescript">const result = await simulate(signup, {
  input: fixtures.validSignup,
  capabilities: {
    &quot;account.lookup@1&quot;: model.returning(null),
    &quot;challenge.email@1&quot;: model.verified(&quot;evidence-1&quot;)
  },
  schedule: &quot;deterministic&quot;,
  fuel: 80000
});

expect(result.outcome).toEqual(&quot;commit&quot;);
expect(result.effects).toMatchTemplate(&quot;signup.account@2&quot;);
expect(result.authorityUsed).toEqual([
  &quot;account.lookup@1&quot;, &quot;challenge.email@1&quot;
]);
</code></pre>
<p>The same trace supports an explanation view:</p>
<pre><code class="language-text">signup.submitted denied with account_exists
because account.lookup@1 returned an active candidate.
No commit effects were proposed.
Fuel used: 2,431 / 30,000.
Capabilities used: account.lookup@1 (1 call).
</code></pre>
<p>This is valuable to operators without exposing secret values.</p>
<h1 id="part-ix---new-patterns-for-framework-implementers">Part IX - New patterns for framework implementers</h1>
<h2 id="32-generated-boundary-code">32. Generated boundary code</h2>
<p>A profile compiler can generate:</p>
<ul>
<li>TypeScript declarations and editor documentation;</li>
<li>Go capability dispatch tables;</li>
<li>schema codecs and validators;</li>
<li>nominal handle kind tables;</li>
<li>outcome decoders;</li>
<li>effect template validators;</li>
<li>trace event definitions;</li>
<li>conformance fixtures;</li>
<li>documentation pages;</li>
<li>source-map and diagnostic registries.</li>
</ul>
<p>This removes handwritten drift between JavaScript APIs and Go validation.</p>
<h2 id="33-an-interpreter-independent-invocation-kernel">33. An interpreter-independent invocation kernel</h2>
<p>The framework should define one backend-neutral contract:</p>
<pre><code class="language-go">type Engine interface {
    Load(ctx context.Context, bundle Bundle, profile HostProfile) (Image, error)
    NewRealm(ctx context.Context, image Image, limits Limits) (Realm, error)
    Invoke(ctx context.Context, realm Realm, request Invocation) (Result, error)
    CloseRealm(ctx context.Context, realm Realm) error
}
</code></pre>
<p>The <code>Invocation</code> contains only profile-defined values and capability tokens. The <code>Result</code> contains one verified outcome plus execution metrics and trace events. Goja-specific types never appear in this interface.</p>
<p>Backends can include:</p>
<ul>
<li><code>gojaengine</code>: executes lowered code in Goja;</li>
<li><code>corevm</code>: interprets verified Core IR;</li>
<li><code>symbolic</code>: explores branches over abstract capability results;</li>
<li><code>staticgo</code>: generates Go for selected high-assurance deployments;</li>
<li><code>wasmengine</code>: executes a Component Model artifact with typed imports.</li>
</ul>
<p>This architecture prevents the compiler project from becoming a Tiny-IDP package.</p>
<h2 id="34-realm-images-and-state-hygiene">34. Realm images and state hygiene</h2>
<p>Stock Tiny-IDP reuses workers after careful cleanup. A malleable engine can provide stronger realm semantics:</p>
<ul>
<li>immutable base image for built-ins and compiled modules;</li>
<li>per-invocation overlay for globals and module state;</li>
<li>copy-on-write or template cloning;</li>
<li>explicit root set for host handles;</li>
<li>deterministic destruction at invocation end;</li>
<li>no cross-invocation module mutation unless a profile permits it.</li>
</ul>
<p>This eliminates a residual class of bugs in which ordinary module state survives worker reuse. It may also make fresh realms cheap enough to prefer creation over cleanup.</p>
<h2 id="35-first-class-invariant-monitors">35. First-class invariant monitors</h2>
<p>The runtime can expose invariant hooks that are impossible to fake from script:</p>
<pre><code class="language-text">onCapabilityCall
onHandleMove
onHandleBorrow
onCheckpoint
onEffectPlan
onTaskSpawn
onTaskComplete
onAllocation
onOutcome
onTrap
</code></pre>
<p>A profile installs monitors such as:</p>
<ul>
<li>no secret live at checkpoint;</li>
<li>no active capability after invocation end;</li>
<li>no effect outside declared transaction template;</li>
<li>no unresolved task at worker release;</li>
<li>every consumed evidence handle is consumed once;</li>
<li>output authority does not exceed input authority;</li>
<li>every host result is classified for replay.</li>
</ul>
<p>Monitors provide runtime defense in depth even when static analysis is incomplete.</p>
<h2 id="36-model-checking-finite-workflow-structure">36. Model checking finite workflow structure</h2>
<p>The compiled workflow graph is finite even when callback computations are dynamic. A symbolic backend can abstract capability results into finite variants and explore:</p>
<ul>
<li>every outcome path;</li>
<li>reachability of commit;</li>
<li>denial versus skip confusion;</li>
<li>replay and duplicate submission paths;</li>
<li>whether all presentations have legal resume handlers;</li>
<li>whether every evidence path consumes or abandons evidence;</li>
<li>whether sensitive fields can reach public frames;</li>
<li>whether a workflow can loop without decreasing a budget or revision.</li>
</ul>
<p>The output can be a counterexample trace using source labels.</p>
<h2 id="37-policy-diffing">37. Policy diffing</h2>
<p>Because bundles contain inferred authority and effect manifests, deployment tooling can compare versions:</p>
<pre><code class="language-text">signup v17 -&gt; v18
  added capability: risk.score@1
  removed capability: invite.lookup@1
  added commit effect: audit.security-event
  checkpoint signup.collect-form frame changed compatibly
  checkpoint signup.verify-email unchanged
  maximum fuel increased 80,000 -&gt; 95,000
  nondeterminism sites unchanged
</code></pre>
<p>This makes code review focus on semantic change rather than only text change.</p>
<h1 id="part-x---extensibility-across-projects">Part X - Extensibility across projects</h1>
<h2 id="38-extension-layers">38. Extension layers</h2>
<p>A malleable platform needs a trust hierarchy. &quot;Extensible compiler&quot; must not mean arbitrary plugins can mutate bytecode after verification.</p>
<h3 id="tier-0---libraries-and-combinators">Tier 0 - libraries and combinators</h3>
<p>Ordinary source libraries built from existing profile operations. They add no authority and require no compiler trust.</p>
<p>Examples:</p>
<ul>
<li>workflow combinators;</li>
<li>schema helpers;</li>
<li>pure validation functions;</li>
<li>finite decision tables.</li>
</ul>
<h3 id="tier-1---checked-source-extensions">Tier 1 - checked source extensions</h3>
<p>Macros or elaborators produce ordinary HIR plus provenance. Their output is re-typechecked, re-effect-checked, and verified. The extension cannot create privileged opcodes or suppress diagnostics.</p>
<p>Examples:</p>
<ul>
<li>a decision-table syntax;</li>
<li>a form-definition DSL;</li>
<li>a retry combinator that lowers to structured tasks;</li>
<li>a policy rule language.</li>
</ul>
<h3 id="tier-2---trusted-profile-extensions">Tier 2 - trusted profile extensions</h3>
<p>A project adds value types, capabilities, effects, handle kinds, native bindings, and verifier rules. This changes the host profile and enters the project's trusted computing base.</p>
<p>Examples:</p>
<ul>
<li>Tiny-IDP password evidence;</li>
<li>deployment-engine cluster handles;</li>
<li>document-engine signing capabilities.</li>
</ul>
<h3 id="tier-3---trusted-language-extensions">Tier 3 - trusted language extensions</h3>
<p>A language package changes parsing, core typing, lowering, or runtime opcodes. It must version and fingerprint the semantic profile and may require new proofs or conformance suites.</p>
<p>Examples:</p>
<ul>
<li>durable async syntax;</li>
<li>a new ownership mode;</li>
<li>a general effect-handler feature;</li>
<li>SIMD or decimal arithmetic.</li>
</ul>
<h3 id="tier-4---backend-extensions">Tier 4 - backend extensions</h3>
<p>A new execution backend must demonstrate conformance to Core IR semantics and host-profile behavior. Differential tests and translation validation are mandatory before production use.</p>
<h2 id="39-extension-capsules">39. Extension capsules</h2>
<p>Every extension should be a signed, versioned capsule:</p>
<pre><code class="language-text">ExtensionCapsule {
  extension_id
  semantic_version
  compiler_api_version
  declared phases
  input_ir_versions
  output_ir_versions
  added syntax
  added profile entries
  proof/checker modules
  deterministic digest
  source-map policy
  conformance tests
  signer
}
</code></pre>
<p>The artifact records the exact extension set. Loading fails if the runtime or verifier cannot identify it.</p>
<h2 id="40-no-arbitrary-bytecode-mutators">40. No arbitrary bytecode mutators</h2>
<p>The extension API should follow one rule:</p>
<blockquote>
<p>Untrusted extensions may generate or transform typed HIR, but only the trusted backend lowers verified Core IR to executable form.</p>
</blockquote>
<p>This preserves a single assurance bottleneck. It resembles the value of an eBPF verifier: programs may be produced by varied frontends, but they enter the kernel only after a finite verifier establishes required safety properties. The Linux verifier tracks abstract register and stack state and enforces ownership-like obligations for reference-counted kernel pointers. [EBPF]</p>
<h2 id="41-language-workbenches-versus-one-off-forks">41. Language workbenches versus one-off forks</h2>
<p>Racket demonstrates language-oriented programming through reader, expander, module, and tooling layers. Truffle demonstrates reusable language and tooling infrastructure around instrumentable AST interpreters. Nanopass demonstrates compiler construction through many small explicit passes. [RACKET] [TRUFFLE] [NANOPASS]</p>
<p>The proposed platform should borrow selectively:</p>
<ul>
<li>from Racket: explicit language/profile identity and phase separation;</li>
<li>from Truffle: common instrumentation and tooling APIs across languages;</li>
<li>from Nanopass: small transformations with explicit IR contracts;</li>
<li>from WIT: language-neutral interfaces and resource handles;</li>
<li>from eBPF: a mandatory load-time verifier;</li>
<li>from Wasm: a compact typed core with formal semantics and multiple embeddings;</li>
<li>from capability systems: authority represented by references, not ambient names.</li>
</ul>
<p>It should not attempt to recreate their full ecosystems.</p>
<h2 id="42-example-profiles-beyond-tiny-idp">42. Example profiles beyond Tiny-IDP</h2>
<h3 id="421-deployment-orchestration">42.1 Deployment orchestration</h3>
<p>Capabilities:</p>
<pre><code class="language-text">cluster.read
release.plan
release.apply
approval.request
secret.reference
</code></pre>
<p>Durable operations include approval, timer, rollout observation, and human intervention. Effects are deployment plans applied by native controllers.</p>
<h3 id="422-document-approval-and-signing">42.2 Document approval and signing</h3>
<p>Capabilities:</p>
<pre><code class="language-text">document.read-metadata
review.request
signature.request
archive.commit
</code></pre>
<p>Handles represent documents, signing sessions, and evidence. Secret signing material never enters script.</p>
<h3 id="423-policy-and-entitlement-engine">42.3 Policy and entitlement engine</h3>
<p>Capabilities:</p>
<pre><code class="language-text">directory.lookup
entitlement.read
risk.score
</code></pre>
<p>No durable operations may be enabled. The same compiler can enforce pure or recorded policy evaluation and produce explanations.</p>
<h3 id="424-agent-tool-runtime">42.4 Agent tool runtime</h3>
<p>Capabilities are tools with typed arguments, cost, side-effect class, user-consent requirements, and delegation rules. Structured concurrency and trace replay become especially valuable. The runtime can forbid a tool handle from surviving beyond one agent turn.</p>
<h3 id="425-game-or-simulation-rules">42.5 Game or simulation rules</h3>
<p>A deterministic profile supplies seeded randomness, logical time, bounded state mutations, and replay. The backend may prioritize throughput over secret handling while sharing the same core scheduler and verifier.</p>
<h1 id="part-xi---verification-strategy">Part XI - Verification strategy</h1>
<h2 id="43-do-not-begin-by-proving-javascript">43. Do not begin by proving JavaScript</h2>
<p>Full ECMAScript is a large and evolving language with complex objects, coercions, proxies, iterators, regular expressions, modules, async behavior, and host hooks. Mechanized projects such as JSCert show that a trusted formal specification and a proved reference interpreter are possible, but also illustrate the scale of the work. [JSCERT] KJS similarly demonstrates executable formal semantics tested against Test262. A production project should use this work as guidance, not make full-language proof a prerequisite.</p>
<p>The assurance target should be layered.</p>
<h2 id="44-layer-1---source-conformance-and-rejection">44. Layer 1 - source conformance and rejection</h2>
<p>The frontend defines an assured subset and rejects unsupported constructs:</p>
<ul>
<li><code>eval</code> and <code>Function</code> constructors;</li>
<li>dynamic module loading outside the profile resolver;</li>
<li>proxies if they defeat analysis;</li>
<li>weak references and finalization;</li>
<li>reflective prototype mutation;</li>
<li>detached Promises;</li>
<li>ambient time and randomness;</li>
<li>unbounded regular-expression features if cost cannot be controlled;</li>
<li>dynamic property access on capability namespaces;</li>
<li>values that cross checkpoints without stable types.</li>
</ul>
<p>The subset should be tested against relevant Test262 cases and project-specific negative suites.</p>
<h2 id="45-layer-2---hir-type-effect-and-ownership-checking">45. Layer 2 - HIR type, effect, and ownership checking</h2>
<p>The checker establishes:</p>
<pre><code class="language-text">- all names and host operations resolve;
- every value has a type and sensitivity label;
- capability use is within the authority row;
- commit effects are within the permitted effect row;
- affine handles are not duplicated or leaked;
- durable frames contain only permitted values;
- task regions close structurally;
- outcomes are exhaustive and legal for the slot;
- resource bounds are finite where required.
</code></pre>
<p>The checker should be a small separate module rather than incidental logic spread through the compiler.</p>
<h2 id="46-layer-3---core-ir-verifier">46. Layer 3 - Core IR verifier</h2>
<p>The Core verifier treats the bundle as untrusted input. It validates:</p>
<ul>
<li>binary/structural well-formedness;</li>
<li>control-flow target validity;</li>
<li>SSA or stack discipline;</li>
<li>type consistency at block joins;</li>
<li>handle ownership and lifetime state;</li>
<li>capability and effect opcode permissions;</li>
<li>checkpoint frame schemas;</li>
<li>bounded stack and local counts;</li>
<li>legal exception edges;</li>
<li>cost annotations;</li>
<li>closed outcome construction;</li>
<li>source-map integrity as non-authoritative metadata.</li>
</ul>
<p>A simplified handle-state rule:</p>
<pre><code class="language-text">state(h) = owned(k)
---------------------------------- MOVE
move h transfers h to destination
and sets source state(h) = moved

state(h) = borrowed(k, region r)
current_region &lt;= r
---------------------------------- USE-BORROW
host.call f(..., h, ...)

live_at_checkpoint(h) and durable(k) = false
---------------------------------- CHECKPOINT-REJECT
program is invalid
</code></pre>
<p>The verifier is analogous to eBPF verification in role, not in exact algorithm.</p>
<h2 id="47-layer-4---translation-validation">47. Layer 4 - translation validation</h2>
<p>For difficult compiler passes, generate a certificate or relation checked by a simpler validator:</p>
<ul>
<li>source callback IDs correspond to HIR symbols;</li>
<li>durable lowering preserves control-flow outcomes;</li>
<li>liveness-derived frames contain exactly the required variables;</li>
<li>capability inference matches host-call nodes;</li>
<li>Goja backend code maps each Core host operation to the correct native stub;</li>
<li>Wasm imports match profile signatures.</li>
</ul>
<p>Translation validation reduces the amount of compiler code that must be trusted.</p>
<h2 id="48-layer-5---formal-core-semantics">48. Layer 5 - formal Core semantics</h2>
<p>The Core IR should have a small-step operational semantics covering:</p>
<ul>
<li>pure evaluation;</li>
<li>host-call request and settlement events;</li>
<li>task scheduling;</li>
<li>cancellation;</li>
<li>traps and resource exhaustion;</li>
<li>checkpoint creation;</li>
<li>outcome construction;</li>
<li>handle movement and borrowing;</li>
<li>effect-plan construction.</li>
</ul>
<p>Candidate machine-checked theorems include:</p>
<ol>
<li><strong>Type safety</strong>: a verified program does not get stuck except at explicit host or resource traps.</li>
<li><strong>Authority confinement</strong>: every host event is authorized by a capability in the function's environment and profile.</li>
<li><strong>Effect confinement</strong>: every proposed commit effect belongs to the permitted effect row and transaction template.</li>
<li><strong>Checkpoint secrecy</strong>: durable frames contain no values above their permitted sensitivity and no forbidden handle kinds.</li>
<li><strong>Handle safety</strong>: affine handles are not used after move, consume, or revoke.</li>
<li><strong>Scheduler closure</strong>: a successful invocation result implies no live child task or unresolved settlement remains.</li>
<li><strong>Lowering preservation</strong>: durable-source execution corresponds to generated state-machine execution at observable boundaries.</li>
</ol>
<p>CompCert's lesson is not that every compiler must be fully proved immediately. It is that semantic preservation can be decomposed pass by pass, and that a small formal IR creates a tractable proof boundary. [COMPCERT]</p>
<h2 id="49-layer-6---backend-conformance">49. Layer 6 - backend conformance</h2>
<p>Every backend runs:</p>
<ul>
<li>Core semantic test vectors;</li>
<li>differential tests against a reference interpreter;</li>
<li>property-based generated programs;</li>
<li>fuzzed malformed bundles;</li>
<li>cancellation and race schedules;</li>
<li>resource exhaustion tests;</li>
<li>host-call adversarial tests;</li>
<li>source-map and diagnostic tests.</li>
</ul>
<p>A native Core interpreter should initially be the reference, not the fastest backend. Goja and Wasm outputs are compared to it.</p>
<p>WebAssembly's SpecTec work is instructive: one source can generate rigorous specification material and executable artifacts, and a reference interpreter plus tests can reveal inconsistencies in prose and implementation. [SPECTEC]</p>
<h2 id="50-layer-7---system-level-protocol-assurance">50. Layer 7 - system-level protocol assurance</h2>
<p>Language verification does not prove the IdP correct. Native protocol code, continuation stores, commit transactions, CSRF defenses, replay controls, key management, provider semantics, and HTTP integration remain separate proof and test obligations.</p>
<p>The language platform should make those boundaries sharper, not claim to absorb them.</p>
<h1 id="part-xii---trusted-computing-base-and-threat-model">Part XII - Trusted computing base and threat model</h1>
<h2 id="51-tcb-decomposition">51. TCB decomposition</h2>
<p>A production Tiny-IDP deployment would trust:</p>
<pre><code class="language-text">native OAuth/OIDC and HTTP kernel
continuation store and commit implementations
host profile definitions and native bindings
frontend parser or its validation boundary
HIR checker and Core verifier
selected backend runtime
artifact loader and signature verification
Go runtime and operating system
</code></pre>
<p>Compiler transformation passes can be outside the TCB if their output is fully checked. Source diagnostics and optimizers need not be trusted for safety.</p>
<h2 id="52-trusted-operator-code-versus-hostile-code">52. Trusted operator code versus hostile code</h2>
<p>The current Tiny-IDP design explicitly targets trusted deployment code, not hostile tenant code. Interpreter ownership can support a stronger hostile-code boundary, but it does not automatically provide one.</p>
<p>For hostile code, add:</p>
<ul>
<li>process or OS isolation;</li>
<li>strict memory and CPU limits;</li>
<li>no shared Go heap with protocol secrets;</li>
<li>minimized native bindings;</li>
<li>side-channel analysis;</li>
<li>denial-of-service controls;</li>
<li>dependency and supply-chain policy;</li>
<li>stronger module signing and tenancy separation.</li>
</ul>
<p>SES documentation likewise notes that compartments sharing one agent do not solve memory-exhaustion or availability threats. [SES]</p>
<h2 id="53-fork-risk">53. Fork risk</h2>
<p>A broad Goja fork can become a new monolith in the TCB. The mitigation is organizational and architectural:</p>
<ul>
<li>keep patches small and hook-oriented;</li>
<li>upstream generic hooks where possible;</li>
<li>pin exact commits and run Goja/Test262 conformance continuously;</li>
<li>keep the Core verifier independent of Goja;</li>
<li>avoid encoding Tiny-IDP concepts directly in Goja packages;</li>
<li>make every fork-dependent feature optional behind an engine interface;</li>
<li>maintain differential tests against unmodified Goja for ordinary semantics.</li>
</ul>
<h1 id="part-xiii---decision-analysis">Part XIII - Decision analysis</h1>
<h2 id="54-option-comparison">54. Option comparison</h2>
<table>
<thead>
<tr>
<th>Option</th>
<th align="right">Usability</th>
<th align="right">Assurance gain</th>
<th align="right">Maintenance</th>
<th align="right">Portability</th>
<th>Recommendation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Continue host-only Goja wrapper</td>
<td align="right">Medium</td>
<td align="right">Medium</td>
<td align="right">Low</td>
<td align="right">Medium</td>
<td>Maintain as baseline</td>
</tr>
<tr>
<td>Add AST analysis and generated manifests</td>
<td align="right">High</td>
<td align="right">High</td>
<td align="right">Low-medium</td>
<td align="right">High</td>
<td>Begin here</td>
</tr>
<tr>
<td>Thin Goja hook fork</td>
<td align="right">High</td>
<td align="right">High for metering/scheduler</td>
<td align="right">Medium</td>
<td align="right">Medium</td>
<td>Recommended after frontend</td>
</tr>
<tr>
<td>Own Assured Core interpreter</td>
<td align="right">High for supported subset</td>
<td align="right">Very high</td>
<td align="right">Medium-high</td>
<td align="right">High</td>
<td>Strategic target</td>
</tr>
<tr>
<td>Compile Core IR to Wasm</td>
<td align="right">Medium-high</td>
<td align="right">High</td>
<td align="right">Medium-high</td>
<td align="right">Very high</td>
<td>Optional backend</td>
</tr>
<tr>
<td>Replace Goja with QuickJS</td>
<td align="right">Similar author experience</td>
<td align="right">Better memory hooks, worse Go integration</td>
<td align="right">Medium-high</td>
<td align="right">Medium</td>
<td>Useful comparison, not primary path</td>
</tr>
<tr>
<td>Build full ECMAScript engine</td>
<td align="right">Potentially high</td>
<td align="right">Depends on implementation maturity</td>
<td align="right">Extreme</td>
<td align="right">Low initially</td>
<td>Do not start here</td>
</tr>
</tbody>
</table>
<h2 id="55-what-a-thin-goja-fork-should-expose">55. What a thin Goja fork should expose</h2>
<p>A disciplined hook proposal could include:</p>
<pre><code class="language-go">type ExecutionObserver interface {
    BeforeInstruction(pc int, opcode Opcode, cost uint64) error
    AfterInstruction(pc int)
    OnJobEnqueue(job JobInfo) error
    OnJobStart(job JobInfo)
    OnJobEnd(job JobInfo, result JobResult)
    OnAllocate(kind AllocationKind, bytes int64) error
    OnHostValueCreate(info HostValueInfo) error
}

type RuntimePolicy struct {
    Clock             Now
    Random            RandSource
    Observer          ExecutionObserver
    JobScheduler      JobScheduler
    HostValueRegistry HostValueRegistry
    RealmPolicy       RealmPolicy
}
</code></pre>
<p>The exact API would evolve, but the principle is stable: generic embedding hooks belong in Goja; Tiny-IDP-specific capability and workflow semantics belong above them.</p>
<h3 id="551-high-value-first-hooks">55.1 High-value first hooks</h3>
<ol>
<li>Instruction/basic-block fuel callback.</li>
<li>Promise job enqueue/dequeue and pending-job count.</li>
<li>Async runner/task lifecycle events.</li>
<li>VM-owned opaque host value with kind and finalizer hooks.</li>
<li>Allocation accounting for major guest structures.</li>
<li>Deterministic realm reset or clone API.</li>
<li>Read-only compiled program inspection with stable opcode metadata.</li>
<li>Compiler callback for source span and semantic annotation propagation.</li>
</ol>
<h2 id="56-what-not-to-put-in-goja">56. What not to put in Goja</h2>
<p>Do not add:</p>
<ul>
<li>Tiny-IDP outcome enums;</li>
<li>password or evidence concepts;</li>
<li>OAuth-specific opcodes;</li>
<li>continuation database formats;</li>
<li>SQL transaction semantics;</li>
<li>project-specific schemas;</li>
<li>arbitrary compiler plugin execution inside the VM.</li>
</ul>
<p>Those belong in profiles, HIR, verifier rules, and native bindings.</p>
<h1 id="part-xiv---recommended-roadmap">Part XIV - Recommended roadmap</h1>
<h2 id="57-phase-0---preserve-and-measure-the-baseline">57. Phase 0 - preserve and measure the baseline</h2>
<p>Before changing semantics:</p>
<ul>
<li>keep the existing runtime factory, owner, pool, capability bridge, and continuation model as the reference behavior;</li>
<li>add complete invocation traces and metrics around current Goja;</li>
<li>construct conformance fixtures for every outcome, capability, continuation, cancellation, and worker-disposal path;</li>
<li>record performance and failure behavior.</li>
</ul>
<p>Deliverable: a reference test corpus independent of implementation internals.</p>
<h2 id="58-phase-1---compiler-frontend-above-public-goja">58. Phase 1 - compiler frontend above public Goja</h2>
<p>Use Goja's public <code>Parse</code> and <code>CompileAST</code> seam. The parser and AST are documented as works in progress, so isolate them behind an internal adapter. [GOJA-PARSER]</p>
<p>Build:</p>
<ul>
<li>module normalization;</li>
<li>stable symbol and callback IDs;</li>
<li>project API recognition;</li>
<li>source-level capability/effect inference;</li>
<li>unsupported-feature checks;</li>
<li>deterministic manifest generation;</li>
<li>source maps and diagnostics;</li>
<li>compile-time workflow graph extraction;</li>
<li>generated TypeScript declarations and Go binding tables.</li>
</ul>
<p>Continue executing through stock Goja. Compare generated manifests to current dynamic collector output.</p>
<p>Deliverable: deterministic compile artifacts without a runtime fork.</p>
<h2 id="59-phase-2---durable-lowering">59. Phase 2 - durable lowering</h2>
<p>Add:</p>
<ul>
<li>nominal durable-operation types;</li>
<li>explicit checkpoint annotations;</li>
<li>liveness analysis;</li>
<li>sensitivity and handle escape checks;</li>
<li>state-machine generation;</li>
<li>continuation-frame schemas;</li>
<li>migration metadata;</li>
<li>source-to-generated-handler mapping.</li>
</ul>
<p>Execute generated handlers through the current Tiny-IDP runtime. The native continuation record remains authoritative.</p>
<p>Deliverable: direct-style durable workflow authoring with no VM serialization.</p>
<h2 id="60-phase-3---thin-goja-hook-layer">60. Phase 3 - thin Goja hook layer</h2>
<p>Implement or upstream:</p>
<ul>
<li>deterministic fuel;</li>
<li>job/task lifecycle observation;</li>
<li>exact invocation scheduler integration;</li>
<li>opaque host values;</li>
<li>logical allocation quotas;</li>
<li>realm state controls;</li>
<li>program inspection.</li>
</ul>
<p>Replace Promise polling and parallel settlement inference with scheduler-owned completion. Keep fail-stop worker disposal as defense in depth.</p>
<p>Deliverable: stronger runtime invariants and better operational diagnostics.</p>
<h2 id="61-phase-4---core-ir-and-verifier">61. Phase 4 - Core IR and verifier</h2>
<p>Define a versioned binary and textual Core IR. Implement:</p>
<ul>
<li>reference interpreter;</li>
<li>load-time verifier;</li>
<li>profile linker;</li>
<li>deterministic scheduler;</li>
<li>host-handle table;</li>
<li>trace format;</li>
<li>differential tests against Goja backend.</li>
</ul>
<p>Initially compile only a narrow subset. Unsupported functions continue through the Goja backend if the profile permits a mixed bundle, but durable and high-assurance handlers should prefer Core IR.</p>
<p>Deliverable: interpreter-independent assured execution.</p>
<h2 id="62-phase-5---reusable-platform-extraction">62. Phase 5 - reusable platform extraction</h2>
<p>Move generic components into project-neutral modules:</p>
<pre><code class="language-text">mjs/frontend
mjs/hir
mjs/coreir
mjs/verifier
mjs/runtime
mjs/profile
mjs/backend/goja
mjs/backend/corevm
mjs/testing
mjs/lsp
</code></pre>
<p>Keep Tiny-IDP in:</p>
<pre><code class="language-text">profiles/tinyidp
bindings/tinyidp-go
packages/tinyidp-js
</code></pre>
<p>Pilot a second profile before freezing extension APIs. A deployment or document-approval workflow is a better validation than another identity use case.</p>
<h2 id="63-phase-6---selective-mechanization">63. Phase 6 - selective mechanization</h2>
<p>Formalize:</p>
<ul>
<li>Core IR typing and small-step semantics;</li>
<li>capability/effect confinement;</li>
<li>checkpoint secrecy;</li>
<li>handle lifetime safety;</li>
<li>selected durable-lowering rules.</li>
</ul>
<p>Use the formal model to generate or validate executable test vectors. Mechanize one critical compiler pass or verifier property at a time.</p>
<p>Deliverable: meaningful machine-checked assurance without attempting a full JavaScript proof.</p>
<h1 id="part-xv---critical-limitations-and-open-questions">Part XV - Critical limitations and open questions</h1>
<h2 id="64-javascript-dynamism-versus-static-assurance">64. JavaScript dynamism versus static assurance</h2>
<p>Dynamic property access, prototype mutation, proxies, reflection, coercion, and higher-order callbacks complicate effect and authority inference. The platform must choose among:</p>
<ul>
<li>reject them in assured code;</li>
<li>permit them only in pure regions;</li>
<li>conservatively widen authority and effects;</li>
<li>lower them to a dynamic boundary with runtime checks;</li>
<li>execute them only in the general Goja backend.</li>
</ul>
<p>A mixed system needs visible boundary markers. Silent fallback would undermine review.</p>
<h2 id="65-memory-accounting-in-go">65. Memory accounting in Go</h2>
<p>A Goja fork cannot obtain perfect per-realm memory isolation while guest values share the Go heap. Logical accounting is still useful, but hostile multi-tenant execution requires process isolation or an interpreter-owned heap.</p>
<h2 id="66-stable-semantics-across-engine-upgrades">66. Stable semantics across engine upgrades</h2>
<p>Even with a stable Core IR, JavaScript frontend semantics can change with parser, Unicode, regular-expression, or standard-library upgrades. Artifacts must pin semantic dependencies, and compatibility tests must include source-level edge cases.</p>
<h2 id="67-cost-model-stability">67. Cost-model stability</h2>
<p>Fuel is deterministic only relative to a cost model and compiler version. Optimizations may change instruction counts. Budgets should be attached to semantic operations where possible and versioned with the artifact. Deployment tooling should show budget deltas.</p>
<h2 id="68-migration-policy-is-a-product-decision">68. Migration policy is a product decision</h2>
<p>Automatic migration is not always safer than retaining old generations. Identity workflows may prefer exact-generation resumption for high-risk steps and migration for low-risk presentation changes. The compiler can classify compatibility, but native policy decides.</p>
<h2 id="69-extensibility-can-destroy-compositionality">69. Extensibility can destroy compositionality</h2>
<p>A compiler that lets extensions rewrite arbitrary trees, inspect unrelated modules, or introduce hidden authority becomes difficult to reason about. Phase separation, hygienic source provenance, restricted extension APIs, post-expansion checking, and a single Core verifier are mandatory.</p>
<h2 id="70-performance">70. Performance</h2>
<p>A custom reference interpreter will likely be slower than Goja. That is acceptable initially if high-assurance handlers are short and host-call dominated. Performance work should follow profiles and traces, not precede semantic stability.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Having access to Goja's interpreter would materially improve Tiny-IDP, but the most important improvements are not JavaScript syntax features. They are semantic hooks:</p>
<ul>
<li>exact execution and memory accounting;</li>
<li>an owned deterministic scheduler;</li>
<li>VM-level nominal handles and lifetimes;</li>
<li>inspectable compiled programs;</li>
<li>compiler-propagated source identity;</li>
<li>clean realm lifecycle;</li>
<li>first-class traces and invariant monitors.</li>
</ul>
<p>Creating a complete JavaScript engine would provide maximum control but is not the efficient first move. The higher-leverage design is a malleable compiler platform with a JavaScript-compatible frontend, a typed and effect-aware HIR, compiler-lowered explicit continuations, a small verified Core IR, a load-time verifier, and multiple execution backends.</p>
<p>For Tiny-IDP, this would make the current rigorous architecture more usable without weakening it. Plugin authors could write direct-style durable workflows, receive precise authority and secrecy diagnostics, use structured concurrency, and test against model capabilities. Framework authors could replace dynamic registration discovery with generated manifests, unify async settlement with the scheduler, enforce deterministic fuel and handle lifetimes, check migrations, and model-check finite workflow structure.</p>
<p>Across projects, the host-profile abstraction is the decisive generalization. It turns &quot;a Tiny-IDP Goja fork&quot; into a reusable embedded-language workbench where each domain supplies its own types, capabilities, effects, outcomes, resources, costs, and durability rules while sharing the compiler, verifier, scheduler, trace system, tooling, and backends.</p>
<p>The governing design rule is:</p>
<blockquote>
<p>Make source code pleasant, make authority explicit, make durable state first-order, make executable artifacts verifiable, and keep native protocol authority outside the scripting language.</p>
</blockquote>
<h1 id="appendix-a---proposed-core-ir-sketch-unnumbered">Appendix A - Proposed Core IR sketch {.unnumbered}</h1>
<pre><code class="language-text">module tinyidp.signup@2
profile tinyidp.assured/v2

handle PasswordSecret affine secret ephemeral
handle EvidenceRef affine restricted durable-ref
handle ContinuationRef affine restricted ephemeral

capability account.lookup@1:
  (IdentityLookup) -&gt; option&lt;IdentityCandidate&gt;
  effect account.read
  cost 25

function signup.submitted(
  %input: SignupPost,
  %password: PasswordSecret,
  %cont: ContinuationRef,
  cap %lookup: account.lookup@1
) -&gt; Outcome&lt;SignupResult&gt;
capabilities { account.lookup@1 }
effects { identity.create, credential.password.set,
          evidence.consume, continuation.consume }
limits { fuel 30000, host 200, heap 1048576, jobs 16 }
{
block entry:
  %email = record.get %input &quot;email&quot;
  %candidate = host.call %lookup (%email)
  %exists = option.is_some %candidate
  br %exists block deny_exists block commit_new

block deny_exists:
  %out = outcome.deny &quot;account_exists&quot;
  ret %out

block commit_new:
  %plan0 = effect.begin &quot;signup.account@2&quot;
  %plan1, %subject = effect.append %plan0 identity.create (%input)
  %plan2 = effect.append.move %plan1 credential.password.set
             (%subject, %password)
  %plan3 = effect.append.move %plan2 continuation.consume (%cont)
  %out = outcome.commit %plan3
  ret %out
}
</code></pre>
<h1 id="appendix-b---selected-verifier-rules-unnumbered">Appendix B - Selected verifier rules {.unnumbered}</h1>
<h2 id="b1-capability-call">B.1 Capability call</h2>
<pre><code class="language-text">C(capID) = capability A : I -&gt; O ! e
Gamma(v) = I
A in permittedCapabilities(function)
e in permittedRuntimeEffects(function)
------------------------------------------------ CAP-CALL
Gamma ; C ; E |- host.call A(v) : O ! {e}
</code></pre>
<h2 id="b2-effect-construction">B.2 Effect construction</h2>
<pre><code class="language-text">E(effectID) = effect K : I -&gt; O
Gamma(v) = I
K in permittedCommitEffects(function)
K acceptedBy(templateID, position)
------------------------------------------------ EFFECT-APPEND
Gamma ; C ; E |- append templateID K(v) : Plan&lt;next&gt; ! {}
</code></pre>
<p>Effect construction is pure with respect to native state. The resulting plan is interpreted later by the native committer.</p>
<h2 id="b3-durable-checkpoint">B.3 Durable checkpoint</h2>
<pre><code class="language-text">live(pc) = {v1 ... vn}
for all vi:
  durableType(type(vi))
  sensitivity(vi) &lt;= checkpointLimit
  ownership(vi) not-in {borrowed, capability, transient}
sizeBound(frame(v1 ... vn)) &lt;= maxFrame
------------------------------------------------ CHECKPOINT
checkpoint k frame(v1 ... vn) is valid
</code></pre>
<h2 id="b4-affine-move">B.4 Affine move</h2>
<pre><code class="language-text">Gamma(h) = owned Handle&lt;K&gt;
------------------------------------------------ MOVE
Gamma |- move h : Handle&lt;K&gt;
post-state Gamma(h) = moved
</code></pre>
<p>Any later read of <code>h</code> is rejected.</p>
<h2 id="b5-successful-invocation">B.5 Successful invocation</h2>
<pre><code class="language-text">rootTask = terminal
liveChildren(rootTask) = empty
pendingJobs = 0
pendingSettlements = 0
outcome is well-typed and allowed
------------------------------------------------ INVOKE-SUCCESS
realm may be returned to reusable state
</code></pre>
<h1 id="appendix-c---artifact-manifest-sketch-unnumbered">Appendix C - Artifact manifest sketch {.unnumbered}</h1>
<pre><code class="language-json">{
  &quot;format&quot;: &quot;mjs.bundle/v1&quot;,
  &quot;artifactDigest&quot;: &quot;sha256:...&quot;,
  &quot;sourceDigest&quot;: &quot;sha256:...&quot;,
  &quot;profile&quot;: {
    &quot;id&quot;: &quot;tinyidp.assured&quot;,
    &quot;version&quot;: &quot;2.1.0&quot;,
    &quot;digest&quot;: &quot;sha256:...&quot;
  },
  &quot;compiler&quot;: {
    &quot;version&quot;: &quot;0.8.0&quot;,
    &quot;frontend&quot;: &quot;goja-ast-adapter/af2ceb9156d7&quot;,
    &quot;extensions&quot;: [&quot;durable-async/1&quot;, &quot;tinyidp-ui/2&quot;]
  },
  &quot;program&quot;: {
    &quot;coreIrDigest&quot;: &quot;sha256:...&quot;,
    &quot;schemaDigest&quot;: &quot;sha256:...&quot;,
    &quot;checkpointDigest&quot;: &quot;sha256:...&quot;,
    &quot;authorityDigest&quot;: &quot;sha256:...&quot;
  },
  &quot;callbacks&quot;: [
    {
      &quot;id&quot;: &quot;signup.submitted&quot;,
      &quot;function&quot;: 17,
      &quot;capabilities&quot;: [&quot;account.lookup@1&quot;],
      &quot;effects&quot;: [&quot;identity.create&quot;, &quot;credential.password.set&quot;],
      &quot;outcomes&quot;: [&quot;deny&quot;, &quot;commit&quot;, &quot;error&quot;],
      &quot;limits&quot;: {&quot;fuel&quot;: 30000, &quot;hostCost&quot;: 200}
    }
  ],
  &quot;checkpoints&quot;: [
    {
      &quot;id&quot;: &quot;signup.collect-form&quot;,
      &quot;frameSchema&quot;: &quot;SignupCollectFormFrameV2&quot;,
      &quot;resumeEvent&quot;: &quot;SignupPostV2&quot;
    }
  ],
  &quot;migrations&quot;: [
    {
      &quot;from&quot;: &quot;signup.collect-form@1&quot;,
      &quot;to&quot;: &quot;signup.collect-form@2&quot;,
      &quot;function&quot;: 41
    }
  ],
  &quot;signatures&quot;: []
}
</code></pre>
<h1 id="appendix-d---research-and-primary-source-notes-unnumbered">Appendix D - Research and primary-source notes {.unnumbered}</h1>
<p>The following sources informed the analysis. Repository links are pinned where the report depends on implementation details.</p>
<p><strong>[TINY-LAMBDA] Tiny-IDP lambda contract.</strong> <code>pkg/idpprogram/lambda.go</code> at the analyzed commit. The type records callback identity, schemas, allowed outcomes, capability and effect sets, budgets, and source location, while excluding the callback function itself.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/lambda.go">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/lambda.go</a></p>
<p><strong>[TINY-OUTCOME] Tiny-IDP outcome algebra.</strong> <code>pkg/idpprogram/outcomes.go</code>. The outcome family is closed; browser continuations and effect plans are data-only and validated against the lambda contract.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/outcomes.go">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpprogram/outcomes.go</a></p>
<p><strong>[TINY-CONT] Tiny-IDP durable continuation record.</strong> <code>pkg/idpcontinuation/types.go</code>. The package explicitly excludes Goja values and stores pure-Go restart-safe state.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpcontinuation/types.go">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpcontinuation/types.go</a></p>
<p><strong>[TINY-DESIGN] Lambda-first design with explicit browser continuations.</strong> The active design distinguishes in-request Promises from browser continuations and anticipates compiler lowering of restricted browser-spanning await.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/design-doc/03-lambda-first-tiny-idp-javascript-api-with-explicit-browser-continuations.md">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/ttmp/2026/07/10/TINYIDP-GOJA-001--go-go-goja-identity-microkernel-scripting-layer/design-doc/03-lambda-first-tiny-idp-javascript-api-with-explicit-browser-continuations.md</a></p>
<p><strong>[TINY-RUNTIME] Tiny-IDP runtime factory.</strong> Closed module loader, independent runtime materialization, canonical equality, and fingerprint checks.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/runtime_factory.go">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/runtime_factory.go</a></p>
<p><strong>[TINY-INVOKE] Tiny-IDP invocation path.</strong> Runtime interruption, deep-frozen JSON input, Promise handling, settlement wait, outcome decoding, and safe worker classification.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/invoke.go">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/invoke.go</a></p>
<p><strong>[TINY-CAP] Tiny-IDP capability bridge.</strong> Versioned bindings, call and byte budgets, lifetime revocation, owner-routed Promise settlement, and panic conversion.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/capabilities.go">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/capabilities.go</a></p>
<p><strong>[TINY-POOL] Tiny-IDP worker pool.</strong> Exclusive leasing and fail-stop discard/replacement.<br />
<a href="https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/pool.go">https://github.com/go-go-golems/tiny-idp/blob/d164ae59408bdd8bc21516274b446339b1761b1e/pkg/idpscript/pool.go</a></p>
<p><strong>[GOJA-README] Goja project documentation.</strong> Pure-Go ECMAScript runtime, runtime ownership constraints, object non-transferability, interrupt behavior, and embedder-owned event-loop policy.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/README.md">https://github.com/dop251/goja/blob/af2ceb9156d7/README.md</a></p>
<p><strong>[GOJA-COMPILE] Goja compile seam.</strong> <code>Parse</code>, <code>CompileAST</code>, and runtime-independent <code>Program</code>.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/runtime.go#L1296-L1380">https://github.com/dop251/goja/blob/af2ceb9156d7/runtime.go#L1296-L1380</a></p>
<p><strong>[GOJA-PARSER] Goja parser.</strong> The parser returns an AST, while its parser and AST interfaces are described as works in progress.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/parser/parser.go">https://github.com/dop251/goja/blob/af2ceb9156d7/parser/parser.go</a></p>
<p><strong>[GOJA-COMPILER] Goja compiler representation.</strong> <code>Program</code> contains the private instruction representation and source mapping data.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/compiler.go">https://github.com/dop251/goja/blob/af2ceb9156d7/compiler.go</a></p>
<p><strong>[GOJA-VM] Goja VM dispatch and suspension.</strong> The central dispatch loop, interrupt check, execution context, and suspension state.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/vm.go">https://github.com/dop251/goja/blob/af2ceb9156d7/vm.go</a></p>
<p><strong>[GOJA-ASYNC] Goja async and generator execution.</strong> Async functions use an async runner and generator suspension over an execution context.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/func.go">https://github.com/dop251/goja/blob/af2ceb9156d7/func.go</a></p>
<p><strong>[GOJA-PROMISE] Goja Promise implementation.</strong> Promise runtime locality, non-goroutine-safe settlement, rejection tracking, and async-context tracking.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/builtin_promise.go">https://github.com/dop251/goja/blob/af2ceb9156d7/builtin_promise.go</a></p>
<p><strong>[GOJA-PROMISE-QUEUE] Goja runtime job queue.</strong> Promise jobs are private runtime state and are drained on normal top-level exit.<br />
<a href="https://github.com/dop251/goja/blob/af2ceb9156d7/runtime.go#L2840-L2860">https://github.com/dop251/goja/blob/af2ceb9156d7/runtime.go#L2840-L2860</a></p>
<p><strong>[GOJA-RUNTIME] Goja runtime configuration.</strong> Custom random and time sources, parser options, stack limit, and async/rejection tracking.<br />
<a href="https://pkg.go.dev/github.com/dop251/goja">https://pkg.go.dev/github.com/dop251/goja</a></p>
<p><strong>[OCAP] Miller, Yee, and Shapiro, &quot;Capability Myths Demolished.&quot;</strong> The paper analyzes capability models and argues that pure capability systems support least privilege and avoid confused-deputy problems.<br />
<a href="https://papers.agoric.com/papers/capability-myths-demolished/abstract/">https://papers.agoric.com/papers/capability-myths-demolished/abstract/</a></p>
<p><strong>[SES] Secure ECMAScript compartments.</strong> SES compartments receive only expressly supplied powers and lock down shared intrinsics; the documentation also notes that same-agent compartments do not solve availability and memory-exhaustion threats.<br />
<a href="https://github.com/endojs/endo/tree/master/packages/ses">https://github.com/endojs/endo/tree/master/packages/ses</a></p>
<p><strong>[DEFUNC] Danvy and Nielsen, &quot;Defunctionalization at Work.&quot;</strong> Defunctionalization is presented as a whole-program transformation from higher-order to first-order programs.<br />
<a href="https://www.brics.dk/RS/01/23/">https://www.brics.dk/RS/01/23/</a></p>
<p><strong>[EFFEKT] Brachthaeuser, Schuster, and Ostermann, &quot;Effects as Capabilities.&quot;</strong> Effect types express capabilities required from context and are translated to explicit capability-passing style.<br />
<a href="https://se.cs.uni-tuebingen.de/publications/brachthaeuser20effekt/">https://se.cs.uni-tuebingen.de/publications/brachthaeuser20effekt/</a></p>
<p><strong>[KOKA] Xie and Leijen, &quot;Generalized Evidence Passing for Effect Handlers.&quot;</strong> A sequence of effect-handler compilation techniques culminating in efficient lower-level compilation.<br />
<a href="https://www.microsoft.com/en-us/research/publication/generalized-evidence-passing-for-effect-handlers/">https://www.microsoft.com/en-us/research/publication/generalized-evidence-passing-for-effect-handlers/</a></p>
<p><strong>[TEMPORAL] Temporal architecture.</strong> Durable workflows use event-sourced history; workflow code is deterministic and side-effect-free while activities own side effects.<br />
<a href="https://github.com/temporalio/temporal/blob/main/docs/architecture/README.md">https://github.com/temporalio/temporal/blob/main/docs/architecture/README.md</a></p>
<p><strong>[WASMTIME] Wasmtime resource controls.</strong> Fuel provides deterministic execution bounds; epoch interruption provides coarser interruption; stores expose resource limiters and async yielding.<br />
<a href="https://docs.wasmtime.dev/api/wasmtime/struct.Store.html">https://docs.wasmtime.dev/api/wasmtime/struct.Store.html</a></p>
<p><strong>[QUICKJS] QuickJS documentation.</strong> Small embeddable engine with explicit runtime controls and a runtime-owned memory model.<br />
<a href="https://www.bellard.org/quickjs/">https://www.bellard.org/quickjs/</a></p>
<p><strong>[WIT] WebAssembly Interface Types.</strong> WIT defines contracts, records, variants, results, interfaces, worlds, and owned or borrowed resource handles without defining component behavior.<br />
<a href="https://component-model.bytecodealliance.org/design/wit.html">https://component-model.bytecodealliance.org/design/wit.html</a></p>
<p><strong>[EBPF] Linux eBPF verifier documentation.</strong> The verifier explores abstract machine states and enforces type, memory, and reference-lifetime constraints before programs execute.<br />
<a href="https://docs.kernel.org/bpf/verifier.html">https://docs.kernel.org/bpf/verifier.html</a></p>
<p><strong>[RACKET] Racket Guide, &quot;Creating Languages.&quot;</strong> Distinguishes ordinary macro extension from control over reader and language-expansion layers.<br />
<a href="https://docs.racket-lang.org/guide/languages.html">https://docs.racket-lang.org/guide/languages.html</a></p>
<p><strong>[NANOPASS] Nanopass Framework.</strong> Compiler construction through small passes and many intermediate representations.<br />
<a href="https://nanopass.org/">https://nanopass.org/</a></p>
<p><strong>[TRUFFLE] GraalVM Truffle Language Implementation Framework.</strong> Reusable language and tool infrastructure built around instrumentable self-modifying AST interpreters.<br />
<a href="https://www.graalvm.org/latest/graalvm-as-a-platform/language-implementation-framework/">https://www.graalvm.org/latest/graalvm-as-a-platform/language-implementation-framework/</a></p>
<p><strong>[JSCERT] JSCert.</strong> Mechanized ECMAScript 5 specification in Coq plus a proved reference interpreter tested with Test262.<br />
<a href="https://jscert.org/">https://jscert.org/</a></p>
<p><strong>[COMPCERT] CompCert.</strong> A compiler with machine-checked semantic-preservation proofs, decomposed across compiler passes and intermediate languages.<br />
<a href="https://compcert.org/">https://compcert.org/</a></p>
<p><strong>[SPECTEC] WebAssembly SpecTec.</strong> A specification toolchain designed to generate rigorous semantics, prose, and executable artifacts from a shared source.<br />
<a href="https://webassembly.org/news/2025-03-27-spectec/">https://webassembly.org/news/2025-03-27-spectec/</a><br />
EOF<br />
wc -w /mnt/data/malleable-js-tiny-idp-monograph.md<br />
wc -l /mnt/data/malleable-js-tiny-idp-monograph.md<br />
ls -lh /mnt/data/malleable-js-tiny-idp-monograph.md</p>
<pre><code>
&lt;details&gt;&lt;summary&gt;💭 Thinking&lt;/summary&gt;

**Generated monograph document in Markdown format and checked Pandoc version**

&lt;/details&gt;

```unknown
bash -lc pandoc --print-default-data-file reference.docx &gt; /mnt/data/reference-default.docx
pandoc /mnt/data/malleable-js-tiny-idp-monograph.md \
  --from markdown+raw_attribute+fenced_divs \
  --to docx \
  --reference-doc=/mnt/data/reference-default.docx \
  --toc --toc-depth=3 --number-sections \
  --metadata toc-title='Contents' \
  -o /mnt/data/malleable-js-draft.docx
python - &lt;&lt;'PY'
from docx import Document
p='/mnt/data/malleable-js-draft.docx'
d=Document(p)
for i,para in enumerate(d.paragraphs[:35]):
    print(i, repr(para.text[:100]), para.style.name)
PY
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Generated DOCX with TOC and custom page breaks</strong></p>
<p><strong>Preparing final deliverables</strong></p>
<p>I’m focused on converting the monograph into DOCX and PDF formats, inspecting each page and making fixes. I’m fulfilling the user’s request using the provided markdown artifact and finalized deliverables.</p>
<p><strong>Prepared final deliverables</strong></p>
</details>
<pre><code class="language-unknown">bash -lc cat /home/oai/skills/docx/SKILL.md &amp;&amp; printf '\n---PDF SKILL---\n' &amp;&amp; cat /home/oai/skills/pdfs/SKILL.md
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Inspected and patched document styles and generated references</strong></p>
</details>
<pre><code class="language-unknown">bash -lc rm -rf /tmp/malleable_docx_render &amp;&amp; mkdir -p /tmp/malleable_docx_render
python /home/oai/skills/docx/render_docx.py /mnt/data/malleable-js-tiny-idp-monograph.docx --output_dir /tmp/malleable_docx_render --emit_pdf --verbose
ls -lh /tmp/malleable_docx_render | sed -n '1,30p'
find /tmp/malleable_docx_render -maxdepth 1 -name 'page-*.png' | wc -l
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Researching sources and context</strong></p>
<p>I’m picking up from an interrupted attempt. I’ll recheck the gathered sources and possibly search for more current information—especially around Go, Tiny-IDP, and related systems—ensuring accuracy and relevance.</p>
<p><strong>Researched sources and context</strong></p>
</details>
<pre><code class="language-unknown">bash -lc ls -lah /mnt/data | sed -n '1,200p' &amp;&amp; find /mnt/data -maxdepth 2 -type f \( -iname '*goja*' -o -iname '*interpreter*' -o -iname '*malleable*' \) -printf '%p %s bytes\n' | sort
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Inspected data and searched for relevant files</strong></p>
<p><strong>Brainstorming interpreter design</strong></p>
<p>I’m thinking through how using or creating a custom JavaScript interpreter could improve Tiny-IDP. Expanding Goja’s functionality, or creating a new one, might simplify design, enhance extensibility, and trigger new patterns for both frameworks and plugins.</p>
<p><strong>Continuing monograph work</strong></p>
<p>I’m resuming work on the second monograph. I'll verify the partial manuscript, fill in the remaining sections, and review the comparative and architectural concepts before rendering the full versions in PDF, DOCX, and Markdown.</p>
<p><strong>Brainstormed interpreter design and continued monograph work</strong></p>
</details>
<pre><code class="language-unknown">bash -lc ls -lah /mnt/data | sed -n '1,220p'; printf '\n--- candidates ---\n'; find /mnt/data -maxdepth 2 -type f \( -iname '*malleab*' -o -iname '*compiler*' -o -iname '*goja*' -o -iname '*interpreter*' -o -iname '*semantic*' \) -printf '%p\t%k KB\n' | sort
</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Inspected and listed candidate files in directory</strong></p>
</details>
<pre><code class="language-unknown">import os, glob, pathlib, json, textwrap, subprocess, sys, re
files = sorted(glob.glob('/mnt/data/*'))
[(os.path.basename(f), os.path.getsize(f) if os.path.isfile(f) else None) for f in files[:200]]

</code></pre>
<details><summary>💭 Thinking</summary>
<p><strong>Listed files and their sizes</strong></p>
</details>
<pre><code class="language-unknown">bash -lc exit 42
</code></pre>
<p>The 50-page manuscript now frames Tiny-IDP as one authority-selecting “world” atop canonical MIR and versioned dialect packs. Layout defects are corrected; final artifact checks and packaging remain.</p>
<details><summary>💭 Thinking</summary>
<p><strong>Tested container command with exit code</strong></p>
</details>
<pre><code class="language-json">{&quot;paths&quot;:[&quot;GitHub&quot;],&quot;query&quot;:&quot;repository&quot;}
</code></pre>
<pre><code class="language-json">{&quot;paths&quot;:[&quot;GitHub&quot;],&quot;query&quot;:&quot;fetch_file&quot;}
</code></pre>
<h1 id="malleable-javascript-for-assurance-oriented-systems">Malleable JavaScript for Assurance-Oriented Systems</h1>
<p>The second monograph is complete.</p>
<ul>
<li><a href="sandbox:/mnt/data/malleable-js-interpreter-compiler-monograph.pdf">Read the 50-page PDF</a></li>
<li><a href="sandbox:/mnt/data/malleable-js-interpreter-compiler-monograph.docx">Download the editable DOCX</a></li>
<li><a href="sandbox:/mnt/data/malleable-js-interpreter-compiler-monograph.md">View the Markdown source</a></li>
</ul>
<p>The report contains approximately 13,053 words. It is based on the same pinned Tiny-IDP branch snapshot used in the first study, including the work associated with <code>TINYIDP-GOJA-001</code>. fileciteturn5file0L1-L3</p>
<h2 id="central-conclusion-1">Central conclusion</h2>
<p>Greater control over Goja would be valuable, but <strong>building a complete JavaScript engine should not be the first move</strong>.</p>
<p>The recommended architecture is a reusable <strong>Malleable JavaScript substrate</strong>:</p>
<pre><code class="language-text">standard JavaScript source syntax
        |
        v
versioned assurance-profile checker
        |
        v
typed/effect-aware compiler front end
        |
        v
small canonical semantic IR
        |
        +-- reference interpreter
        +-- Goja compute backend
        +-- generated Go backend
        +-- WebAssembly or process-isolated backend
        +-- model checker
        +-- documentation and test generators
</code></pre>
<p>Projects extend this substrate through versioned <strong>dialects</strong> and <strong>worlds</strong>:</p>
<ul>
<li>A <strong>dialect</strong> contributes types, operations, effects, resource classes, verification rules, lowering rules, diagnostics, documentation metadata, and test generators.</li>
<li>A <strong>world</strong> selects the exact dialect versions, capabilities, entry points, limits, language profile, trust policy, and backend available to one class of plugin.</li>
<li>Tiny-IDP becomes one assurance-sensitive world rather than the hard-coded owner of the compiler platform.</li>
</ul>
<p>This separates three concerns that are currently entangled in many embedded-language systems:</p>
<pre><code class="language-text">source-language ergonomics
semantic and verification contract
runtime implementation
</code></pre>
<p>JavaScript can remain the author-facing language even when neither JavaScript source nor Goja bytecode is the durable semantic format.</p>
<h2 id="principal-tiny-idp-implications">Principal Tiny-IDP implications</h2>
<p>The existing Tiny-IDP architecture is already close to a compiler-oriented runtime. <code>LambdaSpec</code> records schemas, outcomes, capabilities, effects, and resource budgets without containing the callback itself. fileciteturn17file0L20-L39</p>
<p>Compiler ownership would allow much of that contract to be <strong>derived rather than repeated</strong>:</p>
<table>
<thead>
<tr>
<th>Current declaration</th>
<th>Compiler-derived property</th>
</tr>
</thead>
<tbody>
<tr>
<td>Callback ID</td>
<td>Package, module, export, or lexical identity</td>
</tr>
<tr>
<td>Required capabilities</td>
<td>Reachable capability-call analysis</td>
</tr>
<tr>
<td>Allowed effects</td>
<td>Typed effect-constructor analysis</td>
</tr>
<tr>
<td>Allowed outcomes</td>
<td>Closed control-flow analysis</td>
</tr>
<tr>
<td>Input and output schema use</td>
<td>Property and constructor type checking</td>
</tr>
<tr>
<td>Continuation carry schema</td>
<td>Live-variable and region analysis</td>
</tr>
<tr>
<td>Source location</td>
<td>Precise source map and transformation provenance</td>
</tr>
<tr>
<td>Call and output budgets</td>
<td>Static estimates plus world policy</td>
</tr>
<tr>
<td>Compatibility metadata</td>
<td>Semantic-identity and continuation-schema comparison</td>
</tr>
</tbody>
</table>
<p>The host would still grant the maximum authority. Inference would not grant capabilities. It would prove that a program requests a subset of the selected world’s authority.</p>
<h2 id="durable-await-as-the-flagship-compiler-feature">Durable <code>await</code> as the flagship compiler feature</h2>
<p>The report’s highest-value proposal is browser-spanning <code>await</code> syntax that compiles to Tiny-IDP’s existing explicit continuation machinery.</p>
<p>A script author could write:</p>
<pre><code class="language-javascript">export async function signup(ctx) {
  const invitation =
    await ctx.invites.inspect(ctx.input.code);

  const form =
    await durable.form(SignupForm, {
      email: invitation.email,
    });

  const proof =
    await durable.emailCode(form.email);

  return effects.commit([
    identity.create({
      email: form.email,
      proof,
    }),
    invitation.consume(invitation.ref),
    session.establish(),
  ]);
}
</code></pre>
<p>The compiler would transform this into named handlers, typed continuation records, and explicit native suspension operations. Live-variable analysis would calculate exactly which values must survive each suspension.</p>
<p>The compiler would reject a program when a live value is:</p>
<ul>
<li>a password or raw secret;</li>
<li>a capability function;</li>
<li>a transaction or request resource;</li>
<li>an unresolved Promise;</li>
<li>an ordinary function or closure;</li>
<li>a Proxy, Symbol, or cyclic object;</li>
<li>an oversized public value;</li>
<li>evidence that lacks an approved durable projection.</li>
</ul>
<p>This preserves the current continuation principle. Tiny-IDP explicitly requires durable records to contain no Goja values, functions, Promises, or goroutine-local state. fileciteturn19file0L3-L5 Its continuation record instead contains stable handler identity, program and workflow identity, carry, bindings, native references, revision, expiry, and terminal state. fileciteturn19file0L56-L84</p>
<h2 id="why-vm-frames-should-still-not-be-serialized">Why VM frames should still not be serialized</h2>
<p>Access to Goja’s interpreter internals makes VM-frame persistence technically more conceivable, but not architecturally sound.</p>
<p>Goja’s suspended execution context contains runtime-local values, lexical stashes, a program pointer, private environments, program counters, stacks, try frames, iterator state, and reference state. Suspension copies portions of that structure and resumption restores them into the same VM model. fileciteturn21file0L24-L111</p>
<p>Persisting it would bind browser workflow state to:</p>
<ul>
<li>one Goja implementation and version;</li>
<li>internal opcode and object layouts;</li>
<li>garbage-collector assumptions;</li>
<li>closure and lexical-environment representation;</li>
<li>pending Promise-job semantics;</li>
<li>potentially reachable host functions and Go pointers;</li>
<li>exact compiled instruction streams;</li>
<li>opaque, difficult-to-inspect object graphs.</li>
</ul>
<p>Interpreter access should instead inform a compiler transformation:</p>
<pre><code class="language-text">source async function
        |
        v
control-flow graph
        |
        v
identify durable suspension points
        |
        v
liveness + type + region analysis
        |
        v
defunctionalized handlers
        |
        v
typed continuation schema
</code></pre>
<p>The durable representation remains a small application-level state machine.</p>
<h2 id="what-can-be-built-without-a-goja-fork">What can be built without a Goja fork</h2>
<p>A substantial first implementation can sit above stock Goja:</p>
<ul>
<li>assurance-profile checking;</li>
<li>module and import resolution;</li>
<li>capability and effect inference;</li>
<li>outcome closure;</li>
<li>deterministic callback-ID generation;</li>
<li>durable-<code>await</code> lowering;</li>
<li>continuation-carry liveness analysis;</li>
<li>secret and evidence flow checking;</li>
<li>state-machine extraction;</li>
<li>semantic manifests and diffs;</li>
<li>structured-concurrency checks;</li>
<li>source-to-source generation;</li>
<li>generation-compatibility analysis;</li>
<li>IDE diagnostics;</li>
<li>test and documentation generation;</li>
<li>lowering to a project-independent MIR.</li>
</ul>
<p>Goja exposes a parser and AST, although its AST package explicitly warns that its interfaces remain works in progress. The report therefore recommends isolating Goja AST access behind a pinned adapter and immediately converting it to a platform-owned syntax representation. fileciteturn22file0L3-L10</p>
<h2 id="what-justifies-a-narrow-goja-fork">What justifies a narrow Goja fork</h2>
<p>A fork becomes justified only for guarantees that cannot be observed reliably at the embedding boundary:</p>
<ol>
<li>
<p><strong>Deterministic instruction fuel</strong></p>
<p>Charge a stable semantic cost for VM instructions and size-sensitive operations. Wall time remains an emergency bound rather than the primary execution budget.</p>
</li>
<li>
<p><strong>Allocation and retained-heap accounting</strong></p>
<p>Track logical allocation by runtime, module, invocation, secret, and continuation region.</p>
</li>
<li>
<p><strong>First-class Promise-job ownership</strong></p>
<p>Associate jobs with invocation task scopes, expose pending-job counts, enforce cancellation propagation, and prove quiescence before returning a worker to the pool.</p>
</li>
<li>
<p><strong>Unforgeable per-value provenance</strong></p>
<p>Attach VM-internal origin tags such as native evidence, secret region, capability generation, schema validation, or durable-reference identity.</p>
</li>
<li>
<p><strong>Precise semantic tracing</strong></p>
<p>Trace calls, branches, throws, allocations, suspension points, Promise jobs, source spans, and abstract effect operations.</p>
</li>
<li>
<p><strong>Stronger reset or snapshot support</strong></p>
<p>Snapshot only frozen activation data and immutable module state—not live requests, secrets, capabilities, pending jobs, or control frames.</p>
</li>
<li>
<p><strong>A stable compiler-IR export</strong></p>
<p>This is useful only when source-level rewriting proves too brittle. It should be generic enough to upstream and should not contain Tiny-IDP-specific opcodes.</p>
</li>
</ol>
<p>The fork should remain a replaceable backend. Semantic identity, continuation identity, and verification results must not depend on Goja bytecode.</p>
<h2 id="new-software-design-patterns-developed-in-the-report">New software-design patterns developed in the report</h2>
<h3 id="compiler-enforced-object-capabilities">Compiler-enforced object capabilities</h3>
<p>Capabilities become typed imports rather than arbitrary properties on <code>ctx</code>. Dynamic access such as:</p>
<pre><code class="language-javascript">ctx.cap[namespace][operation](input)
</code></pre>
<p>can be rejected or conservatively widened. Libraries cannot acquire their caller’s authority merely because they are imported. Authority must appear in their effect summary or be passed as an explicitly attenuated capability.</p>
<h3 id="structured-concurrency-for-embedded-javascript">Structured concurrency for embedded JavaScript</h3>
<p>Every asynchronous operation belongs to an invocation task region. Before a handler returns, a task must be:</p>
<ul>
<li>awaited;</li>
<li>joined through a structured combinator;</li>
<li>cancelled;</li>
<li>or converted into an explicitly declared host-owned delivery effect.</li>
</ul>
<p>An ordinary Promise may not escape the invocation region.</p>
<h3 id="typed-algebraic-effects">Typed algebraic effects</h3>
<p>Instead of manufacturing arbitrary result objects, scripts construct typed abstract operations:</p>
<pre><code class="language-javascript">return effects.commit([
  identity.create({ email, proof }),
  credential.bindPassword({ identity, password }),
  invitation.consume(invitation),
  session.establish({ identity }),
]);
</code></pre>
<p>Different backends can interpret the same effect sequence:</p>
<ul>
<li>production transaction handler;</li>
<li>deterministic in-memory test model;</li>
<li>trace-only simulator;</li>
<li>migration adapter;</li>
<li>model checker;</li>
<li>generated documentation.</li>
</ul>
<h3 id="resource-regions">Resource regions</h3>
<p>Values receive lifetime regions such as:</p>
<pre><code class="language-text">static
invocation
secret
transaction
continuation
</code></pre>
<p>The verifier rejects movement into a longer-lived region unless an explicit dialect operation converts the value into an approved native reference.</p>
<h3 id="semantic-hot-reload">Semantic hot reload</h3>
<p>Reload compatibility is classified by semantics rather than source text alone:</p>
<ul>
<li>backend-only replacement;</li>
<li>source-only but MIR-equivalent change;</li>
<li>compatible semantic extension;</li>
<li>explicit continuation migration;</li>
<li>breaking change requiring old-generation retention or revocation.</li>
</ul>
<h3 id="proof-carrying-activation">Proof-carrying activation</h3>
<p>A compiled artifact includes a machine-checkable certificate containing:</p>
<ul>
<li>source and frontend identities;</li>
<li>canonical MIR hash;</li>
<li>world and dialect versions;</li>
<li>pass-pipeline identity;</li>
<li>inferred capabilities and effects;</li>
<li>continuation-schema hashes;</li>
<li>resource policies;</li>
<li>verifier results;</li>
<li>differential-test results;</li>
<li>signature.</li>
</ul>
<p>The production runtime verifies the certificate rather than trusting compiler prose.</p>
<h3 id="semantic-review-diffs">Semantic review diffs</h3>
<p>Code review can report changes such as:</p>
<pre><code class="language-text">+ imports cap.community.lookup@2
+ adds durable state signup.after_recovery
~ continuation carry 72 bytes -&gt; 416 bytes
+ effect credential.bind-recovery@1
- denial outcome member_exists
~ maximum fuel estimate 42k -&gt; 91k
</code></pre>
<p>This exposes authority and persistence changes that ordinary source diffs conceal.</p>
<h2 id="verification-target">Verification target</h2>
<p>The report deliberately does <strong>not</strong> recommend proving all of modern ECMAScript first.</p>
<p>The feasible target is the small MIR and verifier:</p>
<ul>
<li>value and resource typing;</li>
<li>region safety;</li>
<li>capability confinement;</li>
<li>outcome closure;</li>
<li>continuation type preservation;</li>
<li>effect-sequence well-formedness;</li>
<li>deterministic suspension semantics;</li>
<li>selected lowering-pass trace preservation.</li>
</ul>
<p>The production Goja backend, generated-Go backend, and reference interpreter can then be differentially tested against the executable semantic model.</p>
<p>“Verified” in the report therefore means a specific verifier, semantic component, or compiler transformation has a stated and checked property. It does not claim that arbitrary JavaScript, all native capabilities, or the complete identity provider has been formally verified.</p>
<h2 id="recommended-sequence">Recommended sequence</h2>
<p>The concrete roadmap is:</p>
<pre><code class="language-text">0. Define trust model and semantic contract
1. Build a pinned JavaScript front end above stock Goja
2. Prototype one durable-await transformation
3. Add task-scope and deterministic-host analysis
4. Introduce the canonical MIR and reference interpreter
5. Extract a declarative dialect SDK
6. Add narrowly measured Goja instrumentation
7. Formalize and verify the small core
8. Add isolation and alternative backends
9. Reconsider a complete engine only if it becomes a strategic product
</code></pre>
<p>The PDF is the primary reading edition. The DOCX includes a linked static contents section, internal heading navigation, source links, 207 PDF outline entries, embedded fonts, and conventional numbered references.</p>
```

## Backlinks

- [research/kb/projects/tiny-idp](http://parc.yolo.scapegoat.dev/note/research/kb/projects/tiny-idp)
- [transcripts/inventory-programming-languages-and-architecture](http://parc.yolo.scapegoat.dev/note/transcripts/inventory-programming-languages-and-architecture)

## Sitemap

- [Home](http://parc.yolo.scapegoat.dev/)
- [Home markdown mirror](http://parc.yolo.scapegoat.dev/index.md)
- [Markdown sitemap](http://parc.yolo.scapegoat.dev/sitemap.md)
