338 lines
7.4 KiB
Markdown
338 lines
7.4 KiB
Markdown
## PR-09 — Add `prometeu.json` manifest parser + schema validation
|
|
|
|
**Why:** Dependency resolution cannot exist without a stable project manifest.
|
|
|
|
### Scope
|
|
|
|
* Implement `prometeu_compiler::manifest` module:
|
|
|
|
* `Manifest` struct mirroring the spec fields:
|
|
|
|
* `name`, `version`, `kind`
|
|
* `dependencies: HashMap<Alias, DependencySpec>`
|
|
* Support `DependencySpec` variants:
|
|
|
|
* `path`
|
|
* `git` (+ optional `version`)
|
|
* Validate:
|
|
|
|
* required fields present
|
|
* dependency entry must specify exactly one source (`path` or `git`)
|
|
* dependency aliases must be unique
|
|
* basic name rules (non-empty, no whitespace)
|
|
|
|
### Deliverables
|
|
|
|
* `load_manifest(project_root) -> Result<Manifest, ManifestError>`
|
|
* Diagnostic errors with file path + JSON pointer (or best-effort context)
|
|
|
|
### Tests
|
|
|
|
* parse minimal manifest
|
|
* missing name/version errors
|
|
* invalid dependency shape errors
|
|
|
|
### Acceptance
|
|
|
|
* Compiler can reliably load + validate `prometeu.json`.
|
|
|
|
---
|
|
|
|
## PR-10 — Dependency Resolver v0: build a resolved project graph
|
|
|
|
**Why:** We need a deterministic **module graph** from manifest(s) before compiling.
|
|
|
|
### Scope
|
|
|
|
* Implement `prometeu_compiler::deps::resolver`:
|
|
|
|
* Input: root project dir
|
|
* Output: `ResolvedGraph`
|
|
* Graph nodes:
|
|
|
|
* project identity: `{name, version}`
|
|
* local alias name (the key used by the parent)
|
|
* root path in filesystem (after fetch/resolve)
|
|
* manifest loaded for each node
|
|
* Resolution rules (v0):
|
|
|
|
* DFS/stack walk from root
|
|
* cycle detection
|
|
* collision handling:
|
|
|
|
* If the same (project name) appears with incompatible versions, error
|
|
* aliasing:
|
|
|
|
* alias is local to the edge, but graph also stores the underlying project identity
|
|
|
|
### Deliverables
|
|
|
|
* `resolve_graph(root_dir) -> Result<ResolvedGraph, ResolveError>`
|
|
* `ResolveError` variants:
|
|
|
|
* cycle detected (show chain)
|
|
* missing dependency (path not found / git not fetchable)
|
|
* version conflict (same project name, incompatible constraints)
|
|
* name collision (two distinct projects claiming same name)
|
|
|
|
### Tests
|
|
|
|
* simple root -> dep path graph
|
|
* cycle detection
|
|
* alias rename does not change project identity
|
|
|
|
### Acceptance
|
|
|
|
* Compiler can produce a stable, deterministic dependency graph.
|
|
|
|
---
|
|
|
|
## PR-11 — Dependency Fetching v0: local cache layout + git/path fetch
|
|
|
|
**Why:** Graph resolution needs a concrete directory for each dependency.
|
|
|
|
### Scope
|
|
|
|
* Implement `prometeu_compiler::deps::fetch`:
|
|
|
|
* `fetch_path(dep, base_dir) -> ProjectDir`
|
|
* `fetch_git(dep, cache_dir) -> ProjectDir`
|
|
* Define a cache layout:
|
|
|
|
* `~/.prometeu/cache/git/<hash>/...` (or configurable)
|
|
* the dependency is *materialized* as a directory containing `prometeu.json`
|
|
* For git deps (v0):
|
|
|
|
* accept `git` URL + optional `version`
|
|
* support `version: "latest"` as default
|
|
* implementation can pin to HEAD for now (but must expose in diagnostics)
|
|
|
|
### Deliverables
|
|
|
|
* Config option: `PROMETEU_CACHE_DIR` override
|
|
* Errors:
|
|
|
|
* clone failed
|
|
* missing manifest in fetched project
|
|
|
|
### Tests
|
|
|
|
* path fetch resolves relative paths
|
|
* cache path generation deterministic
|
|
|
|
### Acceptance
|
|
|
|
* Resolver can rely on fetcher to produce directories.
|
|
|
|
---
|
|
|
|
## PR-12 — Module Discovery v0: find PBS sources per project
|
|
|
|
**Why:** Once deps are resolved, the compiler must discover compilation units.
|
|
|
|
### Scope
|
|
|
|
* Define a convention (v0):
|
|
|
|
* `src/**/*.pbs` are source files
|
|
* `src/main.pbs` for `kind=app` (entry)
|
|
* Implement `prometeu_compiler::sources::discover(project_dir)`:
|
|
|
|
* returns ordered list of source files
|
|
* Enforce:
|
|
|
|
* `kind=app` must have `src/main.pbs`
|
|
* `kind=lib` must not require `main`
|
|
|
|
### Deliverables
|
|
|
|
* `ProjectSources { main: Option<Path>, files: Vec<Path> }`
|
|
|
|
### Tests
|
|
|
|
* app requires main
|
|
* lib without main accepted
|
|
|
|
### Acceptance
|
|
|
|
* Compiler can list sources for every node in the graph.
|
|
|
|
---
|
|
|
|
## PR-13 — Build Plan v0: deterministic compilation order
|
|
|
|
**Why:** We need a stable pipeline: compile deps first, then root.
|
|
|
|
### Scope
|
|
|
|
* Implement `prometeu_compiler::build::plan`:
|
|
|
|
* Input: `ResolvedGraph`
|
|
* Output: topologically sorted build steps
|
|
* Each step contains:
|
|
|
|
* project identity
|
|
* project dir
|
|
* sources list
|
|
* dependency edge map (alias -> resolved project)
|
|
|
|
### Deliverables
|
|
|
|
* `BuildPlan { steps: Vec<BuildStep> }`
|
|
|
|
### Tests
|
|
|
|
* topo ordering stable across runs
|
|
|
|
### Acceptance
|
|
|
|
* BuildPlan is deterministic and includes all info needed to compile.
|
|
|
|
---
|
|
|
|
## PR-14 — Compiler Output Format v0: emit per-project object module (intermediate)
|
|
|
|
**Why:** Linking needs an intermediate representation (IR/object) per project.
|
|
|
|
### Scope
|
|
|
|
* Define `CompiledModule` (compiler output) containing:
|
|
|
|
* `module_name` (project name)
|
|
* `exports` (functions/symbols)
|
|
* `imports` (symbol refs by (dep-alias, symbol))
|
|
* `const_pool` fragment
|
|
* `code` fragment
|
|
* `function_metas` fragment
|
|
* This is **not** the final VM blob.
|
|
|
|
### Deliverables
|
|
|
|
* `compile_project(step) -> Result<CompiledModule, CompileError>`
|
|
|
|
### Tests
|
|
|
|
* compile root-only project to `CompiledModule`
|
|
|
|
### Acceptance
|
|
|
|
* Compiler can produce a linkable unit per project.
|
|
|
|
---
|
|
|
|
## PR-15 — Link Orchestration v0 inside `prometeu_compiler`
|
|
|
|
**Why:** The compiler must produce the final closed-world blob.
|
|
|
|
### Scope
|
|
|
|
* Move “link pipeline” responsibility to `prometeu_compiler`:
|
|
|
|
* Input: `Vec<CompiledModule>` in build order
|
|
* Output: `ProgramImage` (single bytecode blob)
|
|
* Define linker responsibilities (v0):
|
|
|
|
* resolve imports to exports across modules
|
|
* assign final `FunctionTable` indices
|
|
* patch CALL targets to `func_id`
|
|
* merge const pools deterministically
|
|
* emit the final PBS v0 module image
|
|
|
|
### Deliverables
|
|
|
|
* `link(modules) -> Result<ProgramImage, LinkError>`
|
|
* `LinkError`:
|
|
|
|
* unresolved import
|
|
* duplicate export
|
|
* incompatible symbol signatures (if available)
|
|
|
|
### Tests
|
|
|
|
* `archive-pbs/test01` becomes an integration test:
|
|
|
|
* root depends on a lib
|
|
* root calls into lib
|
|
* output blob runs in VM
|
|
|
|
### Acceptance
|
|
|
|
* Compiler emits a single executable blob; VM only loads it.
|
|
|
|
---
|
|
|
|
## PR-16 — VM Boundary Cleanup: remove linker behavior from runtime
|
|
|
|
**Why:** Runtime should be dumb: no dependency resolution, no linking.
|
|
|
|
### Scope
|
|
|
|
* Audit `prometeu_core` + `prometeu_bytecode`:
|
|
|
|
* VM loads PBS v0 module
|
|
* VM verifies (optional) and executes
|
|
* Remove/disable any linker-like logic in runtime:
|
|
|
|
* no search for func idx by address beyond function table
|
|
* no module graph assumptions
|
|
|
|
### Deliverables
|
|
|
|
* VM init uses:
|
|
|
|
* `BytecodeLoader::load()` => `(code, const_pool, functions)`
|
|
* verifier as a gate
|
|
|
|
### Tests
|
|
|
|
* runtime loads compiler-produced blob
|
|
|
|
### Acceptance
|
|
|
|
* Linking is fully compiler-owned.
|
|
|
|
---
|
|
|
|
## PR-17 — Diagnostics UX: show dependency graph + resolution trace
|
|
|
|
**Why:** When deps fail, we need actionable feedback.
|
|
|
|
### Scope
|
|
|
|
* Add CLI output (or compiler API output) showing:
|
|
|
|
* resolved graph
|
|
* alias mapping
|
|
* where a conflict occurred
|
|
* Add `--explain-deps` mode (or equivalent)
|
|
|
|
### Deliverables
|
|
|
|
* human-readable resolution trace
|
|
|
|
### Tests
|
|
|
|
* snapshot tests for error messages (best-effort)
|
|
|
|
### Acceptance
|
|
|
|
* Users can debug dependency issues without guessing.
|
|
|
|
---
|
|
|
|
## Suggested execution order
|
|
|
|
1. PR-09 → PR-10 → PR-11
|
|
2. PR-12 → PR-13
|
|
3. PR-14 → PR-15
|
|
4. PR-16 → PR-17
|
|
|
|
---
|
|
|
|
## Notes for Junie
|
|
|
|
* Keep all “v0” decisions simple and deterministic.
|
|
* Favor explicit errors over silent fallback.
|
|
* Treat `archive-pbs/test01` as the north-star integration scenario.
|
|
* No background tasks: every PR must include tests proving the behavior.
|