Skip to content

fix(driver): validate and apply lint fixes through the OPY provider - #602

Open
e54-bot wants to merge 5 commits into
mainfrom
fix/583-opy-provider-lint-fixes
Open

e54-bot wants to merge 5 commits into
mainfrom
fix/583-opy-provider-lint-fixes

Conversation

@e54-bot

@e54-bot e54-bot commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

wright lint --fix on a provider-backed OPY project reported duplicate-condition with fix: null: the mapped Program registered the provider's file table but retained no source text, and the dead-branch scanner only understood Workshop Else If/Else/End keywords. Two changes close the gap:

  • After SourceMap::apply, the session retains each mapped member's authored text (Program::set_file_source, pinned workshop-rs rev 6a97b5c), so Program::source resolves for source extents, identity preconditions, and previews.
  • dead_branch_fix prefers the chain markers' authored action spans — if/elif/else keywords and End at the dedent boundary, emitted by opy-rs since feat(lowering): attribute if-chain markers to authored keyword spans opy-rs#504 — and keeps the Workshop text scanner as fallback for marker-less programs.

Mapped fixes materialize as SourceEdits naming the member's file:// URI under the authored text's identity, then validate through the existing provider pipeline (lpp/validateEdits + lpp/check) instead of the raw Workshop reparse; write_previews resolves URI sources before its atomic replace. Unmapped artifacts carry no fix, and provider-side failures surface as structured refusals.

The dependency commit also folds in the pinned rev's catalog-spelling-near-miss classification (workshop-rs#406), mapped to unsupported with the other uncatalogued residuals.

Fixes #583

Test plan

  • mapped_lint_fix_validates_and_writes_through_the_provider — fake LPP provider + injected marker map: preview names the authored member with full original/fixed OPY text, lpp/validateEdits and lpp/check are exercised, --write applies and re-lints clean
  • Mapped-source retention hardened the span validation (invalid-span against retained text); mapped_lint_session fixtures now write the mapped text as the member
  • Real opy-provider end-to-end: lint --fix previews and --write removes a duplicate elif across elif→elif, elif→else, and elif→dedent boundaries, including nested blocks
  • Raw Workshop lint --fix/--write regression pass (lint_fix, lint_fixes, cli suites)
  • cargo fmt --all -- --check, cargo clippy --workspace --all-targets --all-features -- -D warnings, cargo test --workspace --all-targets --all-features

The mapped-source retention in #583 needs to attach authored text to a provider map's file entries; the pin targets the workshop-rs commit adding that API and retargets to crates.io once it ships. The pinned rev also classifies near-miss settings spellings as catalog-spelling-near-miss (workshop-rs#406): wright maps the new residual to unsupported like the other uncatalogued classes, and the raw-setting test names the new code.
Provider-mapped programs registered their file table but retained no source text, so lint fixes could not resolve authored extents, and the dead-branch scanner only knew Workshop keywords — an OPY elif/else/dedent boundary produced fix: null. The session now retains each mapped member's text after SourceMap::apply (Program::set_file_source), and dead_branch_fix prefers the marker actions' authored spans (if/elif/else keywords, End at the dedent) with the Workshop text scan as fallback for unmarked programs. Materialized mapped edits name the member's file:// URI under the authored text's identity and validate through providerValidateEdits + check; --write resolves URIs before replacing files. Unmapped artifacts still carry no fix.

Fixes #583
SourceMap::apply rebinds the program's file table, but the inertly
carried settings tree kept spans in the parsed text's coordinate space.
Once the session retains each mapped member's authored text
(set_file_source), those stale positions fail Program::validate's bounds
check — wright compile errors with invalid-span on any OPY project with a
settings block (wright#583, bench seeds 'modify-opy-project',
'understand-opy-project', 'greenfield-opy-elimination-race',
'repair-opy-runaway-loop', 'renamed-callable-*', 'ana-paintball').

The map's contract is that nodes without an entry carry no span;
workshop-rs 62b20df clears the settings tree's spans on apply since no
map entry can express settings provenance.
The pin to a git rev of feat/program-set-file-source was a stopgap until
Program::set_file_source shipped. workshop-rs 1.12.0 releases it together
with the source-map fix that clears stale settings spans when apply
rebinds the file table (wright#583), so the [patch.crates-io] section is
removed.
@e54-bot

e54-bot commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator Author

CI classification for the Metrics drift failure (job 113952798102): the run installs OPY provider 0.3.6 against a baseline recorded on 0.3.0 (OPY provider differs: baseline=0.3.0 run=0.3.6), then every agent op on bastion and overwatch-ai-pve is skipped with parse-error and the CLI metrics collapse (e.g. bastion/cli:compile tokens 110371.0 -> 103.8, counts.* -> None). This is not a shared provider/baseline drift: the same job passes on a branch based on current main, so the parse errors are specific to this branch. The head is based on 78a3a0e, two commits behind main — 8317ca1 (#599, service check/compile without a canonical snapshot prewarm) touches the same service load path the agent ops use. Updating the branch onto current main would isolate whether the breakage comes from the stale base or from the change itself.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

Validated lint fixes never materialize on provider-backed (OPY) projects

2 participants