Runtime Events
GFRM now emits an ordered runtime event stream for each run.
What it is for
Runtime events are meant for:
- runtime observability
- test assertions
- live GUI progress updates
They complement the operator-facing artifacts, but do not replace summary.json, failed-tags.txt,
migration-log.jsonl, or gfrm resume.
Ordering and sinks
- event ordering is authoritative per run
- supported sinks in this release: console, JSONL, in-memory, and reducer consumers
- sink-specific formatting stays outside the ordered publisher
- sinks now declare an explicit failure mode:
optionalormandatory
The JSONL sink is a runtime-event consumer implementation. The public run artifact for operators remains
migration-log.jsonl.
Failure policy
optionalsinks are best-effort: failures are logged and the run continuesmandatorysinks fail the run immediately when they cannot consume an event
Use mandatory only when the consumer is part of the required runtime contract for your embedding layer.
Derived RunState
The reducer sink can derive a typed RunState snapshot from the ordered event stream.
The current snapshot model includes:
- lifecycle status
- active phase
- preflight summary
- tag and release counters
- per-tag and per-release progress entries
- artifact paths
- retry command and final completion status
- latest failure context
This state is meant for GUI, tests, and in-process diagnostics. It stays provider-agnostic and replay-safe because it is derived only from the canonical runtime events above.
Desktop Run Progress
The desktop Run Progress screen displays lifecycle, active phase, and separate tag/release counters for created, would-create (dry-run), skipped-existing, and failed items. Its item table displays the typed progress entries. Completion status and the latest failure remain visible when a run finishes.
The screen reads the current DesktopRunController snapshot on entry and updates through its snapshot stream,
mapped from shared RunState. It does not parse terminal output or advance counters on a timer. With no run,
it displays an empty state; a stream failure displays an update warning while retaining the current snapshot.
Starting a migration from the wizard is still unavailable. This screen observes runs started through the typed desktop controller; retry/cancel actions are separate work.
Desktop Migration Results
The desktop Results screen reads the same current snapshot and stream. Before a run finishes it shows an empty
or in-progress state. Once the lifecycle is completed or failed, it shows the final lifecycle, completion outcome
when reported, total/failed tag counts, and separate tag/release outcome counters. A completed lifecycle is not a
success verdict: a run with partial_failure keeps that outcome visible. Failure details include the reported code,
phase, and message, including failures before artifacts are available. Failed tag/release entries also show their
item identity and reported message, even when a partial failure has no run-level exception.
Artifact paths for summary.json, failed-tags.txt, and migration-log.jsonl appear only when reported by the
runtime. The screen displays selectable paths without opening files or checking whether they still exist.
Retry guidance appears only when the final snapshot supplies a nonempty resume command; a failure count alone does
not create one. You can select that command for use in a terminal. Executing retries and opening artifacts from the
GUI remain separate work.
Entering Results after completion shows the current snapshot without waiting for another event. A stream error shows a warning while retaining current results; starting a new run replaces the previous results with its pending state. This screen does not read terminal output or reconstruct results from artifact files.
Event families
Examples of runtime events exposed in this release:
run_startedpreflight_completedtag_migratedrelease_migratedartifact_writtenrun_completedrun_failed
These events can mirror progress state and written artifact paths, including summary.json and failed-tags.txt.
run_started Event Structure
The run_started event is emitted as part of the ordered runtime event stream. In the JSONL sink, it is wrapped in a RuntimeEventEnvelope:
{
"event_type": "run_started",
"timestamp": "2026-04-20T20:30:00.000Z",
"payload": {
"source_provider": "github",
"target_provider": "gitlab",
"mode": "migrate",
"dry_run": false,
"skip_tags": false,
"skip_releases": false,
"skip_release_assets": false,
"settings_profile": "my-profile"
}
}
Envelope structure:
event_type: Always"run_started"timestamp: ISO 8601 timestamp when the event was emittedpayload: Event-specific data (see fields below)
Payload fields:
source_provider: Source forge (github,gitlab,bitbucket)target_provider: Target forge (github,gitlab,bitbucket)mode: Command name (migrateorresume)dry_run: Whether the run is in dry-run modeskip_tags: Whether tag migration is skipped (from--skip-tags)skip_releases: Whether release migration is skipped (from--skip-releases)skip_release_assets: Whether release asset migration is skipped (from--skip-release-assets)settings_profile: Optional settings profile name (if provided)
Public contract
Use runtime events when you need ordered runtime visibility inside the app, tests, or future GUI layers.
Use summary.json, failed-tags.txt, migration-log.jsonl, and gfrm resume when you need the public operational
contract for triage and recovery.