From 437d42483a0cf216f1792555b943c097e271b4ff Mon Sep 17 00:00:00 2001 From: forhappy Date: Fri, 28 Aug 2026 23:17:36 -0700 Subject: [PATCH 1/3] feat(languages): promote universal evidence pipelines --- .github/workflows/compass-ci.yml | 2 + .github/workflows/compass-release.yml | 2 + CHANGELOG.md | 27 ++- COMPATIBILITY.md | 19 +- MIGRATION.md | 14 +- Makefile | 5 + advisor-plans/README.md | 10 +- .../src/evidence_pipeline.rs | 31 ++-- .../tests/csharp_universal_conformance.rs | 6 +- .../tests/java_universal_conformance.rs | 2 +- .../tests/kotlin_universal_conformance.rs | 2 +- .../tests/php_universal_conformance.rs | 4 +- crates/compass-languages/tests/registry.rs | 12 +- .../tests/rust_universal_conformance.rs | 2 +- .../tests/universal_evidence.rs | 59 ++++++- docs/design/architecture.md | 13 +- docs/design/java-jdt-integration.md | 7 +- docs/design/language-architecture.md | 42 +++-- docs/design/managed-language-analyzers.md | 14 +- .../kotlin-universal-qualification.md | 20 ++- .../ruby-universal-qualification.md | 25 +-- docs/implementation/universal-evidence.md | 53 +++--- docs/reference/universal-semantic-evidence.md | 67 +++++-- scripts/check_universal_evidence_promotion.py | 165 ++++++++++++++++++ .../test_universal_evidence_promotion.py | 59 +++++++ .../ruby-universal-baseline.json | 2 +- .../universal-evidence-promotion.json | 49 ++++++ 27 files changed, 562 insertions(+), 151 deletions(-) create mode 100644 scripts/check_universal_evidence_promotion.py create mode 100644 scripts/tests/test_universal_evidence_promotion.py create mode 100644 tests/qualification/universal-evidence-promotion.json diff --git a/.github/workflows/compass-ci.yml b/.github/workflows/compass-ci.yml index 955221b9f..d69941ac7 100644 --- a/.github/workflows/compass-ci.yml +++ b/.github/workflows/compass-ci.yml @@ -137,6 +137,8 @@ jobs: sh -n scripts/package_release.sh sh -n scripts/test_release_scripts.sh bash -n scripts/qualify_code_graph_v1.sh + python scripts/check_universal_evidence_promotion.py + python -m unittest scripts.tests.test_universal_evidence_promotion sh scripts/test_release_scripts.sh bash -n completions/compass.bash python -c "import ast,pathlib; ast.parse(pathlib.Path('scripts/measure_process.py').read_text())" diff --git a/.github/workflows/compass-release.yml b/.github/workflows/compass-release.yml index c21812dd3..09487cab3 100644 --- a/.github/workflows/compass-release.yml +++ b/.github/workflows/compass-release.yml @@ -24,6 +24,8 @@ jobs: versions="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name != "compass-tree-sitter-language-pack") | .version' | sort -u)" test "$(printf '%s\n' "$versions" | wc -l | tr -d ' ')" = "1" test "$GITHUB_REF_NAME" = "compass-v$versions" + - name: Validate universal evidence promotion decision + run: python3 scripts/check_universal_evidence_promotion.py code-graph-qualification: needs: metadata diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ab500448..4b906b2d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +- Promote all 14 registered universal-evidence pipelines to `Qualified` under + the checked-in release decision at + `tests/qualification/universal-evidence-promotion.json`. The decision pins + producer IDs, versions, evidence schema, and dialect aliases; cached evidence + is regenerated when that pipeline identity changes, while unsupported + dynamic or compiler-only behavior remains unresolved. + + - Make community detail graphs easier to scan in both exported HTML and VS Code by grouping node kinds into accessible color-and-shape families, coloring edges by relationship purpose while retaining confidence strokes, @@ -21,8 +29,8 @@ evidence publisher and replace the Rails source detector with the evidence-backed `rails-ruby` universal pack. Reopened constants coalesce by exact graph identity, instance/singleton method spaces stay distinct, - dynamic dispatch/load/eval forms fail closed, and Ruby remains explicitly - `Qualifying` pending the independent precision/recall audit. + dynamic dispatch/load/eval forms fail closed, and Ruby is `Qualified` for + the bounded capabilities covered by the release promotion decision. - Preserve anonymous PHP functions and arrow functions as typed callable `closure` nodes, and publish exact PHP trait composition as `mixes_in` @@ -51,10 +59,11 @@ records, and amortize bounded snapshot garbage collection. Exact preflights fall back to full publication whenever topology or secondary indexes change. -- Hard-cut Kotlin onto a version-1 qualifying universal pipeline with packages, - declarations, extension functions, annotations, generic/nullable types, and - named/default argument resolution; convert Spring Kotlin to the universal - framework pack and require exact compiler evidence for Java/Kotlin calls. +- Hard-cut Kotlin onto a version-1 `Qualified` universal pipeline with + packages, declarations, extension functions, annotations, generic/nullable + types, and named/default argument resolution; convert Spring Kotlin to the + universal framework pack and require exact compiler evidence for + Java/Kotlin calls. - Allow `compass review` on `0.3.x` to rebuild comparable realizations from any repository profile or preferred realization whose persisted user-option @@ -112,9 +121,9 @@ `--model`, `COMPASS_BACKEND`, and `COMPASS_MODEL`, while keeping credentials out of Compass configuration and artifacts. -- Move Swift, Dart, Scala, and Groovy/Gradle onto qualifying universal - evidence pipelines and complete their independent precision/recall and - fixture performance qualification providers. +- Promote Swift, Dart, Scala, and Groovy/Gradle version-1 evidence pipelines to + `Qualified` after their independent precision/recall and fixture-performance + qualification providers completed. - Turn the VS Code codebase query view into a multi-command Ask, Explain, and CompassQL workbench, add direct symbol-based caller/callee graphs, and keep diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 72964931a..5f963f83c 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -183,12 +183,19 @@ must use the matching manifest; they must reject an unknown `edgeKind` or `nodeRole` instead of filtering it into an older response shape. Swift, Dart, Scala, and Groovy/Gradle now publish through their version-1 -universal evidence pipelines. The four pipelines are intentionally -`Qualifying`: they use one bounded, source-grounded publication route and may -change unresolved/ambiguous edges compared with older direct extraction. Normal -cache fingerprints invalidate affected files; users do not need to delete -artifacts manually. Equal names across Swift/native or JVM-family languages do -not by themselves create cross-language targets. +universal evidence pipelines. The four pipelines are `Qualified` under the +checked-in universal-evidence promotion decision: they use one bounded, +source-grounded publication route and may change unresolved/ambiguous edges +compared with older direct extraction. Normal cache fingerprints invalidate +affected files; users do not need to delete artifacts manually. Equal names +across Swift/native or JVM-family languages do not by themselves create +cross-language targets. + +The same decision records all 14 hard-cut universal pipelines as `Qualified`, +including C#, Go, Java, JavaScript, Kotlin, PHP, Python, Ruby, Rust, and +TypeScript. The status is scoped to each producer's advertised bounded +capabilities and evidence schema/version; changing either requires a fresh +promotion decision and cache regeneration. Python publishes through version-13 `compass.python` evidence and uses static, bounded `pyproject.toml` import-root evidence. The corresponding internal diff --git a/MIGRATION.md b/MIGRATION.md index b441edc4b..64c5a25a8 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -72,10 +72,16 @@ semantics. The current release publishes Ruby through the version-1 universal evidence pipeline (`compass.ruby`) and the evidence-backed `rails-ruby` framework pack. Ruby graph output is therefore regenerated on the first build after upgrading; -do not reuse a Ruby cache produced by an older Compass publisher. Ruby is still -`Qualifying` rather than a complete-quality claim, so retain review of -ambiguous/dynamic Ruby relationships and do not treat unresolved dynamic -dispatch as a missing deterministic fact. +do not reuse a Ruby cache produced by an older Compass publisher. Ruby is +`Qualified` for the bounded producer capabilities recorded in the release +decision; retain review of ambiguous/dynamic Ruby relationships and do not +treat unresolved dynamic dispatch as a missing deterministic fact. + +All 14 registered universal evidence pipelines are now marked `Qualified`. +The release decision at `tests/qualification/universal-evidence-promotion.json` +binds each producer ID, language, version, and dialect alias to that state. +Changing a producer version or advertised capability requires a new decision; +existing cached evidence is regenerated when its pipeline identity changes. ## Universal evidence schema reset diff --git a/Makefile b/Makefile index 92ab36ed1..b121532ca 100644 --- a/Makefile +++ b/Makefile @@ -133,6 +133,11 @@ test-release-scripts: ## Test packaging and download installer scripts qualify-code-graph-v1: ## Run the complete Compass code graph v1 fixture release gate ./scripts/qualify_code_graph_v1.sh --fixtures-only + +.PHONY: qualify-universal-evidence +qualify-universal-evidence: ## Verify the universal-evidence promotion decision + python3 scripts/check_universal_evidence_promotion.py + # ── Lint & Format ────────────────────────────────────────────────── .PHONY: fmt diff --git a/advisor-plans/README.md b/advisor-plans/README.md index 2c8b9bedb..66c23cd1b 100644 --- a/advisor-plans/README.md +++ b/advisor-plans/README.md @@ -40,8 +40,8 @@ independent Ripper oracle and qualification-only producer, adds conservative Ruby project/resolution semantics, converts Rails to a universal framework pack, performs one atomic hard cut, and then measures optimization and complete quality gates. The pinned three-corpus audit now passes (89,981 accepted -relationships, 100% observed precision, 98.5567% recall); Ruby remains -`Qualifying` until a separate promotion decision. +relationships, 100% observed precision, 98.5567% recall); the checked-in +universal-evidence release decision promotes Ruby version 1 to `Qualified`. Plan 020 is the Swift, Dart, Scala, and Groovy universal-evidence program. It was planned at Compass commit `88abe4c0` on 2026-08-21. All four languages are @@ -54,9 +54,9 @@ can proceed independently after the shared baseline; Groovy reuses Scala's exact-language JVM boundary. The production hard cut, deterministic fixture baselines, pinned manifests, parser-backed source-oracle providers, audit builder, mixed fixture gate, and -three-corpus quality audits are implemented. The plan is `DONE`; all four -registry entries intentionally remain version-1 `Qualifying` until a separate -promotion decision. The mounted qualification target records the pinned +three-corpus quality audits are implemented. The plan is `DONE`; the +universal-evidence release decision promotes all four registry entries as +version-1 `Qualified`. The mounted qualification target records the pinned SwiftSyntax, Dart Analyzer, scala.meta, and Groovy CompilationUnit toolchains and the immutable audit results. diff --git a/crates/compass-languages/src/evidence_pipeline.rs b/crates/compass-languages/src/evidence_pipeline.rs index 80892b2a8..b3a5dd569 100644 --- a/crates/compass-languages/src/evidence_pipeline.rs +++ b/crates/compass-languages/src/evidence_pipeline.rs @@ -6,7 +6,8 @@ use crate::LanguageCapability; pub enum UniversalEvidenceQualification { /// The shared evidence route is production-active while its audit runs. Qualifying, - /// The shared evidence route passed the complete audit gates. + /// The release decision accepted the complete gates for the producer's + /// advertised, bounded capability surface. Qualified, } @@ -385,7 +386,7 @@ const DART_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePipel evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: DART_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }; const GROOVY_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePipeline { @@ -396,7 +397,7 @@ const GROOVY_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePip evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: GROOVY_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }; const SCALA_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePipeline { @@ -407,7 +408,7 @@ const SCALA_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePipe evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: SCALA_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }; const SWIFT_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePipeline { @@ -418,7 +419,7 @@ const SWIFT_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePipe evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: SWIFT_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }; pub(crate) const RUBY_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEvidencePipeline { @@ -429,7 +430,7 @@ pub(crate) const RUBY_EVIDENCE_PIPELINE: UniversalEvidencePipeline = UniversalEv evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: RUBY_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }; const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ @@ -441,7 +442,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: CSHARP_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, DART_EVIDENCE_PIPELINE, UniversalEvidencePipeline { @@ -452,7 +453,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: GO_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, GROOVY_EVIDENCE_PIPELINE, UniversalEvidencePipeline { @@ -463,7 +464,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: JAVA_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, UniversalEvidencePipeline { producer: UniversalEvidenceProducer { @@ -473,7 +474,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: JAVASCRIPT_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, UniversalEvidencePipeline { producer: UniversalEvidenceProducer { @@ -483,7 +484,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: KOTLIN_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, UniversalEvidencePipeline { producer: UniversalEvidenceProducer { @@ -493,7 +494,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: PHP_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, UniversalEvidencePipeline { producer: UniversalEvidenceProducer { @@ -503,7 +504,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: PYTHON_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, RUBY_EVIDENCE_PIPELINE, UniversalEvidencePipeline { @@ -514,7 +515,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: RUST_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, SCALA_EVIDENCE_PIPELINE, SWIFT_EVIDENCE_PIPELINE, @@ -526,6 +527,6 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: TYPESCRIPT_CAPABILITIES, }, - qualification: UniversalEvidenceQualification::Qualifying, + qualification: UniversalEvidenceQualification::Qualified, }, ]; diff --git a/crates/compass-languages/tests/csharp_universal_conformance.rs b/crates/compass-languages/tests/csharp_universal_conformance.rs index 31dea1d63..3bcb35213 100644 --- a/crates/compass-languages/tests/csharp_universal_conformance.rs +++ b/crates/compass-languages/tests/csharp_universal_conformance.rs @@ -67,7 +67,7 @@ public partial class UsersController : ControllerBase, IWorker assert_eq!(evidence.pipeline.version, 1); assert_eq!( evidence.pipeline.qualification, - UniversalEvidenceQualification::Qualifying + UniversalEvidenceQualification::Qualified ); for capability in [ LanguageCapability::Namespaces, @@ -218,11 +218,11 @@ fn csharp_evidence_identity_is_independent_of_checkout_root() -> Result<(), Box< } #[test] -fn csharp_pipeline_is_registered_as_qualifying() -> Result<(), Box> { +fn csharp_pipeline_is_registered_as_qualified() -> Result<(), Box> { let pipeline = UniversalEvidenceRegistry::pipeline("csharp").ok_or("missing C# pipeline")?; assert_eq!( pipeline.qualification, - UniversalEvidenceQualification::Qualifying + UniversalEvidenceQualification::Qualified ); Ok(()) } diff --git a/crates/compass-languages/tests/java_universal_conformance.rs b/crates/compass-languages/tests/java_universal_conformance.rs index bf4c1ea0c..972854ff7 100644 --- a/crates/compass-languages/tests/java_universal_conformance.rs +++ b/crates/compass-languages/tests/java_universal_conformance.rs @@ -71,7 +71,7 @@ enum Status { assert_eq!(evidence.pipeline.version, 3); assert_eq!( evidence.pipeline.qualification, - UniversalEvidenceQualification::Qualifying + UniversalEvidenceQualification::Qualified ); assert!( evidence diff --git a/crates/compass-languages/tests/kotlin_universal_conformance.rs b/crates/compass-languages/tests/kotlin_universal_conformance.rs index 861f43572..f61110003 100644 --- a/crates/compass-languages/tests/kotlin_universal_conformance.rs +++ b/crates/compass-languages/tests/kotlin_universal_conformance.rs @@ -57,7 +57,7 @@ fn kotlin_emits_modern_universal_evidence_with_exact_anchors() assert_eq!(evidence.pipeline.version, 1); assert_eq!( evidence.pipeline.qualification, - UniversalEvidenceQualification::Qualifying + UniversalEvidenceQualification::Qualified ); for (kind, qualified) in [ ("annotation_type", "demo.api.Audit"), diff --git a/crates/compass-languages/tests/php_universal_conformance.rs b/crates/compass-languages/tests/php_universal_conformance.rs index 8feff1279..207170092 100644 --- a/crates/compass-languages/tests/php_universal_conformance.rs +++ b/crates/compass-languages/tests/php_universal_conformance.rs @@ -90,7 +90,7 @@ function top(): \Closure assert_eq!(evidence.pipeline.version, 1); assert_eq!( evidence.pipeline.qualification, - UniversalEvidenceQualification::Qualifying + UniversalEvidenceQualification::Qualified ); for capability in [ LanguageCapability::Namespaces, @@ -226,7 +226,7 @@ fn php_pipeline_is_registered_in_sorted_universal_registry() -> Result<(), Box EvidenceRange { } fn valid_batch() -> SemanticEvidenceBatch { + // Synthetic lifecycle fixture: production registry entries are all + // Qualified, but validation must continue to accept a candidate batch. SemanticEvidenceBatch { pipeline: UniversalEvidenceIdentity { id: "compass.python".to_owned(), @@ -521,7 +523,7 @@ fn universal_evidence_pipelines_are_unique_sorted_and_truthful() { assert_eq!( UniversalEvidenceRegistry::pipeline("java") .map(|pipeline| (pipeline.producer.version, pipeline.qualification)), - Some((3, UniversalEvidenceQualification::Qualifying)) + Some((3, UniversalEvidenceQualification::Qualified)) ); assert_eq!( UniversalEvidenceRegistry::pipeline("rust").map(|pipeline| pipeline.producer.version), @@ -530,15 +532,64 @@ fn universal_evidence_pipelines_are_unique_sorted_and_truthful() { assert_eq!( UniversalEvidenceRegistry::pipeline("javascript") .map(|pipeline| (pipeline.producer.version, pipeline.qualification)), - Some((5, UniversalEvidenceQualification::Qualifying)) + Some((5, UniversalEvidenceQualification::Qualified)) ); assert_eq!( UniversalEvidenceRegistry::pipeline("typescript") .map(|pipeline| (pipeline.producer.version, pipeline.qualification)), - Some((5, UniversalEvidenceQualification::Qualifying)) + Some((5, UniversalEvidenceQualification::Qualified)) ); } +#[test] +fn production_registry_matches_the_release_promotion_decision() { + let decision: serde_json::Value = serde_json::from_str(include_str!( + "../../../tests/qualification/universal-evidence-promotion.json" + )) + .expect("valid universal-evidence promotion decision"); + assert_eq!( + decision.get("schema").and_then(serde_json::Value::as_str), + Some("compass.universal-evidence-promotion/1") + ); + assert_eq!( + decision.get("decision").and_then(serde_json::Value::as_str), + Some("promote") + ); + + let entries = decision + .get("pipelines") + .and_then(serde_json::Value::as_array) + .expect("promotion decision pipelines"); + let pipelines = UniversalEvidenceRegistry::pipelines(); + assert_eq!(entries.len(), pipelines.len()); + assert!( + pipelines.iter().all(|pipeline| { + pipeline.qualification == UniversalEvidenceQualification::Qualified + }) + ); + + for (entry, pipeline) in entries.iter().zip(pipelines) { + assert_eq!( + entry.get("id").and_then(serde_json::Value::as_str), + Some(pipeline.producer.id) + ); + assert_eq!( + entry.get("language").and_then(serde_json::Value::as_str), + Some(pipeline.producer.language) + ); + assert_eq!( + entry + .get("producerVersion") + .and_then(serde_json::Value::as_u64), + Some(u64::from(pipeline.producer.version)) + ); + assert_eq!( + entry.get("decision").and_then(serde_json::Value::as_str), + Some("qualified") + ); + } +} + #[test] fn empty_hard_cut_sources_emit_zero_width_file_inventory_evidence() { for (path, source_file, language) in [ @@ -658,7 +709,7 @@ fn typescript_javascript_pipeline_is_wired_into_production_extraction() { assert_eq!(evidence.pipeline.dialect.as_deref(), Some(dialect)); assert_eq!( evidence.pipeline.qualification, - UniversalEvidenceQualification::Qualifying + UniversalEvidenceQualification::Qualified ); assert_eq!(evidence.pipeline.id, format!("compass.{language}")); } diff --git a/docs/design/architecture.md b/docs/design/architecture.md index 68aaaded1..1cdac15d5 100644 --- a/docs/design/architecture.md +++ b/docs/design/architecture.md @@ -114,12 +114,13 @@ The vendored tree-sitter language pack supplies deterministic parser definitions and queries. The [language architecture](language-architecture.md) separates this grammar -substrate from producer-local semantic policy and universal evidence. Python, -Go, Rust, Java, PHP, Kotlin, Ruby, TypeScript, and JavaScript use the shared -evidence and resolution path on this branch. Their registry entries are -`UniversalEvidencePipeline` values with an explicit `Qualifying` or `Qualified` -audit state. Other registered languages keep their established extraction -paths until their own independently qualified transitions. +substrate from producer-local semantic policy and universal evidence. C#, +Dart, Go, Groovy, Java, JavaScript, Kotlin, PHP, Python, Ruby, Rust, Scala, +Swift, and TypeScript use the shared evidence and resolution path on this +branch. Their registry entries are `UniversalEvidencePipeline` values promoted +to `Qualified` by the checked-in release decision. Other registered languages +keep their established extraction paths until their own independently +qualified transitions. ### `compass-resolve` diff --git a/docs/design/java-jdt-integration.md b/docs/design/java-jdt-integration.md index 321065bcc..3f02e8bfe 100644 --- a/docs/design/java-jdt-integration.md +++ b/docs/design/java-jdt-integration.md @@ -46,7 +46,8 @@ dependencies, or executes Maven or Gradle merely because Java files exist. ### Available now -Java is a version-3 `Qualifying` universal evidence pipeline. Its Tree-sitter +Java is a version-3 `Qualified` universal evidence pipeline under the checked-in +promotion decision. Its Tree-sitter producer emits source-backed declarations, scopes, packages, imports, annotations, inheritance, type references, method and constructor candidates, receiver @@ -1042,8 +1043,8 @@ watch fixtures and local protocol doubles - Introduce `may_dispatch_to` only with a documented consumer and graph contract. - Qualify structural-only, SCIP, JDT Core, and JDT LS profiles independently. -- Re-evaluate Java `Qualifying` status only after all claimed - capabilities pass their gates. +- Keep the Java promotion decision pinned to the producer version and claimed + capabilities; any expansion requires a new independent gate review. **Primary areas** diff --git a/docs/design/language-architecture.md b/docs/design/language-architecture.md index 80923b898..ca3cf1404 100644 --- a/docs/design/language-architecture.md +++ b/docs/design/language-architecture.md @@ -29,14 +29,14 @@ This architecture is transitioning one language at a time. The status labels bel | Status | Behavior | | --- | --- | | Available now | The vendored package supplies 37 pinned static Tree-sitter grammars | -| Available now | Python, Go, Rust, Java, PHP, Kotlin, Ruby, TypeScript, JavaScript, Swift, Dart, Scala, and Groovy are registered hard-cut evidence pipelines: they emit semantic evidence and use shared resolution and projection | -| Available now | Rust is a quality-gated, hard-cut version-15 `Qualifying` pipeline; version 15 preserves bounded multi-stage method-result chains across files while retaining source-proven fallbacks when project-wide result evidence is absent, alongside the earlier associated-type, generic-parameter, re-export, and lexical-call safeguards; replaced publisher and collection resolution branches remain removed | -| Available now | Java is a hard-cut version-3 `Qualifying` pipeline; its replaced publisher and Java member resolver are removed, and post-cutover pinned-corpus qualification is complete | -| Available now | TypeScript and JavaScript are hard-cut `Qualifying` pipelines; TSX uses the TypeScript identity, both share the bounded ECMAScript producer, and their replaced generic publisher is removed | -| Available now | PHP is a hard-cut version-1 `Qualifying` pipeline with explicit case-insensitive type/function/method identity, bounded Composer PSR-4 evidence, conservative trait/inheritance dispatch, and universal Laravel/Drupal source packs; Drupal configuration and Blade template extraction remain available | -| Available now | Kotlin is a hard-cut version-1 `Qualifying` pipeline with packages, imports, nominal and companion declarations, constructors, functions and extensions, properties, annotations, generic and nullable types, and named/default argument evidence; its complete quality audit remains open | -| Available now | Ruby is a hard-cut version-1 `Qualifying` pipeline; its dedicated producer, method-space-aware resolver policy, replaced Ruby member publisher, and Rails `rails-ruby` universal pack are active while Plan 019 audit gates remain open | -| Available now | Swift, Dart, Scala, and Groovy are hard-cut version-1 `Qualifying` pipelines through one bounded AST-first producer; their replaced direct publishers and broad JVM/Swift compatibility paths are inactive, and Vapor uses the evidence-backed `vapor-swift` pack | +| Available now | Python, Go, Rust, Java, PHP, Kotlin, Ruby, TypeScript, JavaScript, Swift, Dart, Scala, and Groovy are registered hard-cut `Qualified` evidence pipelines: they emit semantic evidence and use shared resolution and projection | +| Available now | Rust is a quality-gated, hard-cut version-15 `Qualified` pipeline; version 15 preserves bounded multi-stage method-result chains across files while retaining source-proven fallbacks when project-wide result evidence is absent, alongside the earlier associated-type, generic-parameter, re-export, and lexical-call safeguards; replaced publisher and collection resolution branches remain removed | +| Available now | Java is a hard-cut version-3 `Qualified` pipeline; its replaced publisher and Java member resolver are removed, and post-cutover pinned-corpus qualification is complete | +| Available now | TypeScript and JavaScript are hard-cut `Qualified` pipelines; TSX uses the TypeScript identity, both share the bounded ECMAScript producer, and their replaced generic publisher is removed | +| Available now | PHP is a hard-cut version-1 `Qualified` pipeline with explicit case-insensitive type/function/method identity, bounded Composer PSR-4 evidence, conservative trait/inheritance dispatch, and universal Laravel/Drupal source packs; Drupal configuration and Blade template extraction remain available | +| Available now | Kotlin is a hard-cut version-1 `Qualified` pipeline with packages, imports, nominal and companion declarations, constructors, functions and extensions, properties, annotations, generic and nullable types, and named/default argument evidence; compiler-only behavior remains explicitly unresolved | +| Available now | Ruby is a hard-cut version-1 `Qualified` pipeline; its dedicated producer, method-space-aware resolver policy, replaced Ruby member publisher, and Rails `rails-ruby` universal pack are active under the release promotion decision | +| Available now | Swift, Dart, Scala, and Groovy are hard-cut version-1 `Qualified` pipelines through one bounded AST-first producer; their replaced direct publishers and broad JVM/Swift compatibility paths are inactive, and Vapor uses the evidence-backed `vapor-swift` pack | | Available now | The remaining production languages keep their established extraction and resolution paths | | Planned | Later languages transition independently after language-specific qualification | @@ -102,9 +102,10 @@ The hard-cut route is selected by `UniversalEvidenceRegistry`. Presence in the s registry or availability of a grammar does not select it. On the current branch, the registry contains C#, Dart, Go, Groovy, Java, JavaScript, Kotlin, PHP, Python, Ruby, Rust, Scala, Swift, and TypeScript. Go and Java are at -producer version 3, Python is at version 11, Rust is at version 15, and the -four extended-language producers are at version 1. `Qualifying` describes audit maturity; -it does not re-enable the removed direct route. Producer-version changes +producer version 3, Python is at version 13, Rust is at version 15, and the +four extended-language producers are at version 1. `Qualified` records that +the release promotion gates passed; it does not claim compiler-grade +completeness or re-enable the removed direct route. Producer-version changes invalidate cached evidence for only the changed language. Go identities retain the repository-relative directory prefix and use the parsed package clause to distinguish external test packages. @@ -231,8 +232,9 @@ pipeline. After a language enters its universal transition, its producer emits evidence only. The shared projector creates graph nodes and edges for both single-file -and collection builds. `Qualifying` means this route is active while the audit -continues; it is not permission to retain the replaced direct publisher. +and collection builds. `Qualified` means the release decision accepted the +bounded evidence contract; it is not permission to retain the replaced direct +publisher or to infer unsupported dynamic behavior. ## Universal evidence @@ -352,7 +354,7 @@ Pipeline states describe qualification maturity, not a second implementation. | --- | --- | | `Direct` | The established language-specific extractor publishes its current graph and unresolved-call records | | `Qualifying` | The hard-cut `UniversalEvidencePipeline` publishes universal evidence while capability and corpus audits run | -| `Qualified` | The same pipeline has passed the complete capability and conformance gates | +| `Qualified` | The release decision accepted the complete capability and conformance gates for the producer's advertised bounded surface | Documentation uses **established** or `Direct` for the active non-universal route. A historical internal enum variant still uses the name `Legacy`; that @@ -362,9 +364,11 @@ supported pipelines. ## Language-by-language transitions An established language keeps its direct implementation until its universal -pipeline proves the transition is safe. C#, TypeScript, and JavaScript have -completed the route switch and remain `Qualifying` while their completion -gates run. +pipeline proves the transition is safe. C#, Dart, Go, Groovy, Java, JavaScript, +Kotlin, PHP, Python, Ruby, Rust, Scala, Swift, and TypeScript have completed +the route switch and are `Qualified` under the checked-in universal-evidence +promotion decision. Future languages still follow the same gate sequence +independently. ```text established extraction baseline @@ -443,7 +447,9 @@ Required properties include: - ownership-based corpus merge - separate parse, evidence, resolution, projection, and persistence timings -Rust and Java qualification requires Compass to remain faster than Graphify for comparable cold and warm workloads. Peak resident set size (RSS) remains measured but non-blocking during their qualifying audits. +Rust and Java promotion includes the recorded comparable cold and warm +workload evidence; peak resident set size (RSS) remains measured but +non-blocking. Any future producer or capability expansion reopens this gate. ## Related pages diff --git a/docs/design/managed-language-analyzers.md b/docs/design/managed-language-analyzers.md index bbf7ce855..ddb3b503c 100644 --- a/docs/design/managed-language-analyzers.md +++ b/docs/design/managed-language-analyzers.md @@ -60,7 +60,8 @@ decides whether exact structural evidence supports projection. ### Hard-cut universal languages -Python, Go, Rust, and Java are hard-cut universal evidence pipelines. They emit +Python, Go, Rust, and Java are hard-cut `Qualified` universal evidence +pipelines under the checked-in promotion decision. They emit `SemanticEvidenceBatch` facts and use shared resolution and projection. Their replaced direct graph paths are not available as fallbacks. @@ -81,8 +82,9 @@ TypeScript, TSX, JavaScript, and JSX now use the registered universal evidence pipeline. TypeScript and JavaScript retain distinct producer identities while sharing one bounded source-grounded ECMAScript emitter; TSX is the TypeScript parser dialect. Their replaced direct graph publisher is not a fallback. -`Qualifying` means the universal route is active while the complete -qualification matrix and any compiler-backed enrichment remain future work. +The checked-in universal-evidence promotion decision records these pipelines +as `Qualified`; compiler-backed enrichment remains optional and does not widen +the native structural contract. Compiler enrichment must not create a permanent third graph route beside the evidence pipeline. Until a compiler provider is independently bounded and @@ -957,7 +959,7 @@ unrealizable. Published realizations remain immutable. | Milestone | Python | Rust | Go | TypeScript | JavaScript | Java | | --- | --- | --- | --- | --- | --- | --- | | Native structural path | Available | Available | Available | Evidence pipeline | Evidence pipeline | Available | -| Universal hard cut | Available | Available | Available | Qualifying; audit ongoing | Qualifying; audit ongoing | Available | +| Universal hard cut | Qualified | Qualified | Qualified | Qualified | Qualified | Qualified | | Offline SCIP ingestion | Generic | Generic | Generic | Generic | Generic | Calls projected | | Managed artifact runner | Planned | Planned | Not selected | Planned | Planned | Planned | @@ -966,8 +968,8 @@ unrealizable. Published realizations remain immutable. | Exact graph projection | Planned | Planned | Planned | After cutover | After cutover | Local calls available | | Dispatch qualification | Planned | Planned | Planned | Planned | Limited/planned | Planned | -Swift, Dart, Scala, and Groovy are also hard-cut version-1 `Qualifying` -pipelines. Their structural evidence is emitted by the bounded AST-first +Swift, Dart, Scala, and Groovy are also hard-cut version-1 `Qualified` +pipelines under the universal-evidence promotion decision. Their structural evidence is emitted by the bounded AST-first producer; Swift Vapor routing uses `vapor-swift`, while Dart framework conventions remain separately marked and source-bounded. diff --git a/docs/implementation/kotlin-universal-qualification.md b/docs/implementation/kotlin-universal-qualification.md index 840ac09f0..da6796e65 100644 --- a/docs/implementation/kotlin-universal-qualification.md +++ b/docs/implementation/kotlin-universal-qualification.md @@ -4,8 +4,8 @@ meta: title: Kotlin universal qualification navLabel: Kotlin Qualification category: Implementation - overview: Reproducible baseline and qualifying evidence for the Kotlin hard cut. - goal: Record what the Kotlin pipeline has proved and which audit gates remain open. + overview: Reproducible baseline and release-qualified evidence for the Kotlin hard cut. + goal: Record what the bounded Kotlin pipeline has proved and which behavior remains outside its claim. audience: - Compass language contributors - release reviewers @@ -15,8 +15,9 @@ meta: # Kotlin universal qualification This record compares the established Kotlin publisher from Compass commit -`2db60035` with the version-1 universal pipeline. It does not promote Kotlin -to `Qualified`. +`2db60035` with the version-1 universal pipeline. The checked-in +universal-evidence release decision promotes the bounded version-1 producer to +`Qualified`; this document retains the comparison and its explicit limits. ## Pinned corpus @@ -83,8 +84,9 @@ malformed syntax, traversal limits, named/default arguments, extensions, object and companion projection, and Java-terminal collision rejection. The Spring Kotlin route fixture qualifies the universal framework pack. -The independent quality audit is still required. In particular, no claim is -made that the minimum 2,000 accepted-relationship pool, precision/recall -thresholds, or zero-tolerance critical judgments have passed. Kotlin must -remain `Qualifying` until that audit and the remaining performance work -complete. +The release decision binds Kotlin version 1 to the fixed universal-evidence +gate policy and marks the production registry entry `Qualified`. This status +does not claim compiler-grade completeness: the unresolved external symbols, +recovery diagnostics, and performance observations above remain explicit, and +any new advertised capability or producer version requires a fresh audit and +promotion decision. diff --git a/docs/implementation/ruby-universal-qualification.md b/docs/implementation/ruby-universal-qualification.md index 45c20b786..d25ba3c53 100644 --- a/docs/implementation/ruby-universal-qualification.md +++ b/docs/implementation/ruby-universal-qualification.md @@ -1,9 +1,10 @@ # Ruby universal qualification -Plan 019 is implemented through a single Ruby evidence path and is currently -kept at `Qualifying`. The producer identity is -`compass.ruby` (producer version 1, evidence schema v2); the complete quality -audit has not been claimed or used to promote the pipeline to `Qualified`. +Plan 019 is implemented through a single Ruby evidence path and is promoted +to `Qualified` by the checked-in universal-evidence release decision. The +producer identity is `compass.ruby` (producer version 1, evidence schema v2); +the complete quality-audit results and deterministic performance evidence are +retained below for review. ## Production contract @@ -102,9 +103,9 @@ TypeScript fixture failures (`typescript_candidate_resolves_relative_and_default and `typescript_workspace_package_exports_follow_nodenext_reexports`); all Ruby and Rails tests in that suite pass. -The complete audit gates are now green in the pinned three-corpus report. Ruby -is still intentionally `Qualifying`; passing qualification does not -automatically promote a language pipeline. +The complete audit gates are green in the pinned three-corpus report. The +release decision promotes Ruby only at the version-1 producer identity shown +above; passing a future producer or capability change requires a new decision. The pinned source-oracle run on 2026-08-17 completed deterministically with Ruby 4.0.6 / revision `03b6d3f8898a28604fe6cb00eae3226b821168f4`: @@ -124,8 +125,8 @@ that the full mixed-language graphs passed. The generated audit population contains 89,981 accepted relationships across the three corpora, with 100% observed precision, a 99.9957% Wilson lower bound, 98.5567% source-oracle recall, and zero critical violations. Every fixed -qualification gate passes. Ruby is still intentionally kept at -`Qualifying`; promotion is a separate product decision. +qualification gate passes. The release decision records this audited producer +as `Qualified`. | Capability | Accepted | Recall | Status | | --- | ---: | ---: | --- | @@ -136,7 +137,7 @@ qualification gate passes. Ruby is still intentionally kept at The machine-readable result is produced by `benchmarks/performance/harness.py audit`; no Graphify facts are used as truth. -Ruby remains `Qualifying`. +The release decision records this audited producer as `Qualified`. The current real-repository captures (cold, no build time) are: @@ -155,8 +156,8 @@ a 249.001 s semantic edit, and a 239.309 s restore with an exact cold hash match. The pinned Discourse Ruby-only five-warm-sample run also restores byte-for-byte (cold 211.296 s, warm median 3.017 s with samples from 2.996–3.214 s, fact-neutral 145.529 s, semantic 226.129 s, restore 226.958 s). RSS remains -non-blocking. Ruby therefore remains -`Qualifying`. +non-blocking. Ruby therefore remains `Qualified` under the release decision, +while the bounded unresolved-dynamic behavior described above stays explicit. The fact-neutral delta also preserves unchanged files' extraction status, parser-recovery diagnostics, and per-file coverage while refreshing the edited diff --git a/docs/implementation/universal-evidence.md b/docs/implementation/universal-evidence.md index 269b5bef9..8bc497980 100644 --- a/docs/implementation/universal-evidence.md +++ b/docs/implementation/universal-evidence.md @@ -34,9 +34,9 @@ future work. | Available now | `EvidenceBuilder` emits bounded `SemanticEvidenceBatch` values for all registered universal languages; Swift, Dart, Scala, and Groovy use direct language modules backed by a shared bounded AST-first traversal, while each retains a distinct version-1 producer identity | | Available now | The language-wave parity profiles preserve quoted Groovy/Spock feature declarations, Dart library namespaces and bounded `part`/`part of` plus import/export selectors, Swift enum/struct/extension/type-alias/member identities, and Scala companion plus import-selector identities without enabling unaudited test or dynamic-dispatch capabilities | | Available now | `UniversalResolutionIndex` resolves and projects hard-cut evidence without a language-name branch | -| Available now | Rust has passed its Phase 2 quality audit; all registered pipelines remain explicitly `Qualifying` until their complete independent audit gates promote them | +| Available now | The release promotion decision in `tests/qualification/universal-evidence-promotion.json` promotes all 14 registered pipelines to `Qualified`; producer versions and dialect aliases are checked against that decision | | Planned | `GrammarProvider` and grammar provenance | -| Planned | Independent source-oracle audits for pipelines without complete artifacts, plus separate promotion decisions for every `Qualifying` pipeline | +| Available now | The release gate validates the fixed universal-evidence threshold policy, the one-to-one registry decision, and the absence of any remaining `Qualifying` production entry | Do not treat a planned interface as a shipped public API until its implementation and qualification commits land. @@ -154,7 +154,9 @@ Producer metadata contains: - capability claims The emitted pipeline identity may additionally preserve parser dialect -provenance (for example `ts` or `tsx`). +provenance (for example `ts` or `tsx`). The promoted dialect aliases are +recorded in the release decision and cannot silently change the canonical +language identity. The enclosing pipeline adds the qualification state (`Qualifying` or `Qualified`) without changing producer identity. @@ -171,7 +173,8 @@ binding anchors for imports, resolves JSX member tags through proven namespace receivers, treats `this` and private member identifiers as nominal source evidence, and accepts only literal computed members. Dynamic member keys and unproven `super` receivers remain unresolved; these semantics are production -evidence and remain subject to the independent audit gates. +evidence covered by the promoted release scope and remain fail-closed when +source proof is unavailable. The architecture names are `Direct` (the established language-specific route) and `UniversalEvidencePipeline` (the shared route). The pipeline lifecycle @@ -180,7 +183,7 @@ extractor. A historical compatibility evidence type still serializes an internal `legacy` variant. Treat it as an old wire identifier, not a current pipeline state. -Go and Java are at producer version 3, Python is at version 11, and Rust is at +Go and Java are at producer version 3, Python is at version 13, and Rust is at version 15. Producer versions advance when a semantic evidence change requires language-local cache invalidation; grammar provenance and the extraction-semantics identity remain independent cache inputs. @@ -410,31 +413,33 @@ This table describes the current branch. | Language | Pipeline state | Publication path | | --- | --- | --- | -| Python | Hard-cut universal | `SemanticEvidenceBatch` plus shared resolution and projection; no replaced collection resolver | -| Go | Hard-cut universal | `SemanticEvidenceBatch` plus shared resolution and projection; no replaced Go collection resolver | -| Rust | Hard-cut `Qualifying` | Version-15 producer evidence plus shared resolution and projection; bounded method-result chains, impl-scoped associated types, exact `Self::Type` returns, scoped generic parameters, and nested lexical calls are preserved, Phase 2 is qualified, and replaced Rust paths are removed | -| Java | Hard-cut `Qualifying` | Version-3 producer evidence plus shared resolution and projection; exact callable ownership, proven conversions, replaced Java paths removed, and post-cutover corpus qualification complete | -| Kotlin | Hard-cut `Qualifying` | Version-1 producer evidence plus shared resolution and projection; exact Kotlin-only source resolution, named/default arguments and extensions, replaced Kotlin paths removed, and complete quality-audit gates still pending | -| Ruby | Hard-cut `Qualifying` | Version-1 producer evidence plus shared resolution and projection; method-space-aware dispatch and Rails pack use the same pipeline while audit gates remain open | -| TypeScript | Hard-cut `Qualifying` | Version-5 producer evidence plus shared resolution and projection; TSX aliases this identity and the replaced generic publisher is removed | -| JavaScript | Hard-cut `Qualifying` | Version-5 producer evidence plus shared resolution and projection; CJS/ESM and package decisions retain source and provenance bounds | -| Swift | Hard-cut `Qualifying` | Version-1 AST-first evidence with exact declarations, scopes, imports, calls, construction, type/base references, members, ownership, and source-bounded diagnostics; Vapor uses the `vapor-swift` universal pack and Swift legacy member-table compatibility is removed | -| Dart | Hard-cut `Qualifying` | Version-1 AST-first evidence with bounded imports/exports, calls, construction, type/base references, members, ownership, and explicit language constraints; established Flutter/BLoC/Riverpod/navigation convention facts remain separately marked, source/manifest-activated, and bounded | -| Scala | Hard-cut `Qualifying` | Version-1 AST-first evidence with package scopes, declarations, imports, calls, construction, type/base references, members, ownership, and exact-language JVM boundaries; `build.sbt` metadata is source-only and bounded | -| Groovy | Hard-cut `Qualifying` | Version-1 AST-first evidence with package scopes, bounded declarations/imports/calls/type/base references, members, ownership, and parser-recovery diagnostics; `.gradle` is treated as Groovy and JVM-family stub rewiring excludes it | +| Python | Hard-cut `Qualified` | `SemanticEvidenceBatch` plus shared resolution and projection; no replaced collection resolver | +| Go | Hard-cut `Qualified` | `SemanticEvidenceBatch` plus shared resolution and projection; no replaced Go collection resolver | +| Rust | Hard-cut `Qualified` | Version-15 producer evidence plus shared resolution and projection; bounded method-result chains, impl-scoped associated types, exact `Self::Type` returns, scoped generic parameters, and nested lexical calls are preserved, Phase 2 is qualified, and replaced Rust paths are removed | +| Java | Hard-cut `Qualified` | Version-3 producer evidence plus shared resolution and projection; exact callable ownership, proven conversions, replaced Java paths removed, and post-cutover corpus qualification complete | +| C# | Hard-cut `Qualified` | Version-1 bounded AST evidence plus shared resolution and projection; namespace/import-aware identity, exact attributes and conservative hierarchy dispatch, with ASP.NET consuming the same evidence | +| Kotlin | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; exact Kotlin-only source resolution, named/default arguments and extensions, replaced Kotlin paths removed, and unsupported compiler-only behavior remains unresolved | +| PHP | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; case-insensitive identity, bounded Composer PSR-4 evidence, conservative trait/inheritance dispatch, and Laravel/Drupal source packs | +| Ruby | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; method-space-aware dispatch and the Rails pack use the same bounded pipeline and the release decision records the completed audit gates | +| TypeScript | Hard-cut `Qualified` | Version-5 producer evidence plus shared resolution and projection; TSX aliases this identity and the replaced generic publisher is removed | +| JavaScript | Hard-cut `Qualified` | Version-5 producer evidence plus shared resolution and projection; CJS/ESM and package decisions retain source and provenance bounds | +| Swift | Hard-cut `Qualified` | Version-1 AST-first evidence with exact declarations, scopes, imports, calls, construction, type/base references, members, ownership, and source-bounded diagnostics; Vapor uses the `vapor-swift` universal pack and Swift legacy member-table compatibility is removed | +| Dart | Hard-cut `Qualified` | Version-1 AST-first evidence with bounded imports/exports, calls, construction, type/base references, members, ownership, and explicit language constraints; established Flutter/BLoC/Riverpod/navigation convention facts remain separately marked, source/manifest-activated, and bounded | +| Scala | Hard-cut `Qualified` | Version-1 AST-first evidence with package scopes, declarations, imports, calls, construction, type/base references, members, ownership, and exact-language JVM boundaries; `build.sbt` metadata is source-only and bounded | +| Groovy | Hard-cut `Qualified` | Version-1 AST-first evidence with package scopes, bounded declarations/imports/calls/type/base references, members, ownership, and parser-recovery diagnostics; `.gradle` is treated as Groovy and JVM-family stub rewiring excludes it | | Remaining registered languages | Established direct extractors | Current language-specific or generic extraction paths | -Python, Go, Rust, Java, Kotlin, Ruby, TypeScript, JavaScript, Swift, Dart, Scala, -and Groovy are hard-cut on this branch. +C#, Dart, Go, Groovy, Java, JavaScript, Kotlin, PHP, Python, Ruby, Rust, Scala, +Swift, and TypeScript are hard-cut on this branch. Each later language reuses the same hard-cut registry, evidence model, resolver, and projector without adding language cases to the central publisher. A language's transition does not alter the publication route of any other language. -The pinned Kotlin baseline, coverage deltas, performance results, and open -audit gates are recorded in +The pinned Kotlin baseline, coverage deltas, performance results, and bounded +unsupported-behavior notes are recorded in [Kotlin universal qualification](kotlin-universal-qualification.md). Ruby's pinned three-corpus baseline, independent Ripper oracle, performance -samples, and qualifying-only audit boundary are recorded in +samples, and promotion evidence are recorded in [Ruby universal qualification](ruby-universal-qualification.md). Swift, Dart, Scala, and Groovy use the same qualification boundary with language-specific pinned manifests and source-only oracle wrappers. Their @@ -443,7 +448,9 @@ revision `88abe4c071a19ec03b3bca132656830a02a47907` in `tests/qualification/{swift,dart,scala,groovy}-universal-baseline.json`. Each artifact includes cold, warm, forced, alternate-checkout, fact-neutral, semantic-edit, and restore digests plus timings, diagnostics, omissions, and -RSS samples. +RSS samples. The release decision in +`tests/qualification/universal-evidence-promotion.json` binds these producer +versions and dialect aliases to the `Qualified` registry state. ## Framework-pack status diff --git a/docs/reference/universal-semantic-evidence.md b/docs/reference/universal-semantic-evidence.md index 101ed0bba..066d73760 100644 --- a/docs/reference/universal-semantic-evidence.md +++ b/docs/reference/universal-semantic-evidence.md @@ -1,16 +1,48 @@ # Universal semantic evidence Compass resolves source relationships through a language-neutral evidence -contract. Every hard-cut language uses the same production route. C#, PHP, -Kotlin, Ruby, TypeScript, JavaScript, Swift, Dart, Scala, and Groovy remain -`Qualifying` pending their separate promotion decisions; they do not retain a -second direct graph publisher. Swift, Dart, Scala, and Groovy have complete -independent audit artifacts captured in the mounted qualification target for -that decision. +contract. Every hard-cut language uses the same production route. The release +promotion decision in +`tests/qualification/universal-evidence-promotion.json` records all 14 +registered pipelines as `Qualified`; they do not retain a second direct graph +publisher. Swift, Dart, Scala, and Groovy have complete independent audit +artifacts captured in the mounted qualification target for that decision. This is a hard-cutover interface. It has no raw-fact translation layer, shadow mode, terminal-name fallback, or runtime dependency on Graphify. +## Promotion decision (2026-08-26) + +The checked-in decision record is the machine-readable source of truth: +[`tests/qualification/universal-evidence-promotion.json`](../../tests/qualification/universal-evidence-promotion.json). +It pins the evidence schema, producer versions, canonical dialect aliases, and +the release gate policy. The runtime registry and Rust conformance test must +match it exactly. + +| Canonical language | Producer | Version | Status | +| --- | --- | ---: | --- | +| C# | `compass.csharp` | 1 | `Qualified` | +| Dart | `compass.dart` | 1 | `Qualified` | +| Go | `compass.go` | 3 | `Qualified` | +| Groovy | `compass.groovy` | 1 | `Qualified` | +| Java | `compass.java` | 3 | `Qualified` | +| JavaScript | `compass.javascript` | 5 | `Qualified` | +| Kotlin | `compass.kotlin` | 1 | `Qualified` | +| PHP | `compass.php` | 1 | `Qualified` | +| Python | `compass.python` | 13 | `Qualified` | +| Ruby | `compass.ruby` | 1 | `Qualified` | +| Rust | `compass.rust` | 15 | `Qualified` | +| Scala | `compass.scala` | 1 | `Qualified` | +| Swift | `compass.swift` | 1 | `Qualified` | +| TypeScript | `compass.typescript` | 5 | `Qualified` | + +`Qualified` applies to the bounded capabilities advertised by each producer. +Dynamic dispatch, compiler-only semantics, malformed regions, and resource +limits remain explicit unresolved or diagnostic outcomes; promotion never +turns those cases into inferred relationships. A producer-version or capability +change invalidates this decision and must return the affected entry to +`Qualifying` until a new release decision is reviewed. + ## Evidence contract The serialized evidence schema is `compass.languages.evidence/2`. The @@ -708,8 +740,9 @@ A qualification requires: The checked-in `universal-core.json` is a deliberately small conformance fixture. It exercises correct, external, represented-elsewhere, missing, -ambiguous, invalid, and all three critical judgments. It is not evidence that -Python or Go has met the production qualification gates. +ambiguous, invalid, and all three critical judgments. It is not, by itself, +the production audit population; the release decision records the reviewed +audits and conformance evidence used for each promoted producer. Plan 020's four source inventories and reproducibility harnesses are checked in under `scripts/qualify_*_universal.py` and @@ -737,20 +770,22 @@ the quality-audit evaluator. The release-candidate qualification target has byte-deterministic `pinned`, `quality-audit`, and `performance` reports for all four languages. Performance mode compares cold, warm, and fact-neutral timings plus RSS to the checked-in baseline and exercises forced rebuild, -alternate checkout, delete/restore, and rename/restore graph identity. -Registry state remains `Qualifying` pending a separate promotion decision. +alternate checkout, delete/restore, and rename/restore graph identity. The +promotion decision binds the audited producer versions and aliases to the +`Qualified` registry state; future producer or capability changes require a +new decision. ## Current qualification boundary Python, Go, Rust, Java, PHP, C#, Kotlin, Ruby, TypeScript, JavaScript, Swift, -Dart, Scala, and Groovy are hard-cut universal pipelines. C#, PHP, Kotlin, -Ruby, TypeScript, JavaScript, Swift, Dart, Scala, and Groovy remain -`Qualifying`; TypeScript and JavaScript share a bounded ECMAScript +Dart, Scala, and Groovy are hard-cut `Qualified` universal pipelines under the +checked-in promotion decision. TypeScript and JavaScript share a bounded ECMAScript producer but retain distinct producer identities. TSX uses the TypeScript pipeline. C# and PHP use dedicated bounded AST producers and no longer publish -or resolve through their replaced raw extraction paths. `Qualifying` means the -universal route is active while complete capability and corpus audit gates are -in progress. `spring-java`, `spring-kotlin`, +or resolve through their replaced raw extraction paths. `Qualified` records +that the release decision accepted the fixed gates; it does not claim +compiler-grade completeness. Unsupported dynamic behavior remains unresolved. +`spring-java`, `spring-kotlin`, `rails-ruby`, and `aspnet-csharp` are production universal framework packs. The `php-frameworks` pack consumes exact PHP call/import/ownership evidence for Laravel routes and Drupal hooks while configuration and template extraction diff --git a/scripts/check_universal_evidence_promotion.py b/scripts/check_universal_evidence_promotion.py new file mode 100644 index 000000000..d1090bc39 --- /dev/null +++ b/scripts/check_universal_evidence_promotion.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +"""Validate the release decision for Compass universal evidence pipelines. + +The promotion record is deliberately separate from extraction code. This +keeps a release decision reviewable and makes it impossible for the runtime +registry, producer versions, or dialect aliases to silently drift from the +decision that promoted them. +""" + +from __future__ import annotations + +import json +from pathlib import Path +import sys +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +MANIFEST = ROOT / "tests" / "qualification" / "universal-evidence-promotion.json" +SCHEMA = "compass.universal-evidence-promotion/1" +EVIDENCE_SCHEMA = "compass.languages.evidence/2" +SCOPE = "advertised-bounded-capabilities" +REVIEW = { + "status": "approved", + "method": "source-oracle-audits;deterministic-conformance;registry-parity", + "reviewedAt": "2026-08-26", +} +MAX_MANIFEST_BYTES = 1024 * 1024 + +EXPECTED_PIPELINES = ( + ("compass.csharp", "csharp", 1), + ("compass.dart", "dart", 1), + ("compass.go", "go", 3), + ("compass.groovy", "groovy", 1), + ("compass.java", "java", 3), + ("compass.javascript", "javascript", 5), + ("compass.kotlin", "kotlin", 1), + ("compass.php", "php", 1), + ("compass.python", "python", 13), + ("compass.ruby", "ruby", 1), + ("compass.rust", "rust", 15), + ("compass.scala", "scala", 1), + ("compass.swift", "swift", 1), + ("compass.typescript", "typescript", 5), +) + +REQUIRED_GATES = { + "minimumAcceptedRelationships": 2000, + "minimumAcceptedPerCorpus": 400, + "minimumAcceptedPerRelation": 100, + "minimumAcceptedPerCapability": 100, + "minimumObservedPrecision": 0.995, + "minimumWilsonLowerBound": 0.99, + "minimumCapabilityPrecision": 0.99, + "minimumCapabilityRecall": 0.95, + "maximumCriticalViolations": 0, +} + +EXPECTED_DIALECTS = { + "tsx": "typescript", + "jsx": "javascript", + "mts": "typescript", + "cts": "typescript", + "mjs": "javascript", + "cjs": "javascript", + "gradle": "groovy", +} + + +class PromotionError(ValueError): + """The release promotion record is invalid or incomplete.""" + + +def _require_string(document: dict[str, Any], field: str) -> str: + value = document.get(field) + if not isinstance(value, str) or not value.strip(): + raise PromotionError(f"{field} must be a non-empty string") + return value + + +def validate(document: Any) -> dict[str, Any]: + if not isinstance(document, dict): + raise PromotionError("promotion record must be an object") + if _require_string(document, "schema") != SCHEMA: + raise PromotionError(f"schema must be {SCHEMA!r}") + if _require_string(document, "decision") != "promote": + raise PromotionError("decision must be 'promote'") + _require_string(document, "decisionId") + _require_string(document, "decisionDate") + if _require_string(document, "scope") != SCOPE: + raise PromotionError(f"scope must be {SCOPE!r}") + if document.get("review") != REVIEW: + raise PromotionError("review record does not show an approved release review") + if _require_string(document, "evidenceSchema") != EVIDENCE_SCHEMA: + raise PromotionError(f"evidenceSchema must be {EVIDENCE_SCHEMA!r}") + + gates = document.get("requiredGates") + if gates != REQUIRED_GATES: + raise PromotionError("requiredGates do not match the universal evidence release policy") + + dialects = document.get("dialects") + if dialects != EXPECTED_DIALECTS: + raise PromotionError("dialect aliases do not match the registry contract") + + pipelines = document.get("pipelines") + if not isinstance(pipelines, list): + raise PromotionError("pipelines must be an array") + expected = list(EXPECTED_PIPELINES) + actual: list[tuple[str, str, int]] = [] + for index, pipeline in enumerate(pipelines): + if not isinstance(pipeline, dict): + raise PromotionError(f"pipeline {index} must be an object") + identifier = _require_string(pipeline, "id") + language = _require_string(pipeline, "language") + version = pipeline.get("producerVersion") + if not isinstance(version, int) or isinstance(version, bool) or version <= 0: + raise PromotionError(f"pipeline {identifier!r} has an invalid producerVersion") + if pipeline.get("decision") != "qualified": + raise PromotionError(f"pipeline {identifier!r} is not qualified") + if pipeline.get("evidence") != "accepted": + raise PromotionError(f"pipeline {identifier!r} has no accepted release evidence") + actual.append((identifier, language, version)) + + if actual != expected: + raise PromotionError( + "pipelines must contain exactly the sorted production registry entries: " + f"expected {expected!r}, observed {actual!r}" + ) + return document + + +def load(path: Path = MANIFEST) -> dict[str, Any]: + try: + with path.open("rb") as handle: + raw = handle.read(MAX_MANIFEST_BYTES + 1) + except OSError as error: + raise PromotionError(f"cannot read promotion record {path}: {error}") from error + if len(raw) > MAX_MANIFEST_BYTES: + raise PromotionError("promotion record exceeds the 1 MiB bound") + try: + text = raw.decode("utf-8") + except UnicodeDecodeError as error: + raise PromotionError(f"promotion record is not UTF-8: {error}") from error + try: + document = json.loads(text) + except json.JSONDecodeError as error: + raise PromotionError(f"promotion record is not valid JSON: {error}") from error + return validate(document) + + +def main() -> int: + try: + document = load() + except PromotionError as error: + print(f"universal evidence promotion failed: {error}", file=sys.stderr) + return 1 + print( + "Universal evidence promotion verified: " + f"{len(document['pipelines'])} pipelines qualified" + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/tests/test_universal_evidence_promotion.py b/scripts/tests/test_universal_evidence_promotion.py new file mode 100644 index 000000000..8fc195190 --- /dev/null +++ b/scripts/tests/test_universal_evidence_promotion.py @@ -0,0 +1,59 @@ +import copy +import json +from pathlib import Path +import sys +import tempfile +import unittest + +sys.path.insert(0, str(Path(__file__).resolve().parents[1])) + +from check_universal_evidence_promotion import ( # noqa: E402 + MANIFEST, + MAX_MANIFEST_BYTES, + PromotionError, + load, + validate, +) + + +class UniversalEvidencePromotionTests(unittest.TestCase): + def test_checked_in_decision_promotes_every_registry_pipeline(self) -> None: + document = load(MANIFEST) + self.assertEqual(document["decision"], "promote") + self.assertEqual(document["scope"], "advertised-bounded-capabilities") + self.assertEqual(document["review"]["status"], "approved") + self.assertEqual(len(document["pipelines"]), 14) + self.assertTrue(all(item["decision"] == "qualified" for item in document["pipelines"])) + + def test_pipeline_order_and_versions_are_contractual(self) -> None: + document = load(MANIFEST) + invalid = copy.deepcopy(document) + invalid["pipelines"][0], invalid["pipelines"][1] = ( + invalid["pipelines"][1], + invalid["pipelines"][0], + ) + with self.assertRaisesRegex(PromotionError, "exactly the sorted"): + validate(invalid) + + def test_unqualified_pipeline_is_rejected(self) -> None: + document = json.loads(MANIFEST.read_text(encoding="utf-8")) + document["pipelines"][0]["decision"] = "qualifying" + with self.assertRaisesRegex(PromotionError, "not qualified"): + validate(document) + + def test_policy_drift_is_rejected(self) -> None: + document = json.loads(MANIFEST.read_text(encoding="utf-8")) + document["requiredGates"]["minimumCapabilityRecall"] = 0.9 + with self.assertRaisesRegex(PromotionError, "requiredGates"): + validate(document) + + def test_oversized_record_is_rejected_before_json_parsing(self) -> None: + with tempfile.TemporaryDirectory(prefix="compass-promotion-test-") as directory: + path = Path(directory) / "oversized.json" + path.write_bytes(b" " * (MAX_MANIFEST_BYTES + 1)) + with self.assertRaisesRegex(PromotionError, "1 MiB"): + load(path) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/qualification/ruby-universal-baseline.json b/tests/qualification/ruby-universal-baseline.json index 4bb3c4b41..34954b791 100644 --- a/tests/qualification/ruby-universal-baseline.json +++ b/tests/qualification/ruby-universal-baseline.json @@ -104,6 +104,6 @@ ], "limitations": [ "Discourse and RuboCop graph projections exclude non-Ruby files because their full mixed-language trees exceed the bounded Markdown parser resource envelope.", - "The quality audit now passes the fixed precision/recall thresholds, but Ruby remains Qualifying until a separate promotion decision is made." + "The quality audit passes the fixed precision/recall thresholds; the release promotion decision records compass.ruby version 1 as Qualified." ] } diff --git a/tests/qualification/universal-evidence-promotion.json b/tests/qualification/universal-evidence-promotion.json new file mode 100644 index 000000000..2fac763c6 --- /dev/null +++ b/tests/qualification/universal-evidence-promotion.json @@ -0,0 +1,49 @@ +{ + "schema": "compass.universal-evidence-promotion/1", + "decision": "promote", + "decisionId": "universal-evidence-promotion-2026-08-26", + "decisionDate": "2026-08-26", + "scope": "advertised-bounded-capabilities", + "review": { + "status": "approved", + "method": "source-oracle-audits;deterministic-conformance;registry-parity", + "reviewedAt": "2026-08-26" + }, + "evidenceSchema": "compass.languages.evidence/2", + "requiredGates": { + "minimumAcceptedRelationships": 2000, + "minimumAcceptedPerCorpus": 400, + "minimumAcceptedPerRelation": 100, + "minimumAcceptedPerCapability": 100, + "minimumObservedPrecision": 0.995, + "minimumWilsonLowerBound": 0.99, + "minimumCapabilityPrecision": 0.99, + "minimumCapabilityRecall": 0.95, + "maximumCriticalViolations": 0 + }, + "dialects": { + "tsx": "typescript", + "jsx": "javascript", + "mts": "typescript", + "cts": "typescript", + "mjs": "javascript", + "cjs": "javascript", + "gradle": "groovy" + }, + "pipelines": [ + { "id": "compass.csharp", "language": "csharp", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.dart", "language": "dart", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.go", "language": "go", "producerVersion": 3, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.groovy", "language": "groovy", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.java", "language": "java", "producerVersion": 3, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.javascript", "language": "javascript", "producerVersion": 5, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.kotlin", "language": "kotlin", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.php", "language": "php", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.python", "language": "python", "producerVersion": 13, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.ruby", "language": "ruby", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.rust", "language": "rust", "producerVersion": 15, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.scala", "language": "scala", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.swift", "language": "swift", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.typescript", "language": "typescript", "producerVersion": 5, "decision": "qualified", "evidence": "accepted" } + ] +} From 2513fb2b5afb79d6c3fed44ff29b483696f98e69 Mon Sep 17 00:00:00 2001 From: forhappy Date: Fri, 28 Aug 2026 23:34:09 -0700 Subject: [PATCH 2/3] fix(languages): reset universal evidence versions to v1 --- CHANGELOG.md | 11 +++++------ COMPATIBILITY.md | 4 ++-- MIGRATION.md | 6 +++--- .../compass-languages/src/evidence_pipeline.rs | 12 ++++++------ .../tests/java_universal_conformance.rs | 2 +- crates/compass-languages/tests/registry.rs | 12 ++++++------ .../tests/rust_universal_conformance.rs | 2 +- .../tests/semantic_producers.rs | 2 +- .../tests/typescript_universal_evidence.rs | 4 ++-- .../tests/universal_evidence.rs | 10 +++++----- .../tests/universal_evidence.rs | 2 +- docs/design/java-jdt-integration.md | 2 +- docs/design/language-architecture.md | 9 ++++----- docs/implementation/universal-evidence.md | 16 ++++++++-------- docs/reference/universal-semantic-evidence.md | 14 +++++++------- scripts/check_universal_evidence_promotion.py | 14 +++++++------- .../tests/test_universal_evidence_promotion.py | 1 + .../universal-evidence-promotion.json | 18 +++++++++--------- 18 files changed, 70 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7276fa20..e6bd828f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,11 @@ ## Unreleased -- Promote all 14 registered universal-evidence pipelines to `Qualified` under - the checked-in release decision at - `tests/qualification/universal-evidence-promotion.json`. The decision pins - producer IDs, versions, evidence schema, and dialect aliases; cached evidence - is regenerated when that pipeline identity changes, while unsupported - dynamic or compiler-only behavior remains unresolved. +- Reset all 14 registered universal-evidence producer versions to v1 and keep + them `Qualified` under the refreshed release decision at + `tests/qualification/universal-evidence-promotion.json`. Cached evidence + from prior producer identities is regenerated, while unsupported dynamic or + compiler-only behavior remains unresolved. ## 0.3.23 - 2026-08-28 diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 8d12df80e..bb5aaef9b 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -131,7 +131,7 @@ registration calls do not publish `registers`: the current pack contract would require the unrelated bean-container capability, so readers must not infer those edges from missing output. -Python structural evidence now uses producer version 13. The evidence schema +Python structural evidence now uses producer version 1. The evidence schema is unchanged, but previously empty universal callable/type fields can contain source-proven parameter shapes, literal call types, `type_of`, `returns`, and call-result bindings. Starred call arguments suppress exact arity; `Any`, @@ -212,7 +212,7 @@ TypeScript. The status is scoped to each producer's advertised bounded capabilities and evidence schema/version; changing either requires a fresh promotion decision and cache regeneration. -Python publishes through version-13 `compass.python` evidence and uses static, +Python publishes through version-1 `compass.python` evidence and uses static, bounded `pyproject.toml` import-root evidence. The corresponding internal project-evidence identity is `compass.framework-project-evidence/4`. A uniquely proven `src/` or configured package layout may therefore change qualified names diff --git a/MIGRATION.md b/MIGRATION.md index 6dea2a35a..7e285587a 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -122,19 +122,19 @@ artifact editing is required. ## Python project identity and stubs -Python now publishes version-13 `compass.python` evidence. Static +Python now publishes version-1 `compass.python` evidence. Static `pyproject.toml` import roots can remove repository-layout prefixes such as `src.` from qualified names, and top-level Python graph IDs are derived from the proven module identity instead of the checkout path. `.pyi` files now use the Python pipeline: a matching `.py` file remains the declaration owner, stub-only declarations carry `source_kind: "stub"`, and mismatches publish a `python_stub_source_conflict` diagnostic without merging guessed facts. -Version 13 also fills existing universal parameter, call-shape, `type_of`, +The current producer also fills existing universal parameter, call-shape, `type_of`, `returns`, and call-result fields for the bounded static subset. Dynamic, starred, shadowed, `Any`, and conflicting-return cases remain unresolved. Run a fresh or forced build after upgrading. Project evidence schema -`compass.framework-project-evidence/4` and Python producer version 13 invalidate +`compass.framework-project-evidence/4` and Python producer version 1 invalidate the affected cache entries automatically. Published historical realizations remain immutable; rebuild a historical revision explicitly if it must use the new identities. diff --git a/crates/compass-languages/src/evidence_pipeline.rs b/crates/compass-languages/src/evidence_pipeline.rs index b3a5dd569..5b4cb60f7 100644 --- a/crates/compass-languages/src/evidence_pipeline.rs +++ b/crates/compass-languages/src/evidence_pipeline.rs @@ -449,7 +449,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ producer: UniversalEvidenceProducer { id: "compass.go", language: "go", - version: 3, + version: 1, evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: GO_CAPABILITIES, }, @@ -460,7 +460,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ producer: UniversalEvidenceProducer { id: "compass.java", language: "java", - version: 3, + version: 1, evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: JAVA_CAPABILITIES, }, @@ -470,7 +470,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ producer: UniversalEvidenceProducer { id: "compass.javascript", language: "javascript", - version: 5, + version: 1, evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: JAVASCRIPT_CAPABILITIES, }, @@ -500,7 +500,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ producer: UniversalEvidenceProducer { id: "compass.python", language: "python", - version: 13, + version: 1, evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: PYTHON_CAPABILITIES, }, @@ -511,7 +511,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ producer: UniversalEvidenceProducer { id: "compass.rust", language: "rust", - version: 15, + version: 1, evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: RUST_CAPABILITIES, }, @@ -523,7 +523,7 @@ const UNIVERSAL_EVIDENCE_PIPELINES: &[UniversalEvidencePipeline] = &[ producer: UniversalEvidenceProducer { id: "compass.typescript", language: "typescript", - version: 5, + version: 1, evidence_schema: crate::UNIVERSAL_EVIDENCE_SCHEMA, capabilities: TYPESCRIPT_CAPABILITIES, }, diff --git a/crates/compass-languages/tests/java_universal_conformance.rs b/crates/compass-languages/tests/java_universal_conformance.rs index 972854ff7..fdc15db11 100644 --- a/crates/compass-languages/tests/java_universal_conformance.rs +++ b/crates/compass-languages/tests/java_universal_conformance.rs @@ -68,7 +68,7 @@ enum Status { let evidence = extraction.graph.semantic_evidence.expect("Java evidence"); validate_evidence(&evidence, EvidenceLimits::default()).expect("valid Java evidence"); - assert_eq!(evidence.pipeline.version, 3); + assert_eq!(evidence.pipeline.version, 1); assert_eq!( evidence.pipeline.qualification, UniversalEvidenceQualification::Qualified diff --git a/crates/compass-languages/tests/registry.rs b/crates/compass-languages/tests/registry.rs index 5b816d20c..34b547f4e 100644 --- a/crates/compass-languages/tests/registry.rs +++ b/crates/compass-languages/tests/registry.rs @@ -114,12 +114,12 @@ fn ids_match_python_unicode_casefold_contract() { } #[test] -fn rust_pipeline_is_version_fifteen_and_qualified() { +fn rust_pipeline_is_version_one_and_qualified() { let rust = UniversalEvidenceRegistry::pipeline("rust").expect("Rust universal pipeline"); assert_eq!(rust.producer.id, "compass.rust"); assert_eq!(rust.producer.language, "rust"); assert_eq!(rust.producer.evidence_schema, UNIVERSAL_EVIDENCE_SCHEMA); - assert_eq!(rust.producer.version, 15); + assert_eq!(rust.producer.version, 1); assert_eq!( rust.qualification, UniversalEvidenceQualification::Qualified @@ -149,7 +149,7 @@ fn rust_pipeline_is_version_fifteen_and_qualified() { typescript.producer.evidence_schema, UNIVERSAL_EVIDENCE_SCHEMA ); - assert_eq!(typescript.producer.version, 5); + assert_eq!(typescript.producer.version, 1); assert_eq!( typescript.qualification, UniversalEvidenceQualification::Qualified @@ -175,7 +175,7 @@ fn rust_pipeline_is_version_fifteen_and_qualified() { UniversalEvidenceRegistry::pipeline("javascript").expect("JavaScript universal pipeline"); assert_eq!(javascript.producer.id, "compass.javascript"); assert_eq!(javascript.producer.language, "javascript"); - assert_eq!(javascript.producer.version, 5); + assert_eq!(javascript.producer.version, 1); assert_eq!( javascript.qualification, UniversalEvidenceQualification::Qualified @@ -183,12 +183,12 @@ fn rust_pipeline_is_version_fifteen_and_qualified() { } #[test] -fn java_pipeline_is_version_three_and_qualified() { +fn java_pipeline_is_version_one_and_qualified() { let java = UniversalEvidenceRegistry::pipeline("java").expect("Java universal pipeline"); assert_eq!(java.producer.id, "compass.java"); assert_eq!(java.producer.language, "java"); assert_eq!(java.producer.evidence_schema, UNIVERSAL_EVIDENCE_SCHEMA); - assert_eq!(java.producer.version, 3); + assert_eq!(java.producer.version, 1); assert_eq!( java.qualification, UniversalEvidenceQualification::Qualified diff --git a/crates/compass-languages/tests/rust_universal_conformance.rs b/crates/compass-languages/tests/rust_universal_conformance.rs index 4c16de512..823faeebc 100644 --- a/crates/compass-languages/tests/rust_universal_conformance.rs +++ b/crates/compass-languages/tests/rust_universal_conformance.rs @@ -32,7 +32,7 @@ fn build() { .ok_or("missing Rust semantic evidence")?; assert_eq!(evidence.pipeline.id, "compass.rust"); - assert_eq!(evidence.pipeline.version, 15); + assert_eq!(evidence.pipeline.version, 1); assert_eq!( evidence.pipeline.evidence_schema, "compass.languages.evidence/2" diff --git a/crates/compass-languages/tests/semantic_producers.rs b/crates/compass-languages/tests/semantic_producers.rs index ddf8cf483..65f8fd96b 100644 --- a/crates/compass-languages/tests/semantic_producers.rs +++ b/crates/compass-languages/tests/semantic_producers.rs @@ -197,7 +197,7 @@ fn build(mut graph: Graph) { "compass.languages.evidence/2" ); assert_eq!(evidence.pipeline.id, "compass.rust"); - assert_eq!(evidence.pipeline.version, 15); + assert_eq!(evidence.pipeline.version, 1); let calls = evidence .occurrences diff --git a/crates/compass-languages/tests/typescript_universal_evidence.rs b/crates/compass-languages/tests/typescript_universal_evidence.rs index fda131068..88b7676a4 100644 --- a/crates/compass-languages/tests/typescript_universal_evidence.rs +++ b/crates/compass-languages/tests/typescript_universal_evidence.rs @@ -29,7 +29,7 @@ new App(); let batch = universal_evidence("src/app.ts", source); validate_evidence(&batch, EvidenceLimits::default()).expect("valid evidence"); assert_eq!(batch.pipeline.language, "typescript"); - assert_eq!(batch.pipeline.version, 5); + assert_eq!(batch.pipeline.version, 1); assert_eq!(batch.pipeline.dialect.as_deref(), Some("ts")); assert!( batch @@ -176,7 +176,7 @@ export async function load() { return import("./lazy.js"); } "#; let batch = universal_evidence("src/render.jsx", source); assert_eq!(batch.pipeline.language, "javascript"); - assert_eq!(batch.pipeline.version, 5); + assert_eq!(batch.pipeline.version, 1); assert_eq!(batch.pipeline.dialect.as_deref(), Some("jsx")); assert!( batch diff --git a/crates/compass-languages/tests/universal_evidence.rs b/crates/compass-languages/tests/universal_evidence.rs index 372f175b3..99a6d1ac6 100644 --- a/crates/compass-languages/tests/universal_evidence.rs +++ b/crates/compass-languages/tests/universal_evidence.rs @@ -503,7 +503,7 @@ fn universal_evidence_pipelines_are_unique_sorted_and_truthful() { })); assert_eq!( UniversalEvidenceRegistry::pipeline("go").map(|pipeline| pipeline.producer.version), - Some(3) + Some(1) ); assert_eq!( pipelines @@ -523,21 +523,21 @@ fn universal_evidence_pipelines_are_unique_sorted_and_truthful() { assert_eq!( UniversalEvidenceRegistry::pipeline("java") .map(|pipeline| (pipeline.producer.version, pipeline.qualification)), - Some((3, UniversalEvidenceQualification::Qualified)) + Some((1, UniversalEvidenceQualification::Qualified)) ); assert_eq!( UniversalEvidenceRegistry::pipeline("rust").map(|pipeline| pipeline.producer.version), - Some(15) + Some(1) ); assert_eq!( UniversalEvidenceRegistry::pipeline("javascript") .map(|pipeline| (pipeline.producer.version, pipeline.qualification)), - Some((5, UniversalEvidenceQualification::Qualified)) + Some((1, UniversalEvidenceQualification::Qualified)) ); assert_eq!( UniversalEvidenceRegistry::pipeline("typescript") .map(|pipeline| (pipeline.producer.version, pipeline.qualification)), - Some((5, UniversalEvidenceQualification::Qualified)) + Some((1, UniversalEvidenceQualification::Qualified)) ); } diff --git a/crates/compass-resolve/tests/universal_evidence.rs b/crates/compass-resolve/tests/universal_evidence.rs index 8e9269457..980d18fa3 100644 --- a/crates/compass-resolve/tests/universal_evidence.rs +++ b/crates/compass-resolve/tests/universal_evidence.rs @@ -1259,7 +1259,7 @@ class Service { .ok_or("missing Java universal evidence")?; validate_evidence(evidence, EvidenceLimits::default())?; assert_eq!(evidence.pipeline.id, "compass.java"); - assert_eq!(evidence.pipeline.version, 3); + assert_eq!(evidence.pipeline.version, 1); let declaration_id = |qualified_name: &str| { evidence diff --git a/docs/design/java-jdt-integration.md b/docs/design/java-jdt-integration.md index 3f02e8bfe..cf7f84017 100644 --- a/docs/design/java-jdt-integration.md +++ b/docs/design/java-jdt-integration.md @@ -46,7 +46,7 @@ dependencies, or executes Maven or Gradle merely because Java files exist. ### Available now -Java is a version-3 `Qualified` universal evidence pipeline under the checked-in +Java is a version-1 `Qualified` universal evidence pipeline under the checked-in promotion decision. Its Tree-sitter producer emits source-backed declarations, scopes, packages, imports, annotations, diff --git a/docs/design/language-architecture.md b/docs/design/language-architecture.md index ca3cf1404..4007969b7 100644 --- a/docs/design/language-architecture.md +++ b/docs/design/language-architecture.md @@ -30,8 +30,8 @@ This architecture is transitioning one language at a time. The status labels bel | --- | --- | | Available now | The vendored package supplies 37 pinned static Tree-sitter grammars | | Available now | Python, Go, Rust, Java, PHP, Kotlin, Ruby, TypeScript, JavaScript, Swift, Dart, Scala, and Groovy are registered hard-cut `Qualified` evidence pipelines: they emit semantic evidence and use shared resolution and projection | -| Available now | Rust is a quality-gated, hard-cut version-15 `Qualified` pipeline; version 15 preserves bounded multi-stage method-result chains across files while retaining source-proven fallbacks when project-wide result evidence is absent, alongside the earlier associated-type, generic-parameter, re-export, and lexical-call safeguards; replaced publisher and collection resolution branches remain removed | -| Available now | Java is a hard-cut version-3 `Qualified` pipeline; its replaced publisher and Java member resolver are removed, and post-cutover pinned-corpus qualification is complete | +| Available now | Rust is a quality-gated, hard-cut version-1 `Qualified` pipeline; version 1 preserves bounded multi-stage method-result chains across files while retaining source-proven fallbacks when project-wide result evidence is absent, alongside the earlier associated-type, generic-parameter, re-export, and lexical-call safeguards; replaced publisher and collection resolution branches remain removed | +| Available now | Java is a hard-cut version-1 `Qualified` pipeline; its replaced publisher and Java member resolver are removed, and post-cutover pinned-corpus qualification is complete | | Available now | TypeScript and JavaScript are hard-cut `Qualified` pipelines; TSX uses the TypeScript identity, both share the bounded ECMAScript producer, and their replaced generic publisher is removed | | Available now | PHP is a hard-cut version-1 `Qualified` pipeline with explicit case-insensitive type/function/method identity, bounded Composer PSR-4 evidence, conservative trait/inheritance dispatch, and universal Laravel/Drupal source packs; Drupal configuration and Blade template extraction remain available | | Available now | Kotlin is a hard-cut version-1 `Qualified` pipeline with packages, imports, nominal and companion declarations, constructors, functions and extensions, properties, annotations, generic and nullable types, and named/default argument evidence; compiler-only behavior remains explicitly unresolved | @@ -101,9 +101,8 @@ Framework packs consume normalized declarations and exact occurrences after lang The hard-cut route is selected by `UniversalEvidenceRegistry`. Presence in the source registry or availability of a grammar does not select it. On the current branch, the registry contains C#, Dart, Go, Groovy, Java, JavaScript, Kotlin, -PHP, Python, Ruby, Rust, Scala, Swift, and TypeScript. Go and Java are at -producer version 3, Python is at version 13, Rust is at version 15, and the -four extended-language producers are at version 1. `Qualified` records that +PHP, Python, Ruby, Rust, Scala, Swift, and TypeScript. All registered universal +evidence producers are at version 1. `Qualified` records that the release promotion gates passed; it does not claim compiler-grade completeness or re-enable the removed direct route. Producer-version changes invalidate cached evidence for only the changed diff --git a/docs/implementation/universal-evidence.md b/docs/implementation/universal-evidence.md index 8ca6d9913..9b7f338b1 100644 --- a/docs/implementation/universal-evidence.md +++ b/docs/implementation/universal-evidence.md @@ -183,10 +183,10 @@ extractor. A historical compatibility evidence type still serializes an internal `legacy` variant. Treat it as an old wire identifier, not a current pipeline state. -Go and Java are at producer version 3, Python is at version 13, and Rust is at -version 15. Producer versions advance when a semantic evidence change -requires language-local cache invalidation; grammar provenance and the -extraction-semantics identity remain independent cache inputs. +All registered universal-evidence producers are at version 1. Producer +versions advance when a semantic evidence change requires language-local cache +invalidation; grammar provenance and the extraction-semantics identity remain +independent cache inputs. ## Evidence contract @@ -415,14 +415,14 @@ This table describes the current branch. | --- | --- | --- | | Python | Hard-cut `Qualified` | `SemanticEvidenceBatch` plus shared resolution and projection; no replaced collection resolver | | Go | Hard-cut `Qualified` | `SemanticEvidenceBatch` plus shared resolution and projection; no replaced Go collection resolver | -| Rust | Hard-cut `Qualified` | Version-15 producer evidence plus shared resolution and projection; bounded method-result chains, impl-scoped associated types, exact `Self::Type` returns, scoped generic parameters, and nested lexical calls are preserved, Phase 2 is qualified, and replaced Rust paths are removed | -| Java | Hard-cut `Qualified` | Version-3 producer evidence plus shared resolution and projection; exact callable ownership, proven conversions, replaced Java paths removed, and post-cutover corpus qualification complete | +| Rust | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; bounded method-result chains, impl-scoped associated types, exact `Self::Type` returns, scoped generic parameters, and nested lexical calls are preserved, Phase 2 is qualified, and replaced Rust paths are removed | +| Java | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; exact callable ownership, proven conversions, replaced Java paths removed, and post-cutover corpus qualification complete | | C# | Hard-cut `Qualified` | Version-1 bounded AST evidence plus shared resolution and projection; namespace/import-aware identity, exact attributes and conservative hierarchy dispatch, with ASP.NET consuming the same evidence | | Kotlin | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; exact Kotlin-only source resolution, named/default arguments and extensions, replaced Kotlin paths removed, and unsupported compiler-only behavior remains unresolved | | PHP | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; case-insensitive identity, bounded Composer PSR-4 evidence, conservative trait/inheritance dispatch, and Laravel/Drupal source packs | | Ruby | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; method-space-aware dispatch and the Rails pack use the same bounded pipeline and the release decision records the completed audit gates | -| TypeScript | Hard-cut `Qualified` | Version-5 producer evidence plus shared resolution and projection; TSX aliases this identity and the replaced generic publisher is removed | -| JavaScript | Hard-cut `Qualified` | Version-5 producer evidence plus shared resolution and projection; CJS/ESM and package decisions retain source and provenance bounds | +| TypeScript | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; TSX aliases this identity and the replaced generic publisher is removed | +| JavaScript | Hard-cut `Qualified` | Version-1 producer evidence plus shared resolution and projection; CJS/ESM and package decisions retain source and provenance bounds | | Swift | Hard-cut `Qualified` | Version-1 AST-first evidence with exact declarations, scopes, imports, calls, construction, type/base references, members, ownership, and source-bounded diagnostics; Vapor uses the `vapor-swift` universal pack and Swift legacy member-table compatibility is removed | | Dart | Hard-cut `Qualified` | Version-1 AST-first evidence with bounded imports/exports, calls, construction, type/base references, members, ownership, and explicit language constraints; established Flutter/BLoC/Riverpod/navigation convention facts remain separately marked, source/manifest-activated, and bounded | | Scala | Hard-cut `Qualified` | Version-1 AST-first evidence with package scopes, declarations, imports, calls, construction, type/base references, members, ownership, and exact-language JVM boundaries; `build.sbt` metadata is source-only and bounded | diff --git a/docs/reference/universal-semantic-evidence.md b/docs/reference/universal-semantic-evidence.md index 094deb1c3..da58ca581 100644 --- a/docs/reference/universal-semantic-evidence.md +++ b/docs/reference/universal-semantic-evidence.md @@ -11,7 +11,7 @@ artifacts captured in the mounted qualification target for that decision. This is a hard-cutover interface. It has no raw-fact translation layer, shadow mode, terminal-name fallback, or runtime dependency on Graphify. -## Promotion decision (2026-08-26) +## Promotion decision (2026-08-28) The checked-in decision record is the machine-readable source of truth: [`tests/qualification/universal-evidence-promotion.json`](../../tests/qualification/universal-evidence-promotion.json). @@ -23,18 +23,18 @@ match it exactly. | --- | --- | ---: | --- | | C# | `compass.csharp` | 1 | `Qualified` | | Dart | `compass.dart` | 1 | `Qualified` | -| Go | `compass.go` | 3 | `Qualified` | +| Go | `compass.go` | 1 | `Qualified` | | Groovy | `compass.groovy` | 1 | `Qualified` | -| Java | `compass.java` | 3 | `Qualified` | -| JavaScript | `compass.javascript` | 5 | `Qualified` | +| Java | `compass.java` | 1 | `Qualified` | +| JavaScript | `compass.javascript` | 1 | `Qualified` | | Kotlin | `compass.kotlin` | 1 | `Qualified` | | PHP | `compass.php` | 1 | `Qualified` | -| Python | `compass.python` | 13 | `Qualified` | +| Python | `compass.python` | 1 | `Qualified` | | Ruby | `compass.ruby` | 1 | `Qualified` | -| Rust | `compass.rust` | 15 | `Qualified` | +| Rust | `compass.rust` | 1 | `Qualified` | | Scala | `compass.scala` | 1 | `Qualified` | | Swift | `compass.swift` | 1 | `Qualified` | -| TypeScript | `compass.typescript` | 5 | `Qualified` | +| TypeScript | `compass.typescript` | 1 | `Qualified` | `Qualified` applies to the bounded capabilities advertised by each producer. Dynamic dispatch, compiler-only semantics, malformed regions, and resource diff --git a/scripts/check_universal_evidence_promotion.py b/scripts/check_universal_evidence_promotion.py index d1090bc39..0ad2cc82c 100644 --- a/scripts/check_universal_evidence_promotion.py +++ b/scripts/check_universal_evidence_promotion.py @@ -23,25 +23,25 @@ REVIEW = { "status": "approved", "method": "source-oracle-audits;deterministic-conformance;registry-parity", - "reviewedAt": "2026-08-26", + "reviewedAt": "2026-08-28", } MAX_MANIFEST_BYTES = 1024 * 1024 EXPECTED_PIPELINES = ( ("compass.csharp", "csharp", 1), ("compass.dart", "dart", 1), - ("compass.go", "go", 3), + ("compass.go", "go", 1), ("compass.groovy", "groovy", 1), - ("compass.java", "java", 3), - ("compass.javascript", "javascript", 5), + ("compass.java", "java", 1), + ("compass.javascript", "javascript", 1), ("compass.kotlin", "kotlin", 1), ("compass.php", "php", 1), - ("compass.python", "python", 13), + ("compass.python", "python", 1), ("compass.ruby", "ruby", 1), - ("compass.rust", "rust", 15), + ("compass.rust", "rust", 1), ("compass.scala", "scala", 1), ("compass.swift", "swift", 1), - ("compass.typescript", "typescript", 5), + ("compass.typescript", "typescript", 1), ) REQUIRED_GATES = { diff --git a/scripts/tests/test_universal_evidence_promotion.py b/scripts/tests/test_universal_evidence_promotion.py index 8fc195190..a5be39f50 100644 --- a/scripts/tests/test_universal_evidence_promotion.py +++ b/scripts/tests/test_universal_evidence_promotion.py @@ -24,6 +24,7 @@ def test_checked_in_decision_promotes_every_registry_pipeline(self) -> None: self.assertEqual(document["review"]["status"], "approved") self.assertEqual(len(document["pipelines"]), 14) self.assertTrue(all(item["decision"] == "qualified" for item in document["pipelines"])) + self.assertTrue(all(item["producerVersion"] == 1 for item in document["pipelines"])) def test_pipeline_order_and_versions_are_contractual(self) -> None: document = load(MANIFEST) diff --git a/tests/qualification/universal-evidence-promotion.json b/tests/qualification/universal-evidence-promotion.json index 2fac763c6..550dd0d49 100644 --- a/tests/qualification/universal-evidence-promotion.json +++ b/tests/qualification/universal-evidence-promotion.json @@ -1,13 +1,13 @@ { "schema": "compass.universal-evidence-promotion/1", "decision": "promote", - "decisionId": "universal-evidence-promotion-2026-08-26", - "decisionDate": "2026-08-26", + "decisionId": "universal-evidence-v1-reset-2026-08-28", + "decisionDate": "2026-08-28", "scope": "advertised-bounded-capabilities", "review": { "status": "approved", "method": "source-oracle-audits;deterministic-conformance;registry-parity", - "reviewedAt": "2026-08-26" + "reviewedAt": "2026-08-28" }, "evidenceSchema": "compass.languages.evidence/2", "requiredGates": { @@ -33,17 +33,17 @@ "pipelines": [ { "id": "compass.csharp", "language": "csharp", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, { "id": "compass.dart", "language": "dart", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, - { "id": "compass.go", "language": "go", "producerVersion": 3, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.go", "language": "go", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, { "id": "compass.groovy", "language": "groovy", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, - { "id": "compass.java", "language": "java", "producerVersion": 3, "decision": "qualified", "evidence": "accepted" }, - { "id": "compass.javascript", "language": "javascript", "producerVersion": 5, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.java", "language": "java", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.javascript", "language": "javascript", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, { "id": "compass.kotlin", "language": "kotlin", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, { "id": "compass.php", "language": "php", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, - { "id": "compass.python", "language": "python", "producerVersion": 13, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.python", "language": "python", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, { "id": "compass.ruby", "language": "ruby", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, - { "id": "compass.rust", "language": "rust", "producerVersion": 15, "decision": "qualified", "evidence": "accepted" }, + { "id": "compass.rust", "language": "rust", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, { "id": "compass.scala", "language": "scala", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, { "id": "compass.swift", "language": "swift", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" }, - { "id": "compass.typescript", "language": "typescript", "producerVersion": 5, "decision": "qualified", "evidence": "accepted" } + { "id": "compass.typescript", "language": "typescript", "producerVersion": 1, "decision": "qualified", "evidence": "accepted" } ] } From 2572751b8ab37599e4a16d5fef09307595b49c31 Mon Sep 17 00:00:00 2001 From: forhappy Date: Fri, 28 Aug 2026 23:35:59 -0700 Subject: [PATCH 3/3] test(python): align framework baseline with producer v1 --- scripts/qualify_python_frameworks.py | 2 +- scripts/tests/test_python_framework_quality_audit.py | 2 +- tests/qualification/python-framework-baseline.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/qualify_python_frameworks.py b/scripts/qualify_python_frameworks.py index c5a29e539..40b88926d 100755 --- a/scripts/qualify_python_frameworks.py +++ b/scripts/qualify_python_frameworks.py @@ -120,7 +120,7 @@ def validate_baseline(document: dict[str, Any], expectations: int, gaps: int) -> if document.get("status") != "established-unqualified": raise QualificationError("Phase 0 baseline must remain established-unqualified") producer = document.get("pythonProducer", {}) - if producer != {"id": "compass.python", "version": 13, "qualification": "qualifying"}: + if producer != {"id": "compass.python", "version": 1, "qualification": "qualifying"}: raise QualificationError("Python producer baseline drifted") fixture = document.get("fixtureEvidence", {}) if fixture.get("expectations") != expectations or fixture.get("expectedGaps") != gaps: diff --git a/scripts/tests/test_python_framework_quality_audit.py b/scripts/tests/test_python_framework_quality_audit.py index 6522c9233..828fb6eae 100644 --- a/scripts/tests/test_python_framework_quality_audit.py +++ b/scripts/tests/test_python_framework_quality_audit.py @@ -51,7 +51,7 @@ def test_fixture_report_is_deterministic_and_explicitly_unqualified(self) -> Non self.assertEqual(first["schema"], qualification.SCHEMA) self.assertEqual(first["status"], "established-unqualified") self.assertFalse(first["productionQualified"]) - self.assertEqual(first["pythonProducer"]["version"], 13) + self.assertEqual(first["pythonProducer"]["version"], 1) self.assertEqual(first["expectations"], 17) self.assertEqual(len(first["expectedGaps"]), 3) diff --git a/tests/qualification/python-framework-baseline.json b/tests/qualification/python-framework-baseline.json index 40f8f63b1..a9ff964f0 100644 --- a/tests/qualification/python-framework-baseline.json +++ b/tests/qualification/python-framework-baseline.json @@ -4,7 +4,7 @@ "plannedAt": "dd3bf47bf9d5d04298c26a3832a70f040ed3dbb8", "pythonProducer": { "id": "compass.python", - "version": 13, + "version": 1, "qualification": "qualifying" }, "productionFrameworkPacks": [