Skip to content

[wip] let a plugin's action call another plugin's action as a sub-action - #213

Draft
dhvanipa wants to merge 13 commits into
mainfrom
dhvanipa/swap-recipes
Draft

[wip] let a plugin's action call another plugin's action as a sub-action#213
dhvanipa wants to merge 13 commits into
mainfrom
dhvanipa/swap-recipes

Conversation

@dhvanipa

@dhvanipa dhvanipa commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

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.

fn SwapLogCopper(action) {
    var log     = action.subaction("craft-basics::RekeyLog");
    var copper  = action.subaction("craft-rocket::RekeyCopper");
    var receipt = action.output("Swapped");
    receipt.set([["swapped_at", state_header.block_timestamp]]);
}

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.

@dhvanipa
dhvanipa marked this pull request as draft August 13, 2026 17:55
@dhvanipa dhvanipa changed the title [draft] swap action [wip] swap action Aug 13, 2026
@dhvanipa
dhvanipa force-pushed the dhvanipa/swap-recipes branch from ce71d79 to d3f3319 Compare August 17, 2026 03:50
@dhvanipa
dhvanipa changed the base branch from main to local-dev August 17, 2026 03:50
Base automatically changed from local-dev to main August 17, 2026 06:58
@dhvanipa
dhvanipa force-pushed the dhvanipa/swap-recipes branch from d3f3319 to 6e7b2a4 Compare August 17, 2026 07:10
@dhvanipa
dhvanipa force-pushed the dhvanipa/swap-recipes branch from 6e7b2a4 to 9329963 Compare August 17, 2026 08:01
@dhvanipa dhvanipa changed the title [wip] swap action [wip] let a plugin's action call another plugin's action as a sub-action Aug 17, 2026
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