11 KiB
Phase 03 – Rigid Frontend API & PBS Leak Containment (Junie PR Templates)
Goal: finish Phase 03 with JVM-like discipline by making the Backend (BE) the source of truth and forcing the PBS Frontend (FE) to implement a strict, minimal, canonical contract (
frontend-api).Strategy: surgical PRs that (1) stop PBS types from leaking, (2) replace stringy protocols with canonical models, and (3) make imports/exports/overloads deterministic across deps.
PR-03.01 — Introduce frontend-api crate (canonical models + strict trait)
Title
Create frontend-api crate with canonical models and strict Frontend trait
Briefing / Context
Right now, compiler layers import PBS-specific symbols/types and depend on “string protocols” (e.g., "alias/module", "@alias:module", svc: prefixes). This caused Phase 03 instability and the current golden failure (E_OVERLOAD_NOT_FOUND for imported service methods). We need a single source of truth contract owned by BE.
Target (What “done” means)
-
A new crate (or module)
crates/frontend-apiexporting:- Canonical identifiers and references used by BE for imports/exports.
- A strict
Frontendtrait that returns only BE-required artifacts.
-
No PBS types inside this crate.
Scope
-
Add
frontend-apicrate. -
Define canonical types:
ProjectRef { alias: String }(orProjectAliasnewtype)ModulePathnewtype (normalized"input/testing")ItemNamenewtype (e.g.,"Test","Log")ImportRef { project: ProjectRef, module: ModulePath, item: ItemName }ExportRef/ExportItem(see PR-03.05)CanonicalFnKey(see PR-03.04)
-
Define strict
Frontendtrait (draft; implemented later):parse_and_analyze(...) -> FrontendUnitFrontendUnit { diagnostics, imports, exports, lowered_ir }
-
Include explicit “no strings-as-protocol” policy in doc comments.
Out of scope
- Implementing PBS FE.
- Refactoring build pipeline.
Checklist
- Add crate and wire to workspace.
- Add canonical types with clear invariants.
- Add
Frontendtrait and minimalFrontendUnitoutput. - Add unit tests for parsing/normalization helpers (module path normalization rules).
Tests
cargo test -p frontend-api
Risk
Low. New crate only; no behavior changes yet.
PR-03.02 — Ban PBS leakage at the BE boundary (dependency & import hygiene)
Title
Remove PBS imports from BE layers and enforce frontend-api boundary
Briefing / Context
BE code currently imports PBS modules (symbols, typed builder, etc.) from prometeu-compiler. This is the leak that makes the system unmaintainable and creates accidental coupling. We must ensure BE only depends on frontend-api outputs.
Target
- BE layers (
building/*,sources.rs, orchestrator/linker paths) must not import PBS modules. - Any FE-specific logic is moved behind the
Frontendimplementation.
Scope
-
Replace
use crate::frontends::pbs::*imports in BE files withfrontend-apitypes. -
Add a simple compile-time guard:
- Option A: a
deny/lint viamodseparation + no re-exports. - Option B: create
crates/prometeu-compiler-backendmodule that does not depend onpbsmodule.
- Option A: a
-
Identify and remove PBS-specific helper calls inside BE (e.g.,
build_typed_module_symbolsfrom BE).
Out of scope
- Fixing overload resolution itself (handled in later PRs).
Checklist
- Update imports in BE files.
- Remove PBS type references from BE data structures.
- Ensure build compiles without BE → PBS direct dependency.
- Add a “boundary test”: a module that
uses backend and fails to compile if PBS is required (or a CI check script).
Tests
cargo test -p prometeu-compilercargo test --workspace
Risk
Medium. Refactor touches build/orchestrator wiring.
PR-03.03 — Canonical import syntax → ImportRef (no dual styles)
Title
Define single canonical import model and parse PBS imports into ImportRef
Briefing / Context
We currently support multiple synthetic import path styles ("alias/module" and "@alias:module"). This amplifies ambiguity and is a root cause of mismatch in imported service method overloads.
We want one canonical representation:
- PBS syntax:
import { Test } from "@sdk:input/testing" - Canonical model:
ImportRef { project: "sdk", module: "input/testing", item: "Test" }
Target
- PBS FE produces a list of canonical
ImportRef. - BE consumes only
ImportRef. - Remove support for dual synthetic path style in the BE pipeline.
Scope
-
In PBS FE:
- Parse
@<alias>:<module_path>intoImportRef. - Validate module path normalization.
- Validate that
itemis a single symbol name (service/struct/host/contract/etc).
- Parse
-
In BE:
- Replace “synthetic path generation” with canonical module lookup using
(alias, module_path).
- Replace “synthetic path generation” with canonical module lookup using
Out of scope
- Export naming canonicalization (PR-03.04/03.05).
Checklist
- Implement import parser →
ImportRef. - Remove
alias/modulesynthetic path support. - Update resolver/module-provider lookup to accept
(alias, module_path). - Add diagnostics for invalid import string.
Tests
-
Unit tests in PBS FE for:
- valid:
"@sdk:input/testing" - invalid forms
- normalization edge cases (leading
/,./,\\on Windows paths)
- valid:
-
Integration test (golden-style) compiling a small project importing a service.
Risk
Medium. Changes import resolution plumbing.
PR-03.04 — Canonical function identity: CanonicalFnKey (JVM-like)
Title
Introduce canonical function identity for exports/import calls (no string prefix matching)
Briefing / Context
Phase 03 currently tries to match overloads using name#sigN strings + prefix logic + origin checks. This breaks easily and is exactly what produced E_OVERLOAD_NOT_FOUND for Log.debug.
We need a canonical function key that is not “string protocol”:
-
CanonicalFnKey { owner: Option<ItemName>, name: ItemName, sig: SigId }- Free fn:
owner=None, name=foo, sig=... - Service method:
owner=Some(Log), name=debug, sig=...
- Free fn:
Target
- BE uses
CanonicalFnKeyfor export surface and import relocation. - FE supplies
owner/nameand produces/requests signatures deterministically.
Scope
-
Add
CanonicalFnKeytofrontend-api. -
Update VM import call instruction payload to carry canonical pieces:
ImportCall { dep_alias, module_path, fn_key: CanonicalFnKey, arg_count }- (or equivalent)
-
Eliminate string matching / prefix matching for overload selection.
Checklist
- Define
CanonicalFnKeyand helpers. - Update IR / bytecode instruction structures if needed.
- Update lowering call sites.
- Ensure debug info keeps readable names (owner.name).
Tests
- Unit: canonical formatting for debug name
Log.debug. - Integration: two overloads of
Log.debugacross deps resolved by exact signature.
Risk
High-ish. Touches instruction encoding and matching logic.
PR-03.05 — Canonical export surface: ExportItem (no svc: / no name#sig strings)
Title
Replace stringy export naming with canonical ExportItem model
Briefing / Context
Exports are currently keyed by (module_path, symbol_name string, kind) where symbol_name embeds #sig and/or owner names. This is fragile and couples FE naming to BE behavior.
Target
-
BE export map keys are canonical:
ExportItem::Type { name }ExportItem::Service { name }ExportItem::Function { fn_key: CanonicalFnKey }
-
Export surface remains stable even if we later change display formatting.
Scope
- Update compiled module export structures.
- Update dependency symbol synthesis to use canonical export items.
- Update linker relocation labels to reference canonical export items.
Checklist
- Introduce
ExportItemand migrate ExportKey. - Update dependency export synthesis.
- Update linker/import label format (if used) to canonical encoding.
- Ensure backward compatibility is explicitly NOT required for Phase 03.
Tests
- Unit: exporting a service method yields
ExportItem::Function { owner=Log, name=debug, sig=... }. - Integration: build root + dep, link, run golden.
Risk
High. Touches serialization and linking labels.
PR-03.06 — Deterministic overload resolution across deps (arity is not enough)
Title
Implement deterministic overload selection using canonical signature matching
Briefing / Context
We currently try to disambiguate overloads by arity as a fallback. That’s not sufficient (same arity, different types). For Phase 03 “professional grade”, overload resolution must be deterministic and match by full signature.
Target
-
Imported method call selects overload by:
- resolve callee symbol → candidate set
- typecheck args → determine expected param types
- choose exact match
- otherwise
E_OVERLOAD_NOT_FOUNDorE_OVERLOAD_AMBIGUOUSdeterministically
Scope
- PBS FE typechecker must provide enough info to compute signature selection.
- Resolver must expose all overload candidates for an imported
ImportRefitem. - Lowering uses canonical fn key and selected
SigId.
Checklist
- Ensure imported service methods are actually present in imported symbol arena.
- Ensure candidates include
(owner, name, sig)not justname. - Implement exact-match algorithm.
- Implement deterministic ambiguity ordering for diagnostics.
Tests
-
Add golden regression reproducing
Log.debugfailure:- dep exports
service Log { debug(string) } - root imports
Logand callsLog.debug("x")
- dep exports
-
Add tests for:
- ambiguous same signature
- not found
Risk
Medium/High. Needs clean integration across resolver/typechecker/lowering.
PR-03.07 — Phase 03 cleanup: remove legacy compatibility branches and document boundary
Title
Remove legacy string protocol branches and document FE/BE boundary rules
Briefing / Context
After canonical models are in place, we must delete compatibility code paths (alias/module, svc: prefixes, prefix matching, etc.) to prevent regressions.
Target
- No legacy synthetic module path support.
- No string prefix matching for overloads.
- Documentation: “BE owns the contract; FE implements it.”
Scope
- Delete dead code.
- Add
docs/phase-03-frontend-api.md(or in-crate docs) summarizing invariants. - Add CI/lints to prevent BE from importing PBS modules.
Checklist
- Remove legacy branches.
- Add boundary docs.
- Add lint/CI guard.
Tests
- Full workspace tests.
- Golden tests.
Risk
Low/Medium. Mostly deletion + docs, but could expose hidden dependencies.
Notes / Operating Rules (for Junie)
- BE is the source of truth:
frontend-apidefines canonical models; FE conforms. - No string protocols across layers. Strings may exist only as display/debug.
- No FE implementation imports from other FE implementations.
- No BE imports PBS modules (hard boundary).
- Overload resolution is signature-based (arity alone is not valid).