254 lines
7.7 KiB
Markdown
254 lines
7.7 KiB
Markdown
# 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.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>` into `ImportRef`.
|
||
* Validate module path normalization.
|
||
* Validate that `item` is a single symbol name (service/struct/host/contract/etc).
|
||
* In BE:
|
||
|
||
* Replace “synthetic path generation” with canonical module lookup using `(alias, module_path)`.
|
||
|
||
### Out of scope
|
||
|
||
* Export naming canonicalization (PR-03.04/03.05).
|
||
|
||
### Checklist
|
||
|
||
* [ ] Implement import parser → `ImportRef`.
|
||
* [ ] Remove `alias/module` synthetic 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)
|
||
* 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=...`
|
||
|
||
### Target
|
||
|
||
* BE uses `CanonicalFnKey` for export surface and import relocation.
|
||
* FE supplies `owner/name` and produces/requests signatures deterministically.
|
||
|
||
### Scope
|
||
|
||
* Add `CanonicalFnKey` to `frontend-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 `CanonicalFnKey` and 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.debug` across 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 `ExportItem` and 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:
|
||
|
||
1. resolve callee symbol → candidate set
|
||
2. typecheck args → determine expected param types
|
||
3. choose exact match
|
||
4. otherwise `E_OVERLOAD_NOT_FOUND` or `E_OVERLOAD_AMBIGUOUS` deterministically
|
||
|
||
### Scope
|
||
|
||
* PBS FE typechecker must provide enough info to compute signature selection.
|
||
* Resolver must expose all overload candidates for an imported `ImportRef` item.
|
||
* 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 just `name`.
|
||
* [ ] Implement exact-match algorithm.
|
||
* [ ] Implement deterministic ambiguity ordering for diagnostics.
|
||
|
||
### Tests
|
||
|
||
* Add golden regression reproducing `Log.debug` failure:
|
||
|
||
* dep exports `service Log { debug(string) }`
|
||
* root imports `Log` and calls `Log.debug("x")`
|
||
* 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)
|
||
|
||
1. **BE is the source of truth**: `frontend-api` defines canonical models; FE conforms.
|
||
2. **No string protocols** across layers. Strings may exist only as *display/debug*.
|
||
3. **No FE implementation imports from other FE implementations**.
|
||
4. **No BE imports PBS modules** (hard boundary).
|
||
5. **Overload resolution is signature-based** (arity alone is not valid).
|