Compatibility
2.9.0 release target; current Windows native diagnostics checks
Package applicability is under review; follow the stated version and platform limits.
Download Complete intentional-error hierarchy and read-only static-inspection client (ZIP)Includes main.cir, cells.cir, other.cir, inspect_editor.py, README.txt. Exact checked input files plus instructions; final-release/platform applicability remains pending.

Choose the check that answers your question

Use Workspace Problems to inspect the current circuit source across the working folder. Live analysis is licence-free and uses open buffers, including unsaved include edits. It does not build the default numerical setup or run a simulation. Use the separate saved-circuit guide when you want to check saved inputs through the licensed core, then Run when you need numerical results.

The download is deliberately incorrect: main.cir contains .TRNA instead of .TRAN, and cells.cir closes FILTER as WRONG. other.cir is a second root that shares cells.cir. Keep all three circuit files together in a writable folder. The optional inspect_editor.py client reads one explicitly selected root and its include graph.

Inspect the complete teaching workspace

For a duplicate component label, inspect the primary source location and its related previous declaration in the same circuit scope. Resolve the unintended name collision while preserving the intended branch and its references. This is maintained-reference guidance; the fresh teaching sequence above exercises a closing-name mismatch rather than a duplicate-label case.

  1. Choose the extracted folder as the working folder, open main.cir, and choose Tools > Workspace problems or Ctrl/Cmd+Shift+M. Opening cells.cir is optional for discovery; keep it open when comparing an unsaved edit with disk.
  2. Wait for checking to finish. The example shows two unique Error issues: syntax.directive at main.cir line 6, and semantic.subcircuit.close-name at cells.cir line 5. It also reports incomplete source analysis. Three analyzed candidates include the two roots and their shared library; candidate count is not a count of unique problems.
  3. Expand an issue for its related declaration and include origins. The shared closing-name issue appears once, with both root decks and both include origins retained. It is not two different fixes.
  4. Select an actual source row and press Enter or double-click it. The directive opens line 6, the included closing issue opens cells.cir line 5, and its related opening declaration leads to line 2. Existing unsaved buffers are preserved. Group headings are not source locations.
Actual workspace panel lists the intentional closing-name mismatch in cells.cir and unsupported .TRNA directive in main.cir, with two total errors and incomplete source analysis.
The actual teaching scan has two errors and remains incomplete. Shared-root and related-location details are available by expanding the issue. Open full-size screenshot

Use filters without hiding the meaning of the result

  1. Use the text filter for paths, rule codes, messages or root decks. Open Options to choose Severity, Grouping and Sort; use Back to return to the list.
  2. Enter unmatched-teaching-filter. No matching problems means diagnostics are hidden by the filter. It does not mean the workspace is clean; the state still discloses incomplete analysis.
  3. Choose Clear filters to remove text and severity filters. Grouping and sorting are retained. Confirm that both original issues reappear before making a source decision.
Actual No matching problems state retains the incomplete-analysis explanation and offers Clear filters; hidden diagnostics are not a clean result.
An empty filtered view retains the incomplete-analysis explanation and offers Clear filters. Open full-size screenshot

Recheck the revision you intend to use

Change .ENDS WRONG to .ENDS FILTER in the open cells.cir buffer without saving. The previous workspace snapshot becomes stale and old source actions are disabled. Workspace analysis does not automatically restart after invalidation: use Refresh/F5. The fresh scan now contains only the root directive issue while the included disk file still says WRONG.

Open buffers deliberately override disk for live checks. A disk edit to that same open include is not a request to replace its buffer. Decide whether to save or reload before checking the saved circuit. A disk-only root or include instead has its bytes checked; the native scenario detected a changed unopened other.cir even with its size and timestamp preserved.

A missing include leaves the result incomplete. Restore the dependency or correct the path, then Refresh. After both intended token corrections are saved, a complete scan reports No problems found. This means no unsuppressed static diagnostics were reported, not that the circuit has been numerically qualified.

Inspect one saved graph from an agent or script

Use 64-bit Windows Python and the matching JoSIM 2.9 C API beside its dependencies. In PowerShell, set $Python to that interpreter and $Capi to the full josim-pro_CAPI_AMD64.dll path, then work in the extracted example directory. The command creates a new JSON file; choose a different output name for later inspections.

The original teaching input returns 4 because analysis is incomplete and contains both intended rules. The client returns 0 for complete analysis without visible errors, 3 for complete analysis with visible errors, 4 for incomplete analysis, and 2 for client/connection/input/output errors. Exit 0 still does not prove simulation correctness. Read complete and diagnostics in the JSON, not just file existence.

The optional --overlay TARGET SNAPSHOT arguments use text from an explicit UTF-8 snapshot for an included target without saving it. They do not read unsaved GUI buffers. Inspect each intended root explicitly; this client does not implement the GUI folder discovery or apply fixes. Inspection JSON can contain local paths and source context, so review it before sharing.

