Source-attached probes for execution inspection in a FROG IDE
FROG — Free Open Graphical Language
- 1. Overview
- 2. Document Role
- 3. Repository Navigation
- 4. Architectural Position and Dependencies
- 5. Ownership Boundary
- 6. Design Principles
- 7. Probe Model
- 8. Probes vs Watches
- 9. Probe Target Model
- 10. Probe Kinds
- 11. Probe Lifecycle and States
- 12. Observation Semantics
- 13. Live, Paused, and Retained Views
- 14. Edge Probes
- 15. Port Probes
- 16. Local-Memory Probes
- 17. UI-Related Probes
- 18. Presentation and Management
- 19. Validation and Safety Rules
- 20. Illustrative Examples
- 21. Directory Navigation
- 22. Out of Scope
- 23. Summary
This document defines the probe model of a FROG IDE. A probe is an IDE-managed, source-attached inspection object associated with one source-visible execution target so that a user can inspect source-aligned execution observations.
A probe does not redefine execution semantics. It consumes the source-aligned observability already exposed to the IDE and presents that information in a local inspection form suitable for diagram-centric workflows.
Probes are primarily designed to make ordinary dataflow understandable at the level of:
- edges,
- node ports when needed,
- local-memory state when supported,
- certain UI-related execution objects under compatible observability support.
execution-facing systems
|
v
execution observability
|
+-----------+-----------+
| |
v v
local probe centralized watch
source-attached persistent list entry
diagram-centric monitoring-centric
A probe therefore belongs to the IDE inspection layer. It may be used together with debugging, but it is not itself a debugger control object.
This document is the probe-focused document of the IDE/ family.
Its role is to define local, source-attached inspection behavior built on top of the shared observability layer.
It should be read together with:
IDE/Readme.mdfor the overall IDE architecture and document map,IDE/Observability.mdfor the source-aligned observable projection consumed by probes,IDE/Debugging.mdfor pause, resume, break, and step behavior used together with probes,IDE/Watch.mdfor centralized persistent inspection behavior distinct from probes.
This document is intentionally modular. It defines probe behavior only. It does not absorb execution semantics, debugger control, full watch behavior, or runtime-private observability mechanisms.
The most relevant repository files and directories for this document are:
IDE/
├── Readme.md
│ -> overall IDE architecture and document map
├── Observability.md
│ -> source-aligned execution observability consumed by probes
├── Probes.md
│ -> this document
├── Watch.md
│ -> centralized persistent inspection distinct from probes
└── Debugging.md
-> interactive debugging behavior compatible with probes
Upstream repository areas that matter for probes are:
Expression/
├── Diagram.md
└── Widget interaction.md
Language/
├── Control structures.md
└── State and cycles.md
IR/
├── Execution IR.md
└── Derivation rules.md
Libraries/ and Profiles/
└── ... executable capability surfaces observed through source-aligned projection
This navigation matters because probes depend on a clean chain: source-visible targets, validated execution meaning, execution-facing attribution, source-aligned observability, and finally local IDE-side inspection.
This document belongs in IDE/ because it defines how an IDE inspects execution through source-attached probe objects.
It does not belong to Language/ because it does not own execution meaning.
It does not belong to IR/ because it does not own execution-facing derivation.
This document depends on the following specifications:
IDE/Readme.md— architectural role of observability, debugging, probes, and watches in the IDE layer,IDE/Observability.md— source-aligned observable projection consumed by probes,IDE/Debugging.md— pause, resume, stepping, and breakpoint behavior used together with probes,IDE/Watch.md— centralized persistent inspection behavior distinct from probes,Expression/Diagram.md— canonical node, port, and edge representation,Expression/Widget interaction.md— source-visible widget interaction paths,Language/Control structures.md— normative structure execution meaning,Language/State and cycles.md— normative local-memory and cycle behavior,IR/Execution IR.md— execution-facing identity and attribution posture,IR/Derivation rules.md— source-to-execution-facing correspondence rules.
Expression/ + Language/ + Libraries/ + Profiles/
|
v
IR/
|
v
IDE/Observability.md
/ \
v v
IDE/Probes.md IDE/Watch.md
IDE/Debugging.md
-> consumes the same observable world
-> remains ownership-distinct from probes
If a conflict appears, the following ownership rules apply:
Expression/remains authoritative for source-visible targets and canonical source identity,Language/remains authoritative for execution meaning, committed state, and safe observation boundaries,Libraries/andProfiles/remain authoritative for primitive-local and capability-local behavior,IR/remains authoritative for execution-facing attribution posture,IDE/Observability.mdremains authoritative for the observable projection exposed to tools,IDE/Debugging.mdremains authoritative for debugger controls,IDE/Watch.mdremains authoritative for centralized persistent watch behavior,IDE/Probes.mdremains authoritative only for source-attached probe behavior and meaning.
Expression/
owns what is source-visible and serializable
Language/
owns what execution means and when it is safe to observe
Libraries/ and Profiles/
own primitive-local and capability-local executable meaning
IR/
owns execution-facing attribution and derivation posture
IDE/Observability.md
owns the observable projection exposed to tools
IDE/Probes.md
owns local source-attached inspection behavior
A probe MUST attach to a source-visible execution target. A probe MUST NOT require the user to understand runtime-private buffers, queues, or scheduler artifacts.
A standard probe MUST NOT change program semantics. Adding, removing, opening, or closing a probe MUST NOT alter the meaning of the FROG graph.
Probe-visible values or states MUST correspond to committed source-level observations. A probe MUST NOT present speculative, half-updated, or otherwise incoherent source meaning as stable.
Because FROG is dataflow-based, the canonical first-class probe target is the source edge. This preserves the natural inspection model of observing values as they become available in the graph.
A probe is defined by local source attachment. It is not the same thing as a centralized persistent watch entry. A probe MAY be rendered inline, near its target, or in a detachable local view, but its semantic identity remains target-local.
Probes MAY be used during free-running execution, during a paused debug session, or in a retained post-execution view when supported. They are compatible with debugging, but they are not owned by the debugger command model.
The repository uses Profiles/ for optional standardized executable capability families.
This document may also refer to stronger or weaker probe support through observability support.
These notions MUST NOT be conflated.
- a capability family defines what executable capability surfaces exist,
- an observability support level defines how much source-aligned execution detail is exposed to probes.
FROG defines a minimal probe core. Stronger observability support MAY expose richer rendering, richer history, type-specific visualization, or custom probe forms, provided that the base semantic meaning remains preserved.
A probe is an IDE-managed inspection object associated with exactly one primary target. It receives compatible source-aligned observations and presents a user-facing inspection view of them.
Conceptually, a probe contains:
- a probe identifier,
- a primary target,
- a probe kind,
- a current probe-entry state,
- a last-known compatible observation when available,
- the relevant execution context for that observation when needed,
- an IDE-chosen display strategy.
A probe is not part of the canonical FROG Expression. It is an IDE-side inspection construct layered over execution observability or retained post-execution inspection. Creating or removing a probe MUST NOT modify the source program.
Probes and watches consume the same underlying observability space, but they serve different workflows.
same underlying observations
|
+----------------------+----------------------+
| |
v v
probe watch
local attachment centralized persistence
target-centric list-centric
diagram-centric monitoring-centric
A probe is primarily local and target-centric. It is typically used near the source-visible object being inspected and is naturally diagram-centric.
A watch is primarily persistent and centralized. It belongs to a watch list or equivalent IDE-managed collection intended for cross-navigation and longer-lived monitoring.
An IDE MAY allow:
- creating a probe from a source target,
- creating a watch from a source target,
- creating a watch from an existing probe target,
- creating a probe from an existing watch target.
However, a probe MUST NOT be treated as merely a differently rendered watch. Its defining property is source attachment.
A probe MUST attach to exactly one primary source-visible target. A primary probe target MAY be:
- a source edge,
- a source node input port,
- a source node output port,
- a local-memory slot owned by a local-memory node instance,
- another source-visible target supported by the active observability support.
When repeated observations of the same target would otherwise be ambiguous, a probe MUST preserve sufficient execution context to disambiguate them. Relevant context MAY include:
- execution instance identity,
- sub-FROG stack,
- structure nesting,
- selected region identity,
- loop iteration identity,
- activation identity.
A probe target defines where inspection is attached. The active observability support defines how much compatible observation can actually be exposed for that target.
probe entry
├── primary target
│ └── edge / port / local_memory / supported source-visible target
├── latest compatible observation
│ └── committed value or committed state snapshot
└── execution context
├── instance
├── subfrog stack
├── structure stack
├── selected region
├── iteration
└── activation id
The minimum probe baseline requires support for:
edge_probe
This is the only required probe kind for a minimal conforming probe implementation.
Additional standardized probe kinds MAY include:
port_probe,local_memory_probe.
These kinds are standardized so that compatible implementations can expose the same meanings, but they are not part of the minimum baseline.
A stronger observability support MAY additionally support:
ui_sequence_probe,structure_probe,custom_probe.
Among all probe forms, edge_probe is the canonical and most important probe kind.
It is the primary inspection form for ordinary dataflow values.
A probe is created when the IDE attaches a new probe object to a valid target. Creation MUST fail if the requested target is not a valid probe target under the active observability support.
A probe MAY conceptually be in one of the following states:
created— the probe exists but has not yet received a compatible observation,live— the probe is receiving live execution updates,paused— the probe reflects a paused consistent snapshot,retained— the probe shows a retained post-execution observation when supported,unavailable— the target exists but no compatible observation is currently available,closed— the probe has been removed.
These are probe-entry states. They MUST NOT be confused with the execution state of the underlying live instance.
Removing a probe affects only the inspection layer. It MUST NOT alter the graph, execution semantics, source identity, or debugger control state.
A probe does not invent values. It displays values or source-aligned state only when those observations become available through the observability model exposed to the IDE.
The primary semantic model of a probe is the last-known committed observation. This means the most recent committed source-level value or state snapshot observed for the probe target in the relevant execution context.
If a probe target receives multiple compatible observations over time, the base model requires that the probe be able to show at least the most recent one. A stronger support level MAY additionally retain a bounded history or a richer time-oriented representation.
A runtime is not required to expose a fully materialized value for every observation. A probe MAY therefore display:
- a full value snapshot,
- a summarized preview,
- a type-aware rendering,
- an opaque placeholder indicating availability without a full displayable value.
Whatever rendering strategy is used, the semantic meaning MUST remain that the probe refers to a compatible committed observation for its target.
If no compatible committed observation exists yet, the probe MUST remain unavailable rather than implying that a value exists.
A probe MUST NOT imply that a full historical sequence exists unless such history is actually preserved by the active observability support.
running execution
|
├── compatible committed observation arrives
| └── probe may update live
|
├── debugger pauses at safe boundary
| └── probe must match paused snapshot
|
└── execution ends
└── probe may become retained if supported
During a running execution, a probe MAY update as new compatible committed observations become available. The exact refresh cadence is implementation-defined.
When a debug session is paused, probe-visible information MUST match the paused execution snapshot exposed to the IDE. A probe MUST NOT show values or state that contradict the paused source-level view.
A stronger observability support MAY support retained probe values after execution has completed, faulted, aborted, or otherwise ended. If retained values are supported, the IDE MUST clearly distinguish them from:
- live-updating values,
- paused-snapshot values.
When retained behavior is supported, a retained observation SHOULD remain attributable to the execution instance from which it was derived. An IDE MUST NOT silently conflate retained observations from unrelated instances.
An edge_probe is attached to one source edge.
It is the canonical probe kind for ordinary dataflow inspection in FROG.
An edge probe is updated when the target edge receives a compatible observable edge_value_available observation in the relevant execution context, or when an equivalent paused committed observation confirms the current edge value.
The meaning of an edge probe is:
show the last-known committed value
that became available on this source edge
in the relevant execution context
If one source output fans out to multiple edges, each edge MAY have its own probe. This is correct because source-level inspection is naturally edge-based even if the runtime internally optimizes fan-out.
If the same edge is activated across different iterations or nested scopes, the probe SHOULD preserve the relevant context. A stronger support level MAY show iteration metadata or a visible context stack together with the displayed value.
A port_probe is attached to a specific source node port rather than to a full edge.
This is useful when the IDE wants to present inspection at the node boundary level.
A port probe MAY target:
- an input port,
- an output port.
When the source graph already provides an explicit edge identity for ordinary valueflow, an implementation SHOULD prefer edge probes for canonical dataflow inspection. Port probes are an additional inspection form, not the preferred default for ordinary wire-level understanding.
A port probe attached to an output port SHOULD be semantically equivalent to probing the emitted committed value at that source boundary. A port probe attached to an input port SHOULD reflect the committed value received at that input in the relevant execution context.
A local_memory_probe is attached to the local-memory slot owned by a local-memory node instance.
Its purpose is to inspect source-aligned memory behavior rather than only ordinary edge values.
For frog.core.delay, a local-memory probe SHOULD make it possible to inspect at least, when the active observability support exposes the corresponding information:
- the most recent observed
state_read, - the most recent observed
state_updated, - the current stored state visible at pause time.
A local-memory probe is not merely another edge probe. It is attached to the stateful source-aligned object owned by the node instance. It therefore observes local-memory activity without redefining primitive-local behavior or language-level cycle semantics.
If a local-memory probe displays a current stored value during a paused snapshot, that value MUST be the committed stored value for the paused execution instance.
delay node instance
├── observed state_read
├── observed state_updated
└── paused current stored value
(only when exposed by the active observability support)
Ordinary widget-related valueflow SHOULD be inspected through the same canonical mechanisms as other dataflow:
- edge probes on edges connected to
widget_value, - port probes on relevant widget-related ports when supported.
Object-style widget interaction through widget_reference, frog.ui.property_read, frog.ui.property_write, and frog.ui.method_invoke MAY be inspected through:
- ordinary valueflow targets when relevant,
- pause-consistent debug inspection,
- stronger-support UI-specific probe renderers.
For ordinary widget value participation in dataflow, tools SHOULD prefer the natural widget_value representation rather than object-style property access.
The ui_in / ui_out sequencing edges are not ordinary data-value edges.
A stronger observability support MAY support probes on these edges, but such probes MUST be interpreted as effect-order inspection rather than ordinary value inspection.
If supported, such probes MUST remain aligned with both:
- the source-facing widget interaction model,
- the relevant
frog.ui.*primitive definitions.
This document does not standardize one required probe window layout. It standardizes the source-level meaning of probe displays.
A probe display SHOULD be able to show at least:
- the probe target identity,
- the most recent compatible observation when available,
- basic state information such as live, paused, retained, or unavailable,
- basic execution-context information when relevant.
An IDE MAY present probes through:
- inline overlays near the target,
- detachable probe windows,
- a probe inspector pane,
- another equivalent local-inspection presentation.
A probe-capable IDE SHOULD support at least:
- create probe,
- remove probe,
- list active probes,
- locate a probe from its source target,
- locate the source target from its probe entry.
A stronger observability support MAY additionally support:
- pinning a probe window,
- grouping probes by FROG or by execution instance,
- sorting by creation order,
- showing last-update timestamps,
- bulk removal.
An IDE MAY assign probe numbers or names for management purposes. Such naming is an IDE concern only and is not part of the canonical source model.
- A probe MUST target a valid source-visible object supported by the active observability support.
- A probe MUST NOT alter execution semantics.
- A probe shown during pause MUST reflect the paused execution snapshot exposed to the IDE.
- A retained probe value MUST be clearly distinguishable from a live-updating value and from a paused-snapshot value.
- A probe MUST NOT expose a contradictory combination of target identity, execution context, and observation.
- A local-memory probe MUST respect node-instance-local memory scope.
- A UI-sequencing probe, if supported, MUST NOT be misrepresented as an ordinary data-value probe.
- A probe MUST NOT be presented as a watch entry unless the IDE explicitly re-exposes that target through the watch model.
- A probe MUST NOT silently conflate observations from unrelated execution instances when retained behavior is supported.
The examples below are illustrative only. They show possible probe-facing representations. They are not a required transport format.
{
"probe_id": "p1",
"kind": "edge_probe",
"target": {
"kind": "edge",
"id": "e_sum"
},
"state": "live",
"last_observation": {
"preview": "17.5"
}
}{
"probe_id": "p2",
"kind": "port_probe",
"target": {
"kind": "port",
"node_id": "add_1",
"port": "result",
"direction": "output"
},
"state": "paused",
"last_observation": {
"preview": "17.5"
}
}{
"probe_id": "p3",
"kind": "local_memory_probe",
"target": {
"kind": "local_memory",
"node_id": "delay_1"
},
"state": "paused",
"last_observation": {
"preview": "5.0"
},
"details": {
"last_event": "state_updated"
}
}{
"probe_id": "p4",
"kind": "edge_probe",
"target": {
"kind": "edge",
"id": "e_output"
},
"state": "retained",
"instance_id": "run_42",
"last_observation": {
"preview": "42"
}
}This document is easier to use when read together with the neighboring IDE documents:
IDE/
├── Readme.md
│ -> overall IDE ownership, components, and document map
├── Observability.md
│ -> source-aligned execution visibility consumed by probes
├── Probes.md
│ -> this document; local source-attached inspection
├── Watch.md
│ -> centralized persistent inspection distinct from probes
└── Debugging.md
-> interactive debugging behavior compatible with probes
For readers following repository ownership boundaries, the main cross-layer path is:
Expression/
-> what source-visible probe targets exist
Language/
-> what execution means and when observation is coherent
IR/
-> what execution-facing attribution preserves
IDE/Observability.md
-> what source-aligned observations are exposed
IDE/Probes.md
-> how those observations are consumed locally
- conditional probes that trigger debugger break behavior,
- watch expressions over arbitrary graph expressions,
- mandatory history buffers for every probe,
- reverse-time probe inspection,
- standardized distributed probe aggregation,
- remote probe streaming protocols,
- probe-driven execution modification,
- mandatory custom-probe packaging and discovery rules.
FROG probes are source-attached inspection objects for live, paused, and optionally retained execution views. The canonical probe model is centered on ordinary dataflow inspection through source edges, while also allowing additional probe forms for ports and local memory when supported.
This specification establishes that:
- probes belong to the IDE inspection layer rather than the source language itself,
- probes consume execution observability but do not own debugger controls,
edge_probeis the minimum and primary probe form,- probe-visible values represent compatible committed observations,
- paused probe views must remain causally consistent,
- retained values are optional and must be clearly identified as such,
- probes remain distinct from centralized watch entries,
- stronger support may add richer or more specialized probe forms without changing the base semantics.