feat(runtrace): render a run's trace as a state timeline and a message sequence - #885
devin-ai-integration[bot] wants to merge 20 commits into
Conversation
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
End-to-end verification against 8300b2b, using the CLI, a real-terminal REPL session, and the Mermaid and PlantUML converters.
|
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
This branch now conflicts with
To resolve: merge current Planned merge order for the view and docs PRs: #889 → #881 → #871 → #882 → #884 → #885 → #886. Each needs these files regenerated again after the one before it merges. Re-run the full gate ( |
…derings Co-Authored-By: jason.han <hanhuijun@gmail.com> # Conflicts: # internal/doc/queryexec/events.go
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
…derings Co-Authored-By: jason.han <hanhuijun@gmail.com>
|
Hold on pushes: please don't push to this branch, including |
What and why
A running engine can draw a run's behaviour, which a static model view cannot. This PR renders the runtime's structured trace in two ways:
Representation: a new
view.KindTimeline, and reuse ofKindSequenceKindSequence. A run sequence has the same shape as a model sequence: lifelines plus ordered messages. The newinternal/exec/runtracepackage buildsRoots(one participant per object, plusenvironmentfor sends from outside the run) andEdges(messages in clock order). The existing text, Mermaid and PlantUML sequence writers then draw it unchanged, and DOT is refused as it already is for sequences.view.KindTimeline. No existing kind carries time-valued data.KindStateis the graph of declared states and transitions, not which states one object held between which instants.RenderinggainsRun,RunUntilandLanes(Lane/Span/LaneTransition/Mark).KindTimelineis not inKinds(), is not a pseudo-view (#timelineis refused), is never returned byKindOf, and is refused as a documentDiagramkind. The model stays plain SysML v2 and no library vocabulary is added.Forms
ganttwithdisplayMode: compactconcisetiming diagramsequenceDiagramganttin compact mode. Compact mode puts each lane on one row against a shared numeric time axis, with real durations. Mermaid'stimelinegrammar is a list of categorical periods, with no durations and no shared axis. Choice and guard records become%%comments plus a notice, because gantt has no notes.concise.robustneeds a fixed, ordered set of states per lane. Here a lane value is the active configuration of a machine, e.g. parallel leaveswaiting | charged, which is free text. Choice and guard records becomenote top of.a timeline rendering is not written as dot; ask for text, mermaid or plantuml.-render-runand%render-runwrite text, Mermaid and PlantUML, and a run timeline or sequence asked for as D2 is refused with an error that lists only those forms. Model sequences still render as D2.Runtime record additions
Entry, exit and do trace records now carry:
Path: the state qualified by the states written around it.Region: the innermost orthogonal region, qualified the same way.With these, the timeline can rebuild the active configuration and order parallel leaves by region. The printed trace text is unchanged and every existing
.trace.goldenis byte-identical.Three helpers moved so the query layer and the renderer share one implementation instead of duplicating it:
TraceRecord.Machine()andTraceRecord.PayloadTexts()moved frominternal/doc/queryexecintoruntime.StateExecutor.RegionOfnow holds the region walk thatqueryexecused before.Entry and exit records also carry
Source, the origin of the state's declaration, which source links use.Three further runtime additions keep the renderings correct:
runtime.MessagegainsSerial, a per-context number assigned when a message is posted. It is never rolled back by snapshots or journal rollback, and imported messages get fresh serials. Send and accept records carry it asTraceRecord.Message, so the sequence pairs an accept with the exact send it took, even when same-named signals from different definitions reach one object. Records without a serial fall back to matching by event and target.TraceTerminatekind records aterminateaction or the end of the occurrence performing a machine, with the clock instant and origin. Its printed line is the existing one. The timeline closes the lane's occupancy there and marks it, since termination abandons states without exiting them. Becauseterminateis a documentedEventskind, a state run's trace fromExecuteState(gRPC, clients and the browser engine) also reports it.left.waiting | right.waiting).The end instant comes from the clock, so the
run_start/run_endrecords proposed in the observing-a-run design are not needed yet.Timeline semantics
Surfaces
-render-run <timeline|sequence>=<path>, repeatable, declared next to-trace.-render-formor the path's extension (.txt,.mmd/.mermaid,.puml/.plantuml);-writes text to stdout.-tracealso asks for the printed trace.-schedule explore,-engine check|smt|all,-runs,-sweep/-samples,-record-run, model or document rendering,-convert/-migrateor-query.%render-run <timeline|sequence> [text|mermaid|plantuml|dot] [link=<template>]renders the trace recorded since%trace on, up to the current clock instant. Objects are labelled by the path the session reaches them by. The command has help and completion.-render-link <template>(CLI) andlink=<template>(REPL) apply to run renderings, following the source-link conventions the model renderings use:clicktargets carry no anchor in mermaid-cli SVG output.-jsonwith a-render-run ...=-stdout target (the JSON document would be broken), and-compare-results(it compares many runs, so there is no single trace).-render-documentrefuses-state/-advance, and a documentDiagramselects a model rendering. Embedding a run would need a document-level way to describe the run, which would be new model vocabulary. The limitation is documented indocs/project/view-rendering-forms.md.Long and truncated runs
not represented:notice reports how much was cut and the time range it covers.Example
examples/run-timeline/run-timeline.sysml: acontrollerand aninstrument, sibling parts joined by a connector. Each exhibits a state machine. Timers drive the controller to sendPing(seq)and the instrument to answerAck(seq). A parallel state gives a recorded choice point.Mermaid timeline (gantt, compact):
PlantUML timeline (concise):
Mermaid sequence:
PlantUML sequence:
PlantUML timeline with source links (lanes and single-state spans are links; parallel spans are not):
Specification basis
No specification behaviour changes: this is an output of the execution engine.
docs/project/spec-compliance.mdgains a "Run renderings" table covering the timeline, the run sequence, and the state-path and region fields on trace records.How it was verified
internal/exec/runtrace/testdata/, all new files:#<id>label escaped for PlantUML.internal/ir/view/run_timeline_test.go: form support forKindTimeline, and that it is neither a model kind nor a pseudo-view.internal/exec/runtime/trace_records_test.go: entry and exit records carry path and region.cmd/sysml/render_run_test.go: CLI artifacts, stdout output and every refusal.internal/frontend/repl/run_render_test.go: REPL output, path labels, the missing-trace error, form refusal and completion.internal/exec/runtime: message serials across snapshot restore, journal rollback and held-image import.git diff --diff-filter=M origin/develop -- '*.golden'is empty.validate-sysml-batchwith the OpenSysML library path).go build ./...,go vet ./...,gofmt -l .(empty),go test ./...,make docs-check,make docs-counts,make man-checkall pass.make docs-counts, including the headline lines thatTestW6FSkillDocumentCountsMatchBaselinepins.Checklist
make testandmake lintpass locally (go test ./...passes locally;make lintis left to CI)changes/unreleased/<slug>.<section>.md, not as an edit toCHANGELOG.mdmake docs-countsrun if a gate count moved (compliance rows need nothing: the census is counted at docs build)F4,K5) in the body, docs, or changelog