& $Python -B .\inspect_editor.py --capi $Capi --source .\main.cir --output .\initial-inspection.json
$InspectionExit = $LASTEXITCODE
Write-Output "Inspection exit: $InspectionExit"

Understand bounded analysis

Workspace discovery excludes hidden folders, build, bin and symbolic links; explicitly opened files and reachable includes can still participate. Discovery is bounded to 128 candidates and 1,024 directories; analysis allows 128 roots and 16 MiB of root text, with a 2 MiB unopened-root limit. Skipped or unresolved sources must remain visible as incomplete.

Per-root limits include 64 files, 32 include levels, 512 diagnostics and fixed source/output/expression budgets. Incomplete results cannot establish source validity, and automatic fixes are withheld when an analysis/output limit is reached. Reduce the source set before requiring complete semantic actions.

The exercised small hierarchy checks overlay ownership, source navigation, filter meaning and revision freshness. Exhaustive discovery limits, symbolic-link/platform handling, every grammar rule and final packages remain outside this native scenario.

Save main.cir

* Intentional spelling error for the diagnostics teaching route
.INCLUDE cells.cir
V1 IN 0 DC 1m
X1 IN OUT FILTER
RLOAD OUT 0 20
.TRNA 1p 100p
.PRINT V(IN) V(OUT)
.END

Save cells.cir

* Intentional closing-name mismatch for the diagnostics teaching route
.SUBCKT FILTER A B
R1 A B 10
C1 B 0 1p
.ENDS WRONG

Save other.cir

* A second root shares the intentionally incorrect include
.INCLUDE cells.cir
V2 IN 0 DC 1m
X2 IN OUT FILTER
RLOAD2 OUT 0 20
.TRAN 1p 100p
.PRINT V(IN) V(OUT)
.END

Save inspect_editor.py

"""Inspect a UTF-8 JoSIM source/include graph through the matching editor C API.

This reads source and reports static analysis. It never runs a simulation,
copies a licence, writes a source file or discovers unsaved GUI buffers.
Supply explicit saved UTF-8 snapshots as overlays when they are required.
"""
import argparse
import ctypes
import json
import os
from pathlib import Path
import sys

MAX_SOURCE = 2 * 1024 * 1024
MAX_REPLY = 8 * 1024 * 1024 + 1


