Skip to content

Unify pipeline warning/error reporting into PipelineMessages module#1093

Open
joehendrix wants to merge 6 commits intomainfrom
jhx/pyspec_warnings
Open

Unify pipeline warning/error reporting into PipelineMessages module#1093
joehendrix wants to merge 6 commits intomainfrom
jhx/pyspec_warnings

Conversation

@joehendrix
Copy link
Copy Markdown
Contributor

@joehendrix joehendrix commented May 1, 2026

Consolidate WarningKind/SpecError into a new PipelineMessages module with typed phases, impact levels, and structured output. Callers now receive warnings in the result rather than having them printed to stderr.

Motivation

The pySpecLaurel pipeline previously mixed exception-based error handling (EIO String) with ad-hoc warning printing. This made it impossible to:

  • Report all errors/warnings at once (exceptions abort on first failure)
  • Attach source locations to pipeline errors
  • Let callers control output format (JSON, summary, silent)

This PR establishes structured warning infrastructure as a foundation for end-to-end robust warning reporting across the full pipeline.

Design: impact drives behavior

Each MessageKind has a MessageImpact that determines pipeline behavior via isFatal:

Impact Fatal? Meaning
configurationError yes Invalid arguments or unreadable on-disk pyspecs
internalError yes Unexpected failure preventing output (e.g., name collision)
internalWarning no Unexpected condition that didn't prevent output
knownLimitation no Documented gap in modeling
userCodeIssue no Issue in the user's Python source

Architecture

PipelineM is a StateT PipelineState BaseIO monad where PipelineState carries:

  • messages : Array PipelineMessage — all warnings and errors with source locations
  • shouldAbort : Bool — set automatically when a fatal message is emitted

There may be multiple fatal errors collected (e.g., listing every missing module, not just the first).

Output changes

pythonAndSpecToLaurel returns BaseIO PythonToLaurelResult (.success program warnings or .failure error warnings). Callers invoke PipelineMessage.printSummary / writeSummaryJson explicitly.

JSON warning summary gains "impact" field:

{"phase": "pySpecToLaurel", "category": "unsupportedUnion", "impact": "knownLimitation", "count": 3}

Other changes

  • resolveModules combinator deduplicates three resolve-and-iterate loops
  • Name collision checks use first-wins with dedup, report all collisions with source locations
  • Phase has phaseNumber for display ordering and a private constructor
  • FunctionOverloads.paramName changed from Option String to String
  • Specs/Error.lean deleted; extract reportUserCodeError helper in StrataMain

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@github-actions github-actions Bot added the Python label May 1, 2026
@joehendrix joehendrix force-pushed the jhx/pyspec_warnings branch from 3b069cf to 04b30cc Compare May 1, 2026 00:40
@joehendrix joehendrix marked this pull request as ready for review May 1, 2026 21:56
@joehendrix joehendrix requested a review from a team May 1, 2026 21:56
Copy link
Copy Markdown
Contributor

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verboseWarnings : Bool := false is a hardcoded constant — there's no way for users to enable verbose warnings without editing source code. This should either be:

  1. A CLI flag (e.g., --verbose-pyspec-warnings) passed through to pythonAndSpecToLaurel, or
  2. Controlled by the existing --verbose flag that's already available in the pipeline

The existing quiet parameter already suppresses the count line. Adding a verbose parameter (or reusing the one from the caller) would be cleaner than a dead constant.

Comment thread Strata/Languages/Python/PySpecPipeline.lean Outdated
@joehendrix joehendrix changed the title Supress pySpecToLaurel warnings in output (not typically useful) Supress verbose pySpecToLaurel warnings in output May 4, 2026
@joehendrix joehendrix marked this pull request as draft May 4, 2026 21:17
@joehendrix joehendrix changed the title Supress verbose pySpecToLaurel warnings in output Unify pipeline warning/error reporting into PipelineMessages module May 4, 2026
joehendrix and others added 5 commits May 5, 2026 16:52
Replace WarningKind/SpecError with MessageKind/PipelineMessage in a new
Strata.Languages.Python.PipelineMessages module. Each MessageKind now
carries a typed Phase (with ordering) and a MessageImpact level
(internalError, internalWarning, knownLimitation, userCodeIssue).

Change pythonAndSpecToLaurel to return PythonToLaurelResult (success or
failure with accumulated warnings) instead of printing to stderr, so
callers control output. Extract printSummary/writeSummaryJson utilities.

Convert ad-hoc stderr warnings (invalid module name, overload resolve,
missing pyspec) into structured PipelineMessage entries. Make
FunctionOverloads.paramName non-optional. Extract reportUserCodeError
helper in StrataMain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…orting

Replace EIO String with BaseIO-based PipelineM (StateT PipelineState BaseIO)
so pipeline steps accumulate structured messages without exceptions. This
enables end-to-end warning reporting where all errors and warnings are
collected with their source locations, even when multiple failures occur.

Key changes:
- PipelineState carries messages array and shouldAbort flag
- addMessage/addMessages/fatalPipelineError combinators replace raw modify
- resolveModules combinator deduplicates three resolve-and-iterate loops
- File read errors, signature errors, and name collisions are now fatal
  but report ALL failures (not just the first)
- Collision checks use first-wins with deduplication
- Public wrappers (buildPySpecLaurel, readDispatchOverloads) return
  PipelineState so callers can check shouldAbort

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace separate addMessage/fatalPipelineError with a single emitMessage
combinator. Whether a message aborts the pipeline is now determined by
kind.impact.isFatal rather than the caller choosing which function to call.

Also adds configurationError impact for cases where the tool was invoked
with invalid arguments or on-disk pyspecs are unreadable (previously
misclassified as userCodeIssue or internalError).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@joehendrix joehendrix force-pushed the jhx/pyspec_warnings branch from 59340c0 to 50adc34 Compare May 5, 2026 16:54
Remove the `printSummary` helper (only had one call site) and inline
the warning printing directly in pyAnalyzeLaurel where the `verbose`
flag is available. Simplify `writeSummaryJson` from `BaseIO` with
manual error handling to plain `IO`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@joehendrix joehendrix marked this pull request as ready for review May 5, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants