This commit is contained in:
bQUARKz 2026-02-10 21:06:56 +00:00
parent a115281d88
commit 1135514508
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
7 changed files with 74 additions and 10 deletions

View File

@ -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::<Vec<_>>());
assert!(found, "Expected an export with canonical fn key name=debug but not found. Exports: {:?}", compiled.exports.keys().collect::<Vec<_>>());
}
}

View File

@ -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) {

View File

@ -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:<ServiceName>"
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);
}

View File

@ -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;

View File

@ -0,0 +1,46 @@
use std::fs;
use std::path::{Path, PathBuf};
fn collect_rs_files(dir: &Path, out: &mut Vec<PathBuf>) {
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::<Vec<_>>()
.join("\n - ");
panic!(
"Backend must not import PBS modules (frontends::pbs). Offending files:\n - {}",
list
);
}
}

View File

@ -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.