def read_utf8(path):
    data = path.read_bytes()
    if len(data) > MAX_SOURCE:
        raise ValueError('The selected source exceeds the checked 2 MiB input bound.')
    return data.decode('utf-8-sig')


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--capi', type=Path, required=True,
                        help='Matching 64-bit Windows josim-pro_CAPI_AMD64.dll beside its dependencies')
    parser.add_argument('--source', type=Path, required=True)
    parser.add_argument('--output', type=Path, required=True, help='New JSON result; never overwritten')
    parser.add_argument('--overlay', type=Path, nargs=2, action='append', default=[],
                        metavar=('TARGET', 'SNAPSHOT'), help='Use SNAPSHOT text for an included TARGET without changing it')
    parser.add_argument('--dll-directory', type=Path, action='append', default=[],
                        help='Optional existing dependency directory; repeat when needed')
    args = parser.parse_args()
    handles = []
    try:
        if os.name != 'nt' or ctypes.sizeof(ctypes.c_void_p) != 8:
            raise ValueError('This checked client requires 64-bit Windows Python and a matching Windows C API.')
        library = args.capi.resolve(strict=True)
        source = args.source.resolve(strict=True)
        output = args.output.absolute()
        if not library.is_file() or not source.is_file():
            raise ValueError('Select existing C API and source files.')
        if output.exists() or not output.parent.is_dir():
            raise ValueError('Select a new result filename in an existing writable directory.')
        request = {'path': str(source), 'text': read_utf8(source),
                   'document_id': 'kb-cli-root', 'revision': 1, 'buffers': []}
        if len(args.overlay) > 63:
            raise ValueError('This client accepts at most 63 included-source overlays.')
        targets = set()
        source_bytes = len(request['text'].encode('utf-8'))
        for target_arg, snapshot_arg in args.overlay:
            target = target_arg.resolve(strict=True)
            snapshot = snapshot_arg.resolve(strict=True)
            identity = os.path.normcase(str(target))
            if not target.is_file() or target == source or identity in targets:
                raise ValueError('Overlay targets must be existing distinct included source files.')
            targets.add(identity)
            text = read_utf8(snapshot)
            source_bytes += len(text.encode('utf-8'))
            if source_bytes > MAX_SOURCE:
                raise ValueError('Selected root and overlay text exceed this client’s 2 MiB bound.')
            request['buffers'].append({'path': str(target), 'text': text,
                                       'document_id': 'kb-overlay-' + str(len(targets)), 'revision': 1})
        for directory in [library.parent, *args.dll_directory]:
            directory = directory.resolve(strict=True)
            if not directory.is_dir():
                raise ValueError('A dependency directory is not an existing directory.')
            handles.append(os.add_dll_directory(str(directory)))
        api = ctypes.WinDLL(str(library))
        inspect = api.JPRO_Editor_InspectWorkspace
        inspect.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_int), ctypes.c_void_p, ctypes.c_int]
        inspect.restype = ctypes.c_int
        api.JPRO_GetLastError.argtypes = []
        api.JPRO_GetLastError.restype = ctypes.c_char_p
        # One bounded reply avoids repeating filesystem reads between size/value calls.
        buffer = ctypes.create_string_buffer(MAX_REPLY)
        needed = ctypes.c_int(0)
        code = inspect(json.dumps(request, ensure_ascii=False).encode('utf-8'),
                       ctypes.byref(needed), buffer, len(buffer))
        if code != 0:
            message = api.JPRO_GetLastError()
            raise RuntimeError('Editor inspection failed (' + str(code) + '): ' +
                               (message.decode('utf-8', errors='replace') if message else 'no detail'))
        if not 1 <= needed.value <= len(buffer):
            raise RuntimeError('The C API returned an invalid reply length.')
        result = json.loads(buffer.raw[:needed.value - 1].decode('utf-8'))
        complete = result.get('complete') is True
        visible_errors = [d for d in result.get('diagnostics', [])
                          if d.get('severity') == 'error' and not d.get('suppressed', False)]
        # Exclusive creation protects source/snapshot collisions and concurrent results.
        with output.open('x', encoding='utf-8', newline='\n') as stream:
            json.dump(result, stream, ensure_ascii=False, indent=2)
            stream.write('\n')
        print(json.dumps({'complete': complete, 'visible_errors': len(visible_errors),
                          'diagnostics': len(result.get('diagnostics', [])),
                          'limit': 'Static source analysis only; not saved-circuit or numerical acceptance.'}))
        return 4 if not complete else 3 if visible_errors else 0
    except (OSError, ValueError, RuntimeError, AttributeError) as error:
        print(str(error), file=sys.stderr)
        return 2
    finally:
        for handle in reversed(handles):
            handle.close()


if __name__ == '__main__':
    raise SystemExit(main())
Sources and verification details

Recorded inputs/builds only. Complete walkthrough and final-package acceptance remain separate.

VAL-061 · Frozen maintained Windows JoSIM®-Pro 2.9 candidate
Ten read-only 64-bit Windows Python/C API checks inspect the original, overlaid, corrected and missing-include graphs and protect source/result destinations. They repeat on the actual downloaded inputs, including paths with spaces. The literal PowerShell block reports exit 4 for the original graph and exit 0 for the native-corrected graph.
The client does not discover GUI buffers or folders, apply fixes, save sources, run licensed setup or simulate. Final-package/platform qualification remains separate.

VAL-060 · Frozen maintained Windows JoSIM®-Pro 2.9 candidate
Two normal Windows JoSIM 2.9 candidate processes exercise current workspace diagnostics, root/include/related navigation, filters and stale/incomplete recovery, exact single/linked fixes, changed-preview rejection, local/linked Undo/Redo and explicit Save All. Licensed saved setup and numerical Run remain separate. Actual downloaded inputs repeat all 36 checks and reproduce saved corrections and two current arrays; the download review passes twelve comparisons.
Physical pointer/picker interaction, exhaustive grammar/conflicts/cancellation, automatic session restoration, other platforms, final packages and arbitrary-device numerical accuracy remain unqualified.

josim-workspace-problems
Current-source Windows JoSIM 2.9 native diagnostics teaching scenario, reviewed 4 November 2026
The pictured source/diagnostic state is authentic within the checked teaching scenario; it does not establish numerical accuracy or final-package acceptance.

josim-diagnostics-filtered
Current-source Windows JoSIM 2.9 native diagnostics teaching scenario, reviewed 4 November 2026
The pictured source/diagnostic state is authentic within the checked teaching scenario; it does not establish numerical accuracy or final-package acceptance.

  • josim-pro:docs/manual_source/sections/gui_diagnostics.tex · Live diagnostics, workspace states, reviewed fixes, saved-circuit check and tasks
  • validation:diagnostics-workflow-20261104 · VAL-060 native diagnostics and recovery; VAL-061 explicit static API client
  • Scoped native evidence and current source/manual claims are explicit. Physical operator paths, complete feature/conflict coverage, platform/final-package checks and numerical accuracy remain separate.
Read MarkdownRead structured articleBrowse all guides