[wip] let a plugin's action call another plugin's action as a sub-action - #213
Draft
dhvanipa wants to merge 13 commits into
Draft
[wip] let a plugin's action call another plugin's action as a sub-action#213dhvanipa wants to merge 13 commits into
dhvanipa wants to merge 13 commits into
Conversation
dhvanipa
marked this pull request as draft
August 13, 2026 17:55
dhvanipa
force-pushed
the
dhvanipa/swap-recipes
branch
from
August 17, 2026 03:50
ce71d79 to
d3f3319
Compare
dhvanipa
force-pushed
the
dhvanipa/swap-recipes
branch
from
August 17, 2026 07:10
d3f3319 to
6e7b2a4
Compare
…eceipt-free swap-log-sticks example
dhvanipa
force-pushed
the
dhvanipa/swap-recipes
branch
from
August 17, 2026 08:01
6e7b2a4 to
9329963
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds cross-plugin composition: a script can call another plugin's action by qualified name, so one transaction can act on objects whose classes are defined by different plugins.
Calling the other plugin's action is the only way to touch its objects: a class is the OR over the actions of the script that declares it, so a local mutate("Log") would be a different predicate and could never spend a craft-basics log.
Sub-action rather than sibling top-level actions, because the parent predicate's range spans both halves and can constrain one against the other — the receipt is pinned to the object the nested call just claimed. Siblings in one transaction can prove no relation between each other (test_imported_batch_action_as_subaction).
Changes
SDK — SubRef parses plugin::Action; PluginDeps carries dependency modules through load and execute. Imported object refs are stamped with the plugin that owns their class. Only plugins actually reached are imported, so an unused dependency cannot move the module hash. Rendering — imported calls render as dep_::; records are not importable, so each imported io shape is re-declared locally with entry order preserved. An all-sub-action action now compiles without an io record (podlang has no empty-record form). pod2utils — predicate resolution rejects ambiguity instead of taking the first match, and returns Result instead of panicking. Two plugins may each define Claim; first-match would silently prove the wrong batch. New _in variants skip resolution when the batch is already known.
Manifest [[imports]] — each entry names a dependency, its pexe path, and an optional batch id to pin. This is the only build-time resolution: the declared set must match the script's qualified calls exactly. Pins turn version drift into a message naming the import rather than a whole-plugin hash mismatch. Installed catalogs still resolve by name, topologically ordered with cycles rejected.
Examples
swap-log-copper — reaches into two plugins and mints its own receipt.
swap-log-sticks — one log against two sticks, no receipt: three survivors plus chain overhead land exactly on pod2's 8-wildcard budget.
Rekey actions on craft-basics and craft-rocket. Calling a dependency embeds its batch id in the caller's, so craft-basics' module_hash moves and both swap examples rebuild against it.