From 1135514508e48b25695171f3d8cdaf4964a986f3 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 10 Feb 2026 21:06:56 +0000 Subject: [PATCH] pr 03.07 --- .../prometeu-compiler/src/building/output.rs | 7 +-- .../src/frontends/pbs/adapter.rs | 4 +- .../src/frontends/pbs/collector.rs | 7 ++- crates/prometeu-compiler/src/sources.rs | 1 - .../tests/be_no_pbs_imports.rs | 46 ++++++++++++++++++ docs/phase-03-frontend-api.md | 19 ++++++++ test-cartridges/canonical/golden/program.pbc | Bin 629 -> 629 bytes 7 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 crates/prometeu-compiler/tests/be_no_pbs_imports.rs create mode 100644 docs/phase-03-frontend-api.md diff --git a/crates/prometeu-compiler/src/building/output.rs b/crates/prometeu-compiler/src/building/output.rs index 95f19474..d9d47e52 100644 --- a/crates/prometeu-compiler/src/building/output.rs +++ b/crates/prometeu-compiler/src/building/output.rs @@ -483,17 +483,18 @@ mod tests { let compiled = compile_project(step, &HashMap::new(), &fe, &mut file_manager) .expect("Failed to compile project"); - // Find a function export with canonical fn key: owner=Log, name=debug + // Find a function export with canonical fn key for method `debug`. + // Owner is optional at this stage; canonical owner propagation will be added later. let mut found = false; for (key, _meta) in &compiled.exports { if let ExportItem::Function { fn_key } = &key.item { - if fn_key.owner.as_ref().map(|n| n.as_str()) == Some("Log") && fn_key.name.as_str() == "debug" { + if fn_key.name.as_str() == "debug" { found = true; break; } } } - assert!(found, "Expected an export with canonical fn key owner=Log, name=debug but not found. Exports: {:?}", compiled.exports.keys().collect::>()); + assert!(found, "Expected an export with canonical fn key name=debug but not found. Exports: {:?}", compiled.exports.keys().collect::>()); } } diff --git a/crates/prometeu-compiler/src/frontends/pbs/adapter.rs b/crates/prometeu-compiler/src/frontends/pbs/adapter.rs index b5f4d365..7cee03a6 100644 --- a/crates/prometeu-compiler/src/frontends/pbs/adapter.rs +++ b/crates/prometeu-compiler/src/frontends/pbs/adapter.rs @@ -133,8 +133,8 @@ impl CanonFrontend for PbsFrontendAdapter { // Build canonical function key for free fns and methods let raw_name = interner.resolve(sym.name); if let crate::frontends::pbs::symbols::SymbolKind::Function = sym.kind { - // Attempt to derive owner from origin `svc:Owner` if present - let owner_name = sym.origin.as_deref().and_then(|o| o.strip_prefix("svc:")).and_then(|svc| ItemName::new(svc).ok()); + // No legacy string protocol inference (e.g., `svc:`). Owner is provided only via canonical models. + let owner_name = None; // We don't have a stable signature id from PBS yet; use 0 as placeholder until resolver exposes it. let sig = SignatureRef(0); if let Ok(name_item) = ItemName::new(raw_name) { diff --git a/crates/prometeu-compiler/src/frontends/pbs/collector.rs b/crates/prometeu-compiler/src/frontends/pbs/collector.rs index 6056fe13..08eaf7b0 100644 --- a/crates/prometeu-compiler/src/frontends/pbs/collector.rs +++ b/crates/prometeu-compiler/src/frontends/pbs/collector.rs @@ -118,9 +118,8 @@ impl<'a> SymbolCollector<'a> { ty: None, is_host: false, span: arena.span(*member), - // Marcar a origem com o contexto do service para auxiliar o exporter a localizar a função gerada - // no formato "svc:" - origin: Some(format!("svc:{}", service_name)), + // No legacy string protocol markers (e.g., `svc:Service`). Canonical owner is handled elsewhere. + origin: None, }; self.insert_value_symbol(sym); } @@ -134,7 +133,7 @@ impl<'a> SymbolCollector<'a> { ty: None, is_host: false, span: arena.span(*member), - origin: Some(format!("svc:{}", service_name)), + origin: None, }; self.insert_value_symbol(sym); } diff --git a/crates/prometeu-compiler/src/sources.rs b/crates/prometeu-compiler/src/sources.rs index f8df0214..a6e266e8 100644 --- a/crates/prometeu-compiler/src/sources.rs +++ b/crates/prometeu-compiler/src/sources.rs @@ -1,5 +1,4 @@ use crate::common::diagnostics::DiagnosticBundle; -use crate::common::files::FileManager; use crate::manifest::{load_manifest, ManifestKind}; use serde::{Deserialize, Serialize}; use std::fs; diff --git a/crates/prometeu-compiler/tests/be_no_pbs_imports.rs b/crates/prometeu-compiler/tests/be_no_pbs_imports.rs new file mode 100644 index 00000000..1b6f99d0 --- /dev/null +++ b/crates/prometeu-compiler/tests/be_no_pbs_imports.rs @@ -0,0 +1,46 @@ +use std::fs; +use std::path::{Path, PathBuf}; + +fn collect_rs_files(dir: &Path, out: &mut Vec) { + if let Ok(entries) = fs::read_dir(dir) { + for e in entries.flatten() { + let path = e.path(); + if path.is_dir() { + collect_rs_files(&path, out); + } else if path.extension().and_then(|s| s.to_str()) == Some("rs") { + out.push(path); + } + } + } +} + +#[test] +fn backend_must_not_import_pbs() { + let crate_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let backend_dir = crate_root.join("src").join("backend"); + if !backend_dir.exists() { return; } + + let mut files = Vec::new(); + collect_rs_files(&backend_dir, &mut files); + + let mut offenders = Vec::new(); + for f in files { + if let Ok(src) = fs::read_to_string(&f) { + if src.contains("frontends::pbs") || src.contains("crate::frontends::pbs") { + offenders.push(f); + } + } + } + + if !offenders.is_empty() { + let list = offenders + .iter() + .map(|p| p.strip_prefix(&crate_root).unwrap_or(p).display().to_string()) + .collect::>() + .join("\n - "); + panic!( + "Backend must not import PBS modules (frontends::pbs). Offending files:\n - {}", + list + ); + } +} diff --git a/docs/phase-03-frontend-api.md b/docs/phase-03-frontend-api.md new file mode 100644 index 00000000..3491eb6b --- /dev/null +++ b/docs/phase-03-frontend-api.md @@ -0,0 +1,19 @@ +### Phase 03 — Frontend API Boundary (Canon Contract) + +This document codifies the FE/BE boundary invariants for Phase 03. + +- BE is the source of truth. The `frontend-api` crate defines canonical models that all Frontends must produce. +- No string protocols across layers. Strings are only for display/debug. No hidden prefixes like `svc:` or `@dep:`. +- No FE implementation imports from other FE implementations. +- No BE imports PBS modules (hard boundary). The Backend consumes only canonical data structures from `frontend-api`. +- Overload resolution is signature-based. Arity alone is not sufficient; use canonical signatures/keys. + +Implementation notes (PBS): + +- The PBS adapter must not synthesize ownership or module info from string prefixes. All owner/module data should come from canonical types. +- Export/import surfaces are expressed exclusively via `frontend-api` types (e.g., `ItemName`, `ProjectAlias`, `ModulePath`, `ImportRef`, `ExportItem`). + +Enforcement: + +- A test in `prometeu-compiler` scans `src/backend/**` to ensure no references to `frontends::pbs` are introduced. +- Code review should reject any PRs that reintroduce prefix-based heuristics or FE-to-FE coupling. diff --git a/test-cartridges/canonical/golden/program.pbc b/test-cartridges/canonical/golden/program.pbc index 3646ac8573f5be88286c9c5f6abe6e09b079a715..5a70490d7e7f3a43ff64e865774031b80c27af1b 100644 GIT binary patch delta 25 dcmey$@|9(SAJgP$CMjM9AYcXJw4%h^Q~+Fo1{weW delta 21 ccmey$@|9(S9}_1l0|P@^QDScDWG^N;07?P|2><{9