Skip to content

fix(migrate): count only written sends as senders, note UI-posted specializations, keep a misrouted send's argument note, name only written clock waits - #804

Merged
HuiJun merged 4 commits into
developfrom
fix/migrate-sender-and-wait-notes
Oct 2, 2026
Merged

HuiJun merged 4 commits into
developfrom
fix/migrate-sender-and-wait-notes

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

What and why

Follow-up to #791, addressing the four post-merge review findings on its ledger logic. All four are generic to the migrator's report; no notation changes (the TMT export migrates to a byte-identical TMT.sysml, -validate still 0 errors; only the order of two joined notes moves).

  1. A refused send no longer counts as a sender. recordSender indexed every SendSignalAction/BroadcastSignalAction during prepare, including one sendRefusal later writes as a placeholder (absent/dry/misfit argument), so an accept of a signal only the tool's UI prototype posts went un-noted when such a placeholder existed. Now sendSignal marks senders.sent[sig] only after it emits send new …;, and the UI-only notes are deferred: uiAccept records each accept (transition trigger, accept action) during writing, and uiOnlyAccepts — run after placeholderEnds, when every send is decided — annotates them through the report's pending-note path, so timing and verdict are unchanged for the cases already covered.

  2. A button posting a specialization raises the note. unsentNote only looked up buttons[sig]; a button posting Long Pause :> Pause left an accept of Pause unnoted although the accept takes the specialization. buttonsPosting now counts buttons posting sig or a signal inheriting from it (m.inherits, the same test sentByAction already used for sends) and the note names the specializations:
    no send action of the document sends 'Pause' or a signal specializing it ('Long Pause'), which only 1 button ….

  3. A send on a port that is not the sender's keeps its argument note. Both invalid-port branches of sendSignal assigned note = …, overwriting the argument note signalArguments had produced; they now joinNotes, like the target-pin branch already did.

  4. clockWaitIn names only waits the writer writes. It reported a duration constraint as a wait whenever it had an interval (waitBound), and a time-event accept whenever the trigger named a TimeEvent, and followed called behaviors/methods regardless of whether the callee is written. An entry/exit/effect whose only "wait" the writer leaves as a placeholder (interval open above, time it cannot spell, callee without a v2 declaration) was therefore noted as stopping a run at a wait that does not exist. The duration decision is now factored into migration.waitOf, shared by activity.waitFor (the writer) and clockWaitIn; acceptsTime asks acceptClause (pure) whether the first trigger is writable, with the same scope the writer uses (n.Parent is the activity or structured node whose activity.act writes it); and a call is followed to its callee only when the writer emits it as an invocation: clockWaitIn links the caller's graph as the writer does (scanGraph: newActivity → link/resolveData/deaden, without writing) and activity.invokes applies the writer's own rules — a call refusal refuses (unbound context, undeclared callee, no operation) is a placeholder, a library primitive is no call, an operation written as a usage whose target pin resolves no receiver is written as the empty step; a node whose pin nothing fills is skipped, as the writer writes it without its wait.

Also carries the one-line shaped(mult, r, true, false) repair from #800, which develop needs to build; it drops out of this diff when #800 lands.

Specification basis

No runtime behaviour or compliance row moves; this is the migrator's ledger. UML 2.5.1 §13.3.3 (an accept of a signal takes instances of its specializations) is why a specialized posting counts for an accept of the general signal, on the UI side as it already did on the send side (docs/reference/sysml-v1-migration.md, SignalEvent and instant-wait rows updated).

How it was verified

  • tests/migrate/ui_stimuli.xmi + TestSignalsOnlyTheToolsUIPostsAreLedgered: added Pause/Long Pause :> Pause with a button posting Long Pause (finding 2), and Resume with a required delay attribute, a send of it without an argument (a placeholder) and a button posting it (finding 1); _trPause and _trResume are noted, _sendResume carries its own argument note.
  • tests/migrate/instant_waits.xmi + TestInstantBehaviorsWaitingForTheClockAreLedgered: added transition effect Send Ack Hold calling Hold (duration constraint with only a min → unmapped) and accepting an absolute time event whose time names nothing (→ placeholder); the effect gets no "waits for the clock" note while the existing four waits still do (finding 4); added Send Ack Settle, calling Relay::Settle (accepts a time event, reads gain through its context) from a Stimulus that cannot bind it — a placeholder — and Send Ack Pause, calling Delay through a target pin nothing feeds — never fires; neither is noted as waiting. Checked the never-fires shape against the runtime: an unconnected action call : Delay; beside first start then final; action final terminate; completes at clock 0.0, the connected one at 2.0.
  • TestSendOnAnotherObjectsPortKeepsItsArgumentNote (new, in signal_absent_argument_test.go): a send with a surplus argument pin on another block's port; the note joins both reasons (finding 3).
  • Full gates on the branch with the four corpora downloaded and required: go build ./... && go vet ./... && gofmt -l . clean; go test -count=1 ./... all packages ok (incl. tests/corpus, tests/export, tests/identity, tests/model, tests/migrate); python3 scripts/changelog.py check ok.
  • TMT (TMT-2024x.mdzip + MTIP layout): migrated notation byte-identical to develop+fix(migrate): pass the uniqueness argument the read result pin's shaped multiplicity takes #800; -validate 0 errors; migration report differs only in the order of the two joined notes on the PEAS Abort and MBClock tick triggers (the UI-only note is now appended after the port note).

Checklist

  • make test and make lint pass locally
  • Tests added or updated for the change
  • Documentation extended where it already covers the surface (see CONTRIBUTING.md)
  • Changelog entry added as changes/unreleased/<slug>.<section>.md, not as an edit to CHANGELOG.md
  • baselines regenerated and make docs-counts run if a gate count moved (compliance rows need nothing: the census is counted at docs build)
  • No internal work-item labels (waves, slices, F4, K5) in the body, docs, or changelog

devin-ai-integration Bot and others added 2 commits October 1, 2026 22:34
…ed multiplicity takes

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…cializations, keep a misrouted send's argument note, and name only written clock waits

A send action refused as a placeholder performs nothing, so it no longer counts as a sender of its signal: an accept of a signal only the tool's UI prototype posts is noted once every send is written. A button posting a signal specializing the accepted one raises the same note, naming the specialization. A send on a port that is not the sender's keeps its argument note beside the port note. An entry, exit or transition effect is noted as waiting for the clock only for a wait the writer writes: a duration constraint written as a wait, a time event whose time is spelled, or a called behavior that has a v2 declaration.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@HuiJun
HuiJun marked this pull request as ready for review October 1, 2026 23:18
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits October 1, 2026 23:33
…e call is written invoking it

A clock wait in a behavior named by a call written as a placeholder — one the
writer refuses, its context unbound or its callee undeclared — or by a call
that never fires, its target pin fed by nothing, is no wait of the caller:
the writer invokes nothing there. The clock-wait scan now links the caller's
graph as the writer does and follows only the calls written as invocations,
skipping a node whose pin nothing fills, as the writer writes it without its
wait.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit ff211c4 into develop Oct 2, 2026
46 of 48 checks passed
@HuiJun
HuiJun deleted the fix/migrate-sender-and-wait-notes branch October 2, 2026 01:07
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