Persistent watch entries and centralized watch views 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. Watch Model
- 8. Watches vs Probes
- 9. Watch List Model
- 10. Watch Target Model
- 11. Watch Kinds
- 12. Observation Semantics
- 13. Live, Paused, and Retained Behavior
- 14. Edge Watches
- 15. Port Watches
- 16. Local-Memory Watches
- 17. UI-Related Watches
- 18. Watch Lifecycle and Management
- 19. Watch Presentation Model
- 20. Validation and Safety Rules
- 21. Illustrative Examples
- 22. Directory Navigation
- 23. Out of Scope
- 24. Summary
This document defines the watch model of a FROG IDE. A watch is a persistent IDE-managed inspection entry associated with one source-visible target so that selected observations remain visible in a centralized watch view across execution, navigation, and debugging activity.
A watch is not part of the FROG source language. It belongs to the IDE inspection layer. A watch consumes source-aligned execution observability and presents that information in a centralized, persistent, user-manageable form.
Typical watch workflows include:
- keeping selected observations visible across stepping, breakpoints, and pause / resume cycles,
- monitoring multiple graph locations from one centralized inspection view,
- preserving visibility even when the user navigates away from the watched source target,
- retaining recent observations after pause or after execution has ended when supported.
execution observability
|
+----------------------+----------------------+
| |
v v
probe watch
local attachment centralized persistence
target-centric list-centric
diagram-centric monitoring-centric
A watch may be used together with debugging, but it is not itself a debugger control object.
This document is the watch-focused document of the IDE/ family.
Its role is to define persistent centralized 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 watches,IDE/Debugging.mdfor pause, resume, break, and step behavior used together with watches,IDE/Probes.mdfor local source-attached inspection behavior distinct from watches.
This document is intentionally modular. It defines watch behavior only. It does not absorb execution semantics, debugger control, full probe 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 watches
├── Probes.md
│ -> local source-attached inspection behavior distinct from watches
├── Watch.md
│ -> this document
└── Debugging.md
-> interactive debugging behavior compatible with watches
Upstream repository areas that matter for watches 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 watches depend on a clean chain: source-visible targets, validated execution meaning, execution-facing attribution, source-aligned observability, and finally persistent IDE-side inspection.
This document belongs in IDE/ because it defines how a FROG IDE presents persistent centralized inspection of source-aligned execution observations.
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 watches,IDE/Debugging.md— pause, resume, stepping, and breakpoint behavior used together with watches,IDE/Probes.md— local source-attached inspection behavior distinct from watches,Expression/Diagram.md— canonical source-visible edges, ports, and related identity,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 watches
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 control behavior,IDE/Probes.mdremains authoritative for local source-attached inspection behavior,IDE/Watch.mdremains authoritative only for persistent centralized watch 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/Watch.md
owns centralized persistent inspection behavior
A watch MUST track a source-visible target. A watch MUST NOT require the user to reason about runtime-private buffers, queues, or scheduler artifacts.
A watch is intended to remain visible and manageable independently from the immediate local viewport around the target. That persistent centralized role is what distinguishes it from a probe.
Creating, updating, enabling, disabling, or removing a watch MUST NOT alter execution semantics. Watches belong to the IDE inspection layer only.
A watch MUST NOT present speculative, transient, or half-committed source-level observations as stable values. Watched values and state snapshots MUST correspond to committed source-aligned observations.
When execution is paused, a watch MUST remain consistent with the language-valid pause-consistent snapshot exposed to the IDE. A watch MUST NOT contradict the paused view.
Watches MAY be used together with pause, stepping, and breakpoints, but they do not define debugger control semantics. They consume observable execution state; they do not own the control model.
The repository uses Profiles/ for optional standardized executable capability families.
This document may also refer to stronger or weaker watch 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 watch entries.
FROG defines a minimal watch model. Stronger observability support MAY add richer filtering, grouping, formatting, history retention, custom renderers, or richer contextual retention, provided that the base semantic meaning remains preserved.
A watch is an IDE-managed persistent inspection entry associated with exactly one primary target. It displays the most relevant compatible source-aligned observation for that target in a centralized watch view.
Conceptually, a watch contains:
- a watch identifier,
- a primary target,
- a watch kind,
- a current watch-entry state,
- a last-known compatible observation when available,
- relevant execution context for that observation when needed,
- optional retained observation metadata when supported.
A watch does not exist inside the canonical FROG Expression. It is an IDE-side inspection construct layered over live or retained source-aligned observability. Creating or removing a watch MUST NOT modify the source program.
Watches and probes 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 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 broader monitoring.
An IDE MAY allow:
- 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 watch MUST NOT be treated as merely a differently rendered probe. Its defining property is persistent centralized inspection across navigation and debugging activity.
The canonical logical model of watches is a watch list. A watch list is an IDE-managed collection of persistent watch entries associated with one editing, inspection, or debugging context.
A watch list MAY be presented as:
- a dedicated watch window,
- a dockable watch panel,
- a side inspector pane,
- another equivalent centralized IDE presentation.
The exact UI layout is not standardized here. The standardized semantic model is that watch entries belong to an ordered and user-manageable collection.
A watch-capable IDE SHOULD support at least:
- adding a watch,
- removing a watch,
- listing active watches,
- mapping a watch entry back to its source target,
- showing the most recent compatible observation when available.
A watch MUST attach to exactly one primary source-visible target. A watch 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 watch MUST preserve sufficient execution context to interpret the latest relevant observation. Relevant context MAY include:
- execution instance identity,
- sub-FROG stack,
- structure nesting,
- selected region identity,
- loop iteration identity,
- activation identity.
A watch entry is normally attached to a stable source target, not to one permanently fixed dynamic occurrence. Repeated compatible observations of that target MAY therefore update one watch entry over time, while the IDE MAY also display contextual metadata about the most recent observation.
The minimum watch baseline requires support for:
edge_watch
This is the only required watch kind for a minimal conforming watch implementation.
Additional standardized watch kinds MAY include:
port_watch,local_memory_watch.
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_watch,structure_watch,custom_watch.
Among all watch forms, edge_watch is the canonical and most natural watch kind, because ordinary FROG dataflow is most naturally monitored at the edge level.
A watch does not invent values. It displays values or state only when compatible source-aligned observations become available through the IDE-facing observability model.
The primary semantic model of a watch is the last-known committed observation associated with the watched target in the relevant execution context.
This may be:
- a value observed on an edge,
- a value observed at a node port,
- a state snapshot observed for local memory,
- another source-aligned committed observation exposed by a stronger observability support.
If a watched target receives multiple compatible observations over time, the base model requires that the watch be able to show at least the most recent one. A stronger support level MAY additionally preserve bounded history or richer time-oriented rendering.
A watch MAY display:
- a full materialized value,
- a summarized preview,
- a type-aware rendering,
- an availability marker with limited value detail.
In every case, the semantic meaning remains the same: the display corresponds to the last-known compatible committed observation for the watched target.
If no compatible observation exists yet, the watch entry MUST remain explicitly unavailable rather than implying that a real value exists.
A watch MUST NOT imply that a full history exists unless such history is actually preserved by the active observability support.
running execution
|
├── compatible committed observation arrives
| └── watch may update live
|
├── debugger pauses at safe boundary
| └── watch must match paused snapshot
|
└── execution ends
└── watch may become retained if supported
During running execution, a watch MAY update whenever a compatible committed observation becomes available for its target. The refresh strategy and update frequency are implementation-defined.
When execution is paused under debugging control, a watch MUST reflect the paused execution snapshot exposed to the IDE. A watch MUST NOT display a value or state snapshot that contradicts the paused source-level view.
A stronger observability support MAY allow a watch to retain its last-known observation after pause, after normal completion, after fault termination, or after abort. If retained behavior is supported, the IDE MUST clearly distinguish between:
- live-updating watch entries,
- paused-snapshot watch entries,
- retained watch entries.
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_watch is attached to one source edge.
It is the canonical watch kind for ordinary dataflow monitoring in FROG.
An edge watch is updated when the watched 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 watch 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 watch entry. This remains correct because source-level watch semantics are edge-based even if runtime implementation details are optimized differently.
If the same watched edge is activated repeatedly across iterations or nested scopes, the watch entry MAY continue updating with the latest compatible observation while displaying contextual metadata about that observation.
A port_watch is attached to a specific source node port rather than to a full edge.
This watch form is useful when the IDE wants to center monitoring on node boundaries.
A port watch 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 watches as the canonical monitoring form. Port watches are an additional inspection form, not the preferred default for ordinary wire-level understanding.
A port watch attached to an output port SHOULD be semantically equivalent to monitoring the emitted committed value at that source boundary. A port watch attached to an input port SHOULD reflect the committed value received at that input in the relevant execution context.
A local_memory_watch is attached to the local-memory slot owned by a local-memory node instance.
Its purpose is to monitor source-aligned state rather than only ordinary edge values.
For frog.core.delay, a local-memory watch 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 committed stored value visible in a paused snapshot.
A local-memory watch MUST respect node-instance-local scope. It MUST NOT imply shared state across unrelated node instances or unrelated live execution instances.
A local-memory watch observes source-aligned local-memory activity associated with the node instance.
It does not redefine the primitive-local behavior of frog.core.delay or the language-level semantics of local memory.
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 watched through the same canonical mechanisms as other dataflow:
- edge watches on edges connected to
widget_value, - port watches 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 monitored through:
- ordinary watched valueflow when relevant,
- pause-consistent debug inspection,
- stronger-support UI-specific watch 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 allow watching such sequencing activity, but it MUST be interpreted as effect-order observation rather than ordinary value observation.
If supported, such watches MUST remain aligned with both:
- the source-facing widget interaction model,
- the relevant
frog.ui.*primitive definitions.
A watch is created when the IDE attaches a new watch entry to a valid target. Creation MUST fail if the requested target is not valid under the active observability support.
A watch MAY conceptually be in one of the following states:
created— the watch exists but has not yet received a compatible observation,live— the watch is receiving live updates,paused— the watch reflects a paused consistent snapshot,retained— the watch shows a retained post-execution observation when supported,unavailable— the target exists but no compatible observation is currently available,closed— the watch has been removed.
These are watch-entry states. They MUST NOT be confused with the execution state of the underlying instance.
A watch-capable IDE SHOULD support at least:
- add watch,
- remove watch,
- list active watches,
- show source target from watch entry,
- show watch entry from source target.
A stronger observability support MAY additionally support:
- sorting watches,
- grouping watches by scope or target kind,
- pinning selected watches,
- clearing retained observation state,
- creating a probe from a watch target or a watch from a probe target.
This document does not standardize one mandatory watch-window layout. It standardizes the semantic meaning of watch entries.
A watch presentation SHOULD be able to show at least:
- watch target identity,
- watch kind,
- the most recent compatible observation when available,
- watch-entry state such as live, paused, retained, or unavailable,
- basic execution-context information when relevant.
An IDE MAY present this information through:
- a dedicated watch window,
- a docked watch pane,
- a structured inspection sidebar,
- another equivalent centralized view.
A watch presentation MAY allow expanding structured values into child fields or child elements when the active observability support and available type information permit it. Such expansion behavior is optional.
- A watch MUST target a valid source-visible object supported by the active observability support.
- A watch MUST NOT alter execution semantics.
- A watch shown during pause MUST remain consistent with the paused execution snapshot exposed to the IDE.
- A retained watch value MUST be clearly distinguishable from a live-updating value and from a paused-snapshot value.
- A watch MUST NOT misrepresent sequencing observation as an ordinary data value.
- A local-memory watch MUST respect node-instance-local scope.
- A watch MUST NOT imply arbitrary user-defined watch expressions unless a later specification defines them.
- A watch MUST NOT be presented as a probe unless the IDE explicitly re-exposes the same target through the probe model.
- A watch MUST NOT silently conflate observations from unrelated execution instances when retained behavior is supported.
The examples below are illustrative only. They show possible watch-facing representations. They are not a required transport format.
{
"watch_id": "w1",
"kind": "edge_watch",
"target": {
"kind": "edge",
"id": "e_sum"
},
"state": "live",
"last_observation": {
"preview": "17.5"
}
}{
"watch_id": "w2",
"kind": "port_watch",
"target": {
"kind": "port",
"node_id": "add_1",
"port": "result",
"direction": "output"
},
"state": "paused",
"last_observation": {
"preview": "17.5"
}
}{
"watch_id": "w3",
"kind": "local_memory_watch",
"target": {
"kind": "local_memory",
"node_id": "delay_1"
},
"state": "paused",
"last_observation": {
"preview": "5.0"
},
"details": {
"last_event": "state_updated"
}
}{
"watch_id": "w4",
"kind": "edge_watch",
"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 watch entries
├── Probes.md
│ -> local source-attached inspection distinct from watches
├── Watch.md
│ -> this document; persistent centralized inspection
└── Debugging.md
-> interactive debugging behavior compatible with watches
For readers following repository ownership boundaries, the main cross-layer path is:
Expression/
-> what source-visible watch 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/Watch.md
-> how those observations are consumed persistently
- arbitrary textual watch expressions,
- computed watches over user-defined graph expressions,
- mandatory time history for every watch entry,
- reverse-time watch browsing,
- mandatory remote watch streaming,
- standardized distributed aggregation of watch lists,
- watch-triggered execution modification,
- a mandatory dedicated watch-window UI toolkit or layout.
FROG watches are persistent centralized inspection entries used to monitor selected source-visible targets across execution and debugging activity. They are distinct from probes, even though both consume the same source-aligned observability.
This specification establishes that:
- watches belong to the IDE inspection layer,
- watches track source-visible targets such as edges, ports, and local-memory state,
edge_watchis the minimum and primary watch form,- watched values represent compatible committed observations,
- paused and retained watch views must be clearly distinguishable,
- watches provide centralized persistent monitoring rather than local inline inspection.