Skip to content

feat(mdl): alter microflow target resolver and describe … with handles - #730

Merged
ako merged 4 commits into
mainfrom
feature/713-alter-microflow-target-resolver
Sep 27, 2026
Merged

ako merged 4 commits into
mainfrom
feature/713-alter-microflow-target-resolver

Conversation

@ako

@ako ako commented Sep 26, 2026

Copy link
Copy Markdown
Owner

Closes #713. This is the first step of alter microflow (plan item 4.2a, ADR-0012 decision 2).

What it adds

  • mdl/backend/mfmutator: a content-addressed target resolver that works on the stored object collection, loop bodies included. A target can be:

    • an output variable ($IsValidEmail),
    • a custom caption ('Email is Valid?'),
    • a statement pattern where * matches any run of words.

    Any of them can end in @n. When there is no match, the error gives hints. When several activities match and no @n is given, the error lists them (<target> @n -- <statement> at (x, y)); it never guesses.

  • describe microflow M.X with handles prints -- handle: <target> above each activity. The handles are comments, so the output still runs unchanged. Every handle is checked by resolving it back. It refuses to combine with normalized.

Design choices (not settled by the ADRs)

  1. The address forms never fall back on each other. $Var only means an output variable, and a quoted string only means a caption.
  2. A pattern must match the whole statement. commit $Order does not match commit $Order with events; write commit $Order *.
  3. Matching is word by word, not by exact text. Keywords and names match regardless of case; $variables and string literals match exactly.
  4. A pattern matches both the printed and the stored form of a statement, because describe prints some ifs with a negated condition.
  5. Ordinals follow the order describe prints the activities.
  6. Only custom captions address an activity.
  7. with handles and normalized cannot be combined.
  8. A caption containing a line break falls back to its statement as the handle.

Tests

  • Unit tests in mdl/backend/mfmutator and in executor tests on the mock backend. They cover each address form, ambiguity errors, ordinals, whole-statement matching, the round trip from handle to activity, and a control showing that output minus the handle lines equals plain describe.
  • PedApp tests on the Studio Pro-authored FeedbackModule.VAL_Feedback (gated by MXCLI_PEDAPP_MPR until Round-trip harness: describe → exec on the Studio Pro PedApp fixture must write nothing #725's fixture lands):
    • every form resolves to the right activity;
    • set $ValidFeedback = false is refused, listing its three matches;
    • all 16 handles resolve to the activity whose @position follows them.
  • Revert checks:
    • removing SetPrinted breaks the resolver and negated-if tests;
    • moving the warnings in front of the line numbers puts handles above the wrong activities.

Checks run

Follow-ups

🤖 Generated with Claude Code

ako and others added 4 commits September 26, 2026 22:05
Start of mfmutator (mdl/backend/mfmutator), alongside pagemutator and
wfmutator: a content-addressed target resolver over the stored microflow
object collection (ADR-0012 decision 2, proposal item 4.2a).

A target addresses an activity by output variable ($Lines), by caption
('Email is valid?'), or by statement pattern with * wildcards
(commit $Order *), optionally with an @n ordinal. A target matching more
than one activity is an error listing each match with its ordinal; the
resolver never guesses. Patterns match the statement as describe prints
it and as it is stored, since describe negates an if whose then-branch
is empty.

describe microflow M.X with handles prints "-- handle: <target>" above
each activity. The handles are comments; removing them leaves the plain
description (tested as a control).

Tested on Studio Pro-authored FeedbackModule.VAL_Feedback via
MXCLI_PEDAPP_MPR until the PedApp fixture lands (#703).

Refs #713, #714

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Activities inside an `on error { … }` block were rendered by a second
describer that never wrote the source map, so describe … with handles
printed no handle for them and the resolver counted them after the whole
main flow. On PedApp's SUB_Feedback_PostToAppInsights, `return * @1`
picked `return $Response` although describe prints the handler's
`return empty` first: an ordinal a reader counted selected another
activity.

The handler traversal now reports each object's statement span and the
emitters record it (also in the ELK sourceMap, additively).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The output-variable switch was a copy of actionOutputVariableName and had
drifted from the formatter: a REST call whose result is on its result
handling (PedApp's $Response), a cast, create list, web service call,
REST operation call, database query, XML/JSON and workflow actions all
print `$X = …` yet `$X` found nothing. It now reads the variable where
describe does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe prints an activity it cannot render as `-- Unsupported …`.
Used as a statement, that became the handle `-- handle: -- Unsupported
action type: …`, which the lexer swallows as a comment when pasted into
an alter target, and `*` matched it. Such an activity is now addressed
only by its variable or caption, or listed in an ambiguity error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ako
ako merged commit 3f6dba9 into main Sep 27, 2026
15 checks passed
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.

alter microflow: content-addressed target resolver (output variable, caption, statement pattern)

1 participant