You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Readiness: decided — see ADR-0013 and the decision comment below; implementation issues are split per owner.
Goal
Decide the canonical source-mapping contract that lets Workshop-level evidence produced from a source-language program (lint findings, analysis, element cost, validation diagnostics, validated edits) be attributed to the original authored source, and decide which part of that contract must be settled before the workshop-rs 1.0 API freeze (#252).
Context
opy-rs lowering already attaches rule, condition, and action spans to workshop_rs::Program through Program::set_rule_span / set_condition_span / set_action_span (crates/opy-rs/src/compiler/lowering.rs).
That mapping is lost at the provider boundary: lpp/compile returns an opaque Workshop artifact (text), and the LPP spec explicitly defers a canonical Workshop artifact format to the ecosystem ("LPP will not freeze one without concrete evidence").
Wright re-parses the returned Workshop text. wright-driver's SourceProvenance currently has a single Unmapped variant, so every Wright-owned lint/analyze finding on an OPY project is reported against <provider-artifact>. Preserve Wright lint and analyze semantics across the OPY provider boundary wright#246 was completed by labeling this evidence explicitly unmapped, which is truthful but leaves the actual mapping undelivered.
Current workshop-rs source-mapping model (Program in program.rs, docs/source-preservation.md): spans live in a private side table indexed by rule/condition/action position, while rules / actions are public Vecs. Granularity stops at direct action arguments; nested Value expressions have no span. Inserting or removing an element through the public fields silently shifts every later mapping.
The goal requires diagnostics, analysis, and validated edits to work on real projects for humans and agents; on the primary real-world language (OPY) that currently stops at the provider boundary.
Decisions required
Identity model (1.0-blocking). How a mapping stays attached to a canonical node:
position-indexed side table (current) with mutation constrained so it cannot desync;
stable node identities issued by Program with a side table keyed by identity;
inline optional spans on public nodes.
Trade-offs: mutation safety for edits/transforms, compatibility with the requested public construction sugar (Expose a typed Workshop action and value API #178) and public fields, and 1.x extensibility.
Granularity (1.0-blocking if it changes public shape). Whether nested value expressions carry mappings, or rule/condition/action/direct-argument is the durable contract.
Mapping target. Whether a mapping is a workshop-rsSpan into an attached SourceFile, or a source-language-owned opaque reference (e.g. URI + range) that workshop-rs carries without interpreting, including multi-file includes and macro-expanded / generated code with no single authored location.
Transport across the provider boundary. Options include Workshop text plus a structural source map keyed by canonical node path, or a versioned serialized canonical program. Owner of the format (expected: workshop-rs, as the canonical Workshop artifact) and how LPP advertises it (capability) without LPP defining Workshop semantics.
Mapping through Wright transforms. How mappings survive wright-transform profiles and which findings remain explicitly generated/unmapped.
Scope
Record the decisions above (ADR in the owning repository, current contract in docs/).
Split follow-up implementation issues per owner: workshop-rs (model/format), language-provider-protocol (capability), opy-rs (provider emission), Wright (consumption and presentation).
Non-goals
Implementing the contract in this issue.
Changing LPP to carry provider AST/HIR or workshop-rs internal WIR.
DEL/OSTW provider mapping (deltin-rs has no provider yet; the contract must not preclude it).
Exact whole-file formatting or byte-identical re-emission.
Acceptance criteria
Each decision above is recorded with its rationale and rejected alternatives.
The workshop-rs 1.0 candidate's public source-mapping API matches the decided identity model and granularity, or Freeze the workshop-rs public API for 1.0 #252 explicitly records that the model is out of the 1.x contract.
Follow-up implementation issues exist in each owning repository with a shared real-project acceptance check: Wright lint/analyze findings on a pinned Bastion revision resolve to valid .opy locations, and unmappable evidence stays explicitly unmapped.
Dependencies / ownership
Owner: workshop-rs (canonical program model and canonical Workshop artifact).
Non-binding recommendation for the design discussion: a structural source map (canonical node path → source-owned location) carried beside the Workshop text keeps LPP neutral, avoids freezing a serialized Program wire format, and matches the existing position-based model, provided workshop-rs constrains public mutation so paths cannot silently desync. Whether that constraint is compatible with the #178 construction sugar is the key question to settle first.
Readiness: decided — see ADR-0013 and the decision comment below; implementation issues are split per owner.
Goal
Decide the canonical source-mapping contract that lets Workshop-level evidence produced from a source-language program (lint findings, analysis, element cost, validation diagnostics, validated edits) be attributed to the original authored source, and decide which part of that contract must be settled before the
workshop-rs1.0 API freeze (#252).Context
opy-rslowering already attaches rule, condition, and action spans toworkshop_rs::ProgramthroughProgram::set_rule_span/set_condition_span/set_action_span(crates/opy-rs/src/compiler/lowering.rs).lpp/compilereturns an opaque Workshop artifact (text), and the LPP spec explicitly defers a canonical Workshop artifact format to the ecosystem ("LPP will not freeze one without concrete evidence").wright-driver'sSourceProvenancecurrently has a singleUnmappedvariant, so every Wright-owned lint/analyze finding on an OPY project is reported against<provider-artifact>. Preserve Wright lint and analyze semantics across the OPY provider boundary wright#246 was completed by labeling this evidence explicitly unmapped, which is truthful but leaves the actual mapping undelivered..opylines.workshop-rssource-mapping model (Programinprogram.rs,docs/source-preservation.md): spans live in a private side table indexed by rule/condition/action position, whilerules/actionsare publicVecs. Granularity stops at direct action arguments; nestedValueexpressions have no span. Inserting or removing an element through the public fields silently shifts every later mapping.The goal requires diagnostics, analysis, and validated edits to work on real projects for humans and agents; on the primary real-world language (OPY) that currently stops at the provider boundary.
Decisions required
Programwith a side table keyed by identity;Trade-offs: mutation safety for edits/transforms, compatibility with the requested public construction sugar (Expose a typed Workshop action and value API #178) and public fields, and 1.x extensibility.
workshop-rsSpaninto an attachedSourceFile, or a source-language-owned opaque reference (e.g. URI + range) thatworkshop-rscarries without interpreting, including multi-file includes and macro-expanded / generated code with no single authored location.workshop-rs, as the canonical Workshop artifact) and how LPP advertises it (capability) without LPP defining Workshop semantics.wright-transformprofiles and which findings remain explicitly generated/unmapped.Scope
docs/).workshop-rspublic API and fold them into Freeze the workshop-rs public API for 1.0 #252 before the freeze.workshop-rs(model/format),language-provider-protocol(capability),opy-rs(provider emission), Wright (consumption and presentation).Non-goals
workshop-rsinternal WIR.Acceptance criteria
workshop-rs1.0 candidate's public source-mapping API matches the decided identity model and granularity, or Freeze the workshop-rs public API for 1.0 #252 explicitly records that the model is out of the 1.x contract..opylocations, and unmappable evidence stays explicitly unmapped.Dependencies / ownership
workshop-rs(canonical program model and canonical Workshop artifact).language-provider-protocollpp/compileartifact boundary.Planning notes
Non-binding recommendation for the design discussion: a structural source map (canonical node path → source-owned location) carried beside the Workshop text keeps LPP neutral, avoids freezing a serialized
Programwire format, and matches the existing position-based model, providedworkshop-rsconstrains public mutation so paths cannot silently desync. Whether that constraint is compatible with the #178 construction sugar is the key question to settle first.