Skip to content

Petrinaut HIR: compile user code to buffer-native programs, remove Babel#8973

Draft
kube wants to merge 12 commits into
mainfrom
petrinaut-lang
Draft

Petrinaut HIR: compile user code to buffer-native programs, remove Babel#8973
kube wants to merge 12 commits into
mainfrom
petrinaut-lang

Conversation

@kube

@kube kube commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

🌟 What is the purpose of this PR?

🔗 Related links

  • ...

🚫 Blocked by

  • ...

🔍 What does this change?

  • ...

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing
  • modifies an npm-publishable library and I have added a changeset file(s)
  • modifies a Cargo-publishable library and I have amended the version
  • modifies a Cargo-publishable library, but it is not yet ready to publish
  • modifies a block that will need publishing via GitHub action once merged
  • I am unsure / need advice

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change
  • are in a state where docs changes are not yet required but will be
  • require changes to docs which are made as part of this PR
  • require changes to docs which are not made in this PR
    • Provide more detail here
  • I am unsure / need advice

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph
  • affected the execution graph, and the turbo.json's have been updated to reflect this
  • I am unsure / need advice

⚠️ Known issues

🐾 Next steps

🛡 What tests cover this?

❓ How to test this?

  1. Checkout the branch / view the deployment
  2. Try X
  3. Confirm that Y

📹 Demo

kube and others added 7 commits July 7, 2026 18:36
Introduce a typed, source-spanned, JSON-serializable HIR as the single
compiler for dynamics/lambda/kernel user code:

- TS->HIR lowering (const destructuring, guard if/early-return, .map
  comprehensions, first-class distributions) with positioned diagnostics
- Schema-checked typing against Color/parameter definitions; analyses for
  dependency sets, distribution DAGs (nodes/edges/sinks/shared draws),
  binding usage and constant folding
- Buffer-ABI emitters: lambdas read token attributes at statically
  resolved offsets (tokenValues[slotBases[slot] + attr]); kernels write
  place-major staging floats with deferred distribution sampling ordered
  by output index (exact legacy RNG-stream parity); dynamics compile to
  allocation-free Float64Array loops
- Engine hot loops (single-run + Monte Carlo) prefer buffer programs and
  fall back to object-convention HIR programs per item
- HirArtifacts v2 compiled in the LSP worker (sdcpn/compileHirArtifacts
  request) and threaded through simulation/experiment configs; the
  engine no longer bundles any compiler (simulation workers: ~3MB -> ~40kB)
- HIR semantic lints in the LSP checker (source "hir", codes 99001+);
  out-of-subset code is an error and Play gates on error severity only
- Remove @babel/standalone and compile-user-code.ts; fix H-6519
  violations in the supply-chain example; shipped examples are the
  buffer-ABI coverage gate

Design docs: src/hir/README.md (architecture) and src/hir/dsl-sketch.md
(planned OCaml-flavoured DSL lowering to the same HIR).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Interactive playground for the HIR pipeline: type dynamics/lambda/kernel
TypeScript on the left, and inspect everything it compiles to on the
right — the spanned HIR tree, diagnostics with exact ranges, the inferred
return type, dependency sets, the distribution DAG (derivation edges,
output sinks, shared draws), and both emitted programs (buffer-ABI fast
path and object-convention fallback). The model schema (parameters,
places, attribute types) is editable JSON and re-checks live.

Exposes the compiler via new `@hashintel/petrinaut-core/hir` and
`/hir-runtime` entries (typescript declared as an optional peer — only
the ./hir entry needs it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… the HIR

Rebase onto the FE-769 stack (token format v2, UUID + interned strings) and
extend the compiler:

- New HIR nodes: string literals, string predicates
  (startsWith/endsWith/includes), Uuid.generate()/Uuid.from(...) sentinels
- Typecheck: uuid/string attribute types; kernel outputs accept strings for
  string attributes and uuid/string for uuid attributes (omitted uuid =
  auto-generated); string .length; uuid helpers are kernel-only
- Buffer-ABI v2: lambdas and dynamics compile to packed-struct byte reads
  through the frame's shared f64/u64/u8 views (integers rounded, booleans
  u8, strings resolved via the per-run pool, uuids assembled from two u64
  lanes); slotBases now carry byte offsets. Kernel buffer emission is
  deferred (needs an RNG-ordinal sink design to preserve the stream) — the
  object program runs per firing meanwhile
