Skip to content

Keep per-instance where an include is, and refuse runs that cannot pick an instance - #118

Merged
qfeuilla merged 3 commits into
mainfrom
compiler-engine
Nov 1, 2026
Merged

qfeuilla merged 3 commits into
mainfrom
compiler-engine

Conversation

@qfeuilla

@qfeuilla qfeuilla commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

What changes

A file included in two places is now per instance only where an instance's value reaches it. A program that includes one helper file from a shared route and from a group holding a per-instance part (a bridge per customer) had every shared run refused (... exists once per instance, so this run needs to know which instance it is for). Now each include decides for itself.

  • Per-instance per place. The compiler keeps the mark per place: the node plus the include path. Every reader asks it of a place:
    • the engine;
    • run refusals;
    • activation, infra and displays;
    • the rules;
    • the editor's view of an included file, which now shows the place's answer.
  • A shared trigger whose runs would reach something per instance is refused by the compiler (shared-trigger-reaches-per-instance). It names what the trigger reaches and why each part is per instance. Before, every fire was refused at run time.
    • Routes and sockets are exempt, since each call can name its instance.
    • Broken parts now name their places, so a trigger refused under one include still turns on under the file's other includes.
    • Stored broken parts read as before: they mean every place.
  • Loops.
    • A loop with no outputs now ends, over an empty list and over items. Before, it was declared stuck.
    • A loop output nothing inside the loop writes is refused (loop-output-unwritten).
    • The docs say what parallel: false guarantees, and that an iteration can outlive its loop.
  • Files kept past their run. A file stored with scope: run and wired into a node that keeps its inputs past the run gets a warning (run-file-kept-past-run). Two new metadata keys drive it: fileScopeFrom and keepsInputsPastRun.
  • Tags work on unrecorded runs. TagRun and StopTagged work on a run whose trigger has recorded: false.
  • Value checks. A check against a record type names every missing, unknown and wrong field at once.
    • Cast errors label each problem with its field, item or key.
    • Unknown keys are capped at 20 and escaped.
    • Checking union members stops at the first problem.

What breaks

  • A shared trigger whose runs reach per-instance nodes is refused when it is turned on or fired. It shows as an error in the editor.
  • A loop output nothing inside the loop writes is refused.
  • Programs that hit the include problem need weft resync after updating.

The CHANGELOG entry is 2026-11-01 (0.2.283).

Checked locally

Everything the PR's checks run, on this branch's final code:

  • nextest (4623 passed), doc tests, workspace clippy -D warnings, the parse-only build, validate-examples, hakari, terraform validate and the moved-targets test;
  • every db test (584 passed);
  • node tests for api, postgres, llm and storage;
  • every JS package test, the VS Code extension test and compile, the bridge, Postgres credential and Tangle plugin tests;
  • the browser extension's tsc and svelte-check;
  • the docs build;
  • setup.sh and the named e2e tests (the include outage shape, an outputless loop, a typed route body).

…ck an instance

An included file is per instance only at the sites an instance's value
reaches: the mark is kept per place (node and include path), and every
reader (engine, run refusals, activation, infra, displays, rules, the
editor's view of an included file) asks it of a place. A shared trigger
whose runs would reach something per instance is refused by the
compiler, at that site only (broken parts now name their places); routes
and sockets stay exempt since each call names its instance.

Also:
- a loop with no outputs ends (its LoopOut starts with each iteration);
  a loop output nothing inside writes is refused (loop-output-unwritten)
- a file stored for its run only and wired into a node that keeps its
  inputs past the run is warned about (run-file-kept-past-run), from two
  new metadata keys, fileScopeFrom and keepsInputsPastRun
- tags work on unrecorded runs
- a value checked against a record names every missing, unknown and
  wrong field at once, casts label each problem, unknown keys are capped
  and escaped, and union probing stops at the first problem
- docs, Tangle copies and the changelog follow
@qfeuilla
qfeuilla merged commit f6e56c1 into main Nov 1, 2026
26 checks passed
@qfeuilla
qfeuilla deleted the compiler-engine branch November 1, 2026 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant