Purpose: Core GNN file discovery, parsing, multi-format serialization, and validation for Generalized Notation Notation specifications
Pipeline Step: Step 3: GNN file processing (3_gnn.py)
Category: Core Processing
Status: ✅ Production Ready
Version: 1.6.0
Last Updated: 2026-04-16
- Discover GNN specification files in target directories
- Parse GNN markdown specifications into structured data
- Serialize parsed models to 22 registered output formats (23
GNNFormatvalues; PNML is parser-focused — see SPEC.md) - Validate GNN syntax and semantic correctness
- Multi-format GNN parsing (markdown, JSON, YAML, etc.)
- 22 registered serializers for 23
GNNFormatvalues (PNML: parse-only inSERIALIZER_REGISTRY— see SPEC.md); covers Scala, Lean, Coq, Python, BNF, EBNF, Isabelle, Maxima, XML, JSON, Protobuf, YAML, XSD, ASN.1, PKL, Alloy, Z-notation, TLA+, Agda, Haskell, Pickle, Markdown .pklis treated as textual PKL DSL by default; binary pickle inputs should use.pickle, with previous-format binary.pklrouted by content detection and logged as a warning.- Round-trip validation (parse → serialize → parse)
- Cross-format consistency checking
process_gnn_multi_format(target_dir: Path, output_dir: Path, logger: logging.Logger, recursive: bool = True, verbose: bool = False, **kwargs: Any) -> bool
Description: Main processing function used by pipeline orchestrator (3_gnn.py). Discovers, parses, and serializes GNN files to all supported formats.
Parameters:
target_dir(Path): Directory containing GNN files to processoutput_dir(Path): Base output directory (step-specific directory will be created)logger(logging.Logger): Logger instancerecursive(bool): Whether to recurse into subdirectories (default: True)verbose(bool): Enable verbose logs (default: False)**kwargs(Any): Additional processing options
Returns: bool - True on success, False otherwise
Location: src/gnn/multi_format_processor.py
Example:
from gnn.multi_format_processor import process_gnn_multi_format
from pathlib import Path
import logging
logger = logging.getLogger(__name__)
success = process_gnn_multi_format(
target_dir=Path("input/gnn_files"),
output_dir=Path("output"),
logger=logger,
recursive=True,
verbose=True
)process_gnn_directory(directory: Union[str, Path], output_dir: Union[str, Path, None] = None, recursive: bool = True, parallel: bool = False) -> Dict[str, Any]
Description: Process all GNN files in a directory. Returns processing results dictionary.
Parameters:
directory(Union[str, Path]): Directory to processoutput_dir(Union[str, Path, None]): Optional output directory for results (default: None)recursive(bool): Whether to process subdirectories (default: True)parallel(bool): Whether to process discovered files concurrently (default: False)
Returns: Dict[str, Any] - Dictionary with processing results containing:
status(str): Processing status ("SUCCESS" or "FAILED")files(List[str]): List of processed file pathsprocessed_files(List[str]): List of successfully processed files
Location: src/gnn/processor.py
process_gnn_directory_lightweight(target_dir: Path, output_dir: Path = None, recursive: bool = False) -> Dict[str, Any]
Description: Lightweight GNN directory processing without heavy dependencies and faster execution.
Parameters:
target_dir(Path): Directory containing GNN filesoutput_dir(Path, optional): Directory to save results (default: None)recursive(bool): Whether to process subdirectories (default: False)
Returns: Dict[str, Any] - Dictionary with processing results containing:
timestamp(str): Processing timestamptarget_directory(str): Source directory pathfiles_found(int): Number of files discoveredfiles_processed(int): Number of files successfully processedsuccess(bool): Overall success statuserrors(List[Dict]): List of error informationparsed_files(List[Dict]): List of parsed file informationvalidation_results(List[Dict]): List of validation results
Location: src/gnn/processor.py
Description: Discovers candidate files for lightweight processing (process_gnn_directory, reports, etc.). This is not the same discovery policy as pipeline Step 3.
Parameters:
directory(Union[str, Path]): Directory to searchrecursive(bool): Whether to search subdirectories (default: True)
Returns: List[Path] - List of Path objects for discovered files
Glob patterns: *.md, *.gnn, *.txt only. Excludes README.md, CHANGELOG.md, LICENSE.md, and names matching *.template.md / *.example.md.
Pipeline Step 3 (process_gnn_multi_format) uses a broader extension list in multi_format_processor.py (e.g. .json, .yaml, .lean, …) so interchange artifacts on disk are found and re-processed. See SPEC.md § File discovery.
Location: src/gnn/processor.py
Description: Parse a single GNN file and extract basic information.
Parameters:
file_path(Union[str, Path]): Path to the GNN file
Returns: Dict[str, Any] - Dictionary with parsed information containing:
file_path(str): Path to the filefile_name(str): Name of the filefile_size(int): Size of the file in bytessections(List[str]): List of extracted sectionsvariables(List[str]): List of extracted variablesstructure_info(Dict): Structure analysis informationparse_timestamp(str): Timestamp of parsing
Location: src/gnn/processor.py
Description: Validate the structure of a GNN file.
Parameters:
file_path(Union[str, Path]): Path to the GNN file
Returns: Dict[str, Any] - Dictionary with validation results containing:
file_path(str): Path to the filefile_name(str): Name of the filevalid(bool): Whether the file structure is validerrors(List[str]): List of validation errorswarnings(List[str]): List of validation warningsvalidation_timestamp(str): Timestamp of validation
Location: src/gnn/processor.py
generate_gnn_report(processing_results: Dict[str, Any], output_path: Union[str, Path] = None) -> str
Description: Generate a report from GNN processing results.
Parameters:
processing_results(Dict[str, Any]): Results from GNN processingoutput_path(Union[str, Path, None]): Optional path to save the report (default: None)
Returns: str - Report content as markdown string
Location: src/gnn/processor.py
Description: Get information about the GNN module.
Returns: Dict[str, Any] - Dictionary with module information containing:
name(str): Module nameversion(str): Module versiondescription(str): Module descriptionfeatures(List[str]): List of available featuresavailable_validators(List[str]): List of available validatorsavailable_parsers(List[str]): List of available parsersschema_formats(List[str]): List of supported schema formatssupported_formats(List[str]): List of supported file formatscapabilities(Dict): Dictionary of capability flags
Location: src/gnn/processor.py
Description: Public alias for process_gnn_directory.
Parameters: Same as process_gnn_directory
Returns: Same as process_gnn_directory
Location: src/gnn/__init__.py
Description: Validate GNN file content string.
Parameters:
content(str): GNN file content as string
Returns: Dict[str, Any] - Dictionary with validation results:
is_valid(bool): Whether content is validerrors(List[str]): List of validation errors
Location: src/gnn/__init__.py
validate_gnn(file_path_or_content: str, validation_level: ValidationLevel = ValidationLevel.STANDARD, **kwargs) -> Tuple[bool, List[str]]
Description: Validate a GNN file or content string.
Parameters:
file_path_or_content(str): Path to a GNN file or GNN content stringvalidation_level(ValidationLevel): Level of validation to perform (default: STANDARD)**kwargs: Additional validation options
Returns: Tuple[bool, List[str]] - Tuple of (is_valid, list_of_errors)
Location: src/gnn/parser.py
Description: Extract sections from GNN content using lightweight parsing.
Parameters:
content(str): GNN file content
Returns: List[str] - List of extracted section names
Location: src/gnn/processor.py
Description: Extract variables from GNN content using lightweight parsing.
Parameters:
content(str): GNN file content
Returns: List[str] - List of extracted variable names
Location: src/gnn/processor.py
Description: Unified registry-backed API — loads parsers/serializers from PARSER_REGISTRY / SERIALIZER_REGISTRY.
Typical use: GNNParsingSystem().parse_file(path), then serialize via the system’s serializer map for a chosen GNNFormat.
Description: Formal / section-oriented parsing helpers used with validate_gnn, parse_gnn_formal, etc.
schema_validator.GNNParser: Section-level parser used by enhanced validation.parsers.common.GNNParser: Protocol implemented by concrete format parsers.
Description: Enumeration of supported GNN formats
Values:
MARKDOWN,JSON,XML,YAML,SCALA,PROTOBUF,PKL,XSD,ASN1,PNML,LEAN,COQ,PYTHON,BNF,EBNF,ISABELLE,MAXIMA,ALLOY,Z_NOTATION,TLA_PLUS,AGDA,HASKELL,PICKLE
pathlib- File path manipulationtyping- Type annotationsre- Regular expression parsingjson- JSON serialization
yaml- YAML format support (recovery: skip YAML generation)protobuf- Protocol buffer support (recovery: skip Protobuf generation)
utils.pipeline_template- Logging and pipeline utilitiespipeline.config- Configuration management
GNN_MAX_FILE_SIZE- Maximum GNN file size in bytes (default: 10MB)GNN_ENABLE_VALIDATION- Enable strict validation (default: True)
DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
DEFAULT_SUPPORTED_FORMATS = 23
DEFAULT_ENABLE_ROUND_TRIP = False
DEFAULT_ENABLE_CROSS_FORMAT = Falsefrom gnn.multi_format_processor import process_gnn_multi_format
from pathlib import Path
success = process_gnn_multi_format(
target_dir=Path("input/gnn_files"),
output_dir=Path("output/3_gnn_output"),
logger=logger
)success = process_gnn_multi_format(
target_dir=Path("input/gnn_files"),
output_dir=Path("output/3_gnn_output"),
logger=logger,
recursive=True,
enable_round_trip=True,
enable_cross_format=True
)# Called from 3_gnn.py
from gnn.multi_format_processor import process_gnn_multi_format
run_script = create_standardized_pipeline_script(
"3_gnn.py",
process_gnn_multi_format,
"GNN discovery, parsing, and multi-format serialization"
)- File Formats:
.mdfiles containing GNN specifications - Directory Structure: Any directory structure (recursive search supported)
- Prerequisites: None (first processing step after template/setup)
- Primary Outputs:
- Parsed model JSON files (
*_parsed.json) - One artifact per serializer-backed format (22 registered serializers; PNML is parse-only in
SERIALIZER_REGISTRY— see SPEC.md)
- Parsed model JSON files (
- Metadata Files:
gnn_processing_results.json- Processing summarygnn_processing_summary.json- Detailed statistics
- Artifacts: Format-specific files in subdirectories
output/3_gnn_output/
├── model_name/
│ ├── model_name_parsed.json
│ ├── model_name.scala
│ ├── model_name.lean
│ ├── model_name.coq
│ ├── model_name.py
│ ├── ... (additional serializer outputs)
├── gnn_processing_results.json
└── gnn_processing_summary.json
- File Not Found: Log warning, continue to next file
- Parse Errors: Log error with line number, mark file as failed
- Serialization Errors: Log warning, skip problematic format
- Validation Errors: Log error, optionally continue based on strict mode
- Primary: Parse all formats successfully
- Recovery 1: Skip problematic format, continue with others
- Recovery 2: Generate minimal JSON representation
- Final: Log error, continue pipeline (non-blocking)
- Logging Level: ERROR for parse failures, WARNING for format skips
- User Messages: "Failed to parse {file}: {specific_error}"
- Recovery Suggestions: "Check GNN syntax at line {N}" or "Install {dependency} for {format} support"
- Script:
3_gnn.py - Function:
run_script()wrapper
utils.pipeline_template- Standardized logging and error handlingpipeline.config- Output directory management
5_type_checker.py- Uses parsed model data6_validation.py- Uses validation results7_export.py- Uses parsed models for export8_visualization.py- Uses model structure for visualization10_ontology.py- Uses ontology terms from models11_render.py- Uses models for code generation
input/gnn_files/ (mixed extensions per multi_format_processor) → GNNParsingSystem → Serializers → output/3_gnn_output/
↓
Parsed Model JSON
↓
[Downstream Steps 5-23]
src/tests/gnn/test_gnn_overall.py- Module-level coverage and smoke testssrc/tests/gnn/test_gnn_parsing.py- Parsing-focused testssrc/tests/gnn/test_gnn_parsing_system.py-GNNParsingSystem/ registry testssrc/tests/gnn/test_gnn_processing.py- Directory processing testssrc/tests/gnn/test_gnn_parsers_common.py- Parser utilities testssrc/tests/gnn/test_gnn_parsers_json.py- JSON parser testssrc/tests/gnn/test_gnn_parsers_base_serializer.py- Serializer base testssrc/tests/gnn/test_gnn_xml_parser.py- XML parser testssrc/tests/gnn/test_gnn_schema.py- Schema validator testssrc/tests/gnn/test_gnn_cross_format_validator.py- Cross-format validation testssrc/tests/gnn/test_gnn_validation.py- Validation tests
Measure locally: uv run --extra dev python -m pytest src/tests/test_gnn*.py --cov=src/gnn --cov-report=term-missing. Targets are project-defined (see CI / maintainer notes); do not treat fixed percentages in docs as measured unless cited from a report.
- Parse valid GNN markdown files
- Handle malformed GNN syntax gracefully
- Serialize to all serializer-backed formats (22; 23 enum values — see SPEC.md)
- Round-trip validation (parse → serialize → parse)
- Cross-format consistency checking
# Run GNN-specific tests
uv run --extra dev python -m pytest src/tests/test_gnn*.py -v
# Run with coverage
uv run --extra dev python -m pytest src/tests/test_gnn*.py --cov=src/gnn --cov-report=term-missing
# Run only parser tests
uv run --extra dev python -m pytest src/tests/gnn/test_gnn_parsing.py -vSee mcp.py register_tools for the authoritative list. Examples include:
get_gnn_documentation— load bundled docs / schema / grammar snippetsvalidate_gnn_content— validate content with level and optional round-trip flagsparse_gnn_content— parse content with format hintvalidate_cross_format_consistency_content— cross-format checksprocess_gnn_directory,run_round_trip_tests,get_gnn_module_info, etc.
src/gnn/mcp.py— MCP tool registrations
- Memory: ~5MB per GNN file + 2MB per format
- CPU: Low (primarily I/O bound)
- Disk: Order of magnitude ~150KB per format × 22 serializer outputs (varies by model)
- Fast Path: <100ms for typical GNN file (13 variables, 11 connections)
- Slow Path: ~2-3s for large models (>100 variables, >50 connections)
- Timeout: None (synchronous processing)
- Input Size Limits: 10MB per file (configurable)
- Parallelization: Lightweight directory processing can process discovered files concurrently.
- Add a value to
GNNFormatinsrc/gnn/parsers/common.py(if it is a new format id). - Implement
src/gnn/parsers/<name>_parser.pyand, unless parse-only,src/gnn/parsers/<name>_serializer.py. - Register classes in
PARSER_REGISTRYand, when applicable,SERIALIZER_REGISTRYinsrc/gnn/parsers/system.py. - Add tests under
src/tests/and extendsrc/gnn/testing/test_round_trip.pyif the format should join the default round-trip list. - Update SPEC.md if canonical counts change.
- Follow PEP 8
- Use type hints for all public functions
- Document all public classes and methods
- Include docstring examples
- New serializers need tests; round-trip tests should cover any format claimed in SPEC.md /
test_round_trip.pyconfig.
Symptom: Parser error with line number
Cause: Invalid GNN syntax (missing delimiter, incorrect format)
Solution: Check GNN syntax at specified line, ensure proper markdown formatting
Symptom: Warning about missing format support
Cause: Optional dependency not installed
Solution: Install missing dependency or accept format will be skipped
Symptom: Parsed model differs after serialize/parse cycle
Cause: Lossy serialization format or parser inconsistency
Solution: Check format specification, report bug if parser issue
# Run with verbose logging
python src/3_gnn.py --verbose
# Check output directory
ls -la output/3_gnn_output/
# View processing summary
cat output/3_gnn_output/gnn_processing_summary.json | python -m json.toolFeatures:
- 23
GNNFormatvalues; 22 registered serializers (see SPEC.md) - Round-trip validation
- Cross-format consistency checking
- Comprehensive error handling
Known Issues:
- Some formats (Protobuf, ASN.1) require optional dependencies
- Large models (>100 variables) may be slow to serialize
- Next Version: Parallel processing for multiple files
- Future: Incremental parsing, lazy serialization