- Object programs emit uuid sentinels/string literals; analyses track
  generatesUuids; string-equality constant folding
- Replace the deleted Babel compiler in the dev token playground with a
  local evaluator

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the object-convention path entirely: the engine no longer decodes
token records for user code, and every dynamics/lambda/kernel runs a
buffer program with all dimension offsets and strides resolved at compile
time and baked into the emitted code as literal constants.

- Kernel buffer emitter: static writes into per-transition staging bytes
  at compile-time-constant offsets; RNG-consuming slots (distributions,
  generated/converted UUIDs) defer through sink calls emitted in
  (arc, token, element-declaration) order, preserving the seeded RNG
  stream; strings intern through the per-run pool inline
- Lambda programs now receive (placeBases, indices) with strides baked
  in — the per-slot offset loop is gone; token layouts are computed once
  per arc slot at emit time
- CompiledTransition carries only buffer programs + reusable scratch
  (placeBases/indices/staging views); encode-kernel-token.ts and the
  record-decode adapters are deleted
- Artifacts v3 are buffer-only; shapes that don't scalarize fail
  compilation with hir:not-compilable (all example models compile fully,
  kernels included — enforced by the coverage gate)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Metrics become the fourth HIR surface and lose their new Function path:

- New arrayReduce/arrayConcat HIR nodes (.reduce/.concat lowering); metric
  code lowers as a function body with spans mapped back to the raw text
- Metric buffer programs read frames directly with statically-resolved
  offsets: attribute offsets/strides baked as literals, place ordinals
  resolved once at instantiation, reductions emitted as loops over the
  packed token region (no per-frame MetricState decoding)
- compileHirArtifacts covers sdcpn.metrics; expression metric specs carry
  the compiled artifact; single-run timeline and actual-mode metric paths
  migrated to the same evaluator via SimulationFrameReader.getRawView()
- Delete compile-metric.ts and frames/metric-state.ts; LSP metric
  sessions get HIR lint incl. hir:not-compilable as blocking errors
- All 18 example metrics compile (reduce/concat/guards/strings) —
  enforced by the coverage gate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Jul 9, 2026 8:05pm
petrinaut Ready Ready Preview Jul 9, 2026 8:05pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview Jul 9, 2026 8:05pm

@github-actions github-actions Bot added area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team area/apps > hash.design Affects the `hash.design` design site (app) labels Jul 7, 2026

kube commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

case "let":
// `let` only appears as a function/callback body; those emit blocks.
// eslint-disable-next-line no-use-before-define -- mutual recursion
return `(() => ${emitBody(expr, scope)})()`;
"__dist",
"__params",
"__pool",
`"use strict"; return (${source});`,
"__params",
"__pool",
"__places",
`"use strict"; return (${source});`,
Comment on lines +54 to +60
const create = new Function(
`"use strict";
const Token = (fn) => fn;
let __default;
${code.replace(/export\s+default\s+/, "__default = ")}
return __default;`,
)() as () => unknown;
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Runs scenarios (dynamics, lambda combinations, kernel firings, Monte-Carlo
experiment with expression metrics) through the public in-process
createMonteCarloSimulator API. Feature-detects the HIR entry so the same
script runs on pre-HIR baselines; emits per-scenario build/run medians,
heap growth, and a work checksum that must match across variants.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
--no-warmup/--samples/--only for fresh-process cold runs; --compile
isolates user-code compilation (HIR pipeline vs Babel per-item).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps > hash.design Affects the `hash.design` design site (app) area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

2 participants