-
Notifications
You must be signed in to change notification settings - Fork 2
docs(architecture): requirements for the unified CLI engine #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
a5079b5
docs(architecture): requirements for the unified CLI engine
wmadden-electric 220807b
docs(architecture): rule the tree (shell-defined) and ban package-man…
wmadden-electric ced1388
docs(architecture): R5 clarifications — framework renderers are legal…
wmadden-electric 7247cfb
docs(architecture): the engine wraps @stricli/core
wmadden-electric f7ea6e8
docs(architecture): R14 — engine-defined event vocabulary with produc…
wmadden-electric 4851431
drive(prisma-cli-v8): commit the project workspace — spec, design rec…
wmadden-electric 04809e8
drive(prisma-cli-v8): project plan — platform, then Composer, then ORM
wmadden-electric 03f8703
drive(prisma-cli-v8): S1 slice contract — engine package + auth whoam…
wmadden-electric 423cca6
drive(prisma-cli-v8): S1 dispatch plan — six sequential dispatches
wmadden-electric 6c00a6b
drive(prisma-cli-v8): strip review artifacts and superseded interface…
wmadden-electric 5e3da1f
docs(architecture): scope R4's prohibition and define the output surface
wmadden-electric e8c99af
docs(architecture): clarify R9 forbids discovery, not startup instant…
wmadden-electric 911f452
docs(architecture): R10 covers config load and evaluation failures
wmadden-electric 7c9b183
docs(architecture): state the R10 version-marker contract exactly
wmadden-electric 0c34b78
docs(architecture): make the friction-points reference followable
wmadden-electric 1899416
docs(architecture): record evaluated framework versions in the decision
wmadden-electric a920cc0
docs(plan): tag the dependency-graph fence as text
wmadden-electric 22877f7
chore: exclude .drive design artifacts from biome
wmadden-electric File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
39 changes: 39 additions & 0 deletions
39
.drive/projects/prisma-cli-v8/assets/briefs/1b-leftovers-prisma-prisma.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Brief: prisma/prisma config-contract repairs and ControlClient test double | ||
|
|
||
| Repo: prisma/prisma (main). Three independent deliverables; land as separate PRs or one PR with separate commits. Operator: Will Madden. Process: verify every claim below against current code before changing it; if you hit a judgment call this brief doesn't settle, stop and report it as a numbered question with options and a recommendation — do not decide it yourself. | ||
|
|
||
| ## Context | ||
|
|
||
| These are the remaining config/contract items from the CLI-consolidation work. The governing rules are in-repo: ADR 239 (structural error envelopes, dotted codes), ADR 245 (errors structured at origin, no catch-all codes; one `ok` discriminator on results), and `docs/CLI Style Guide.md` (exit codes). The error-code registry is `docs/reference/error-reference.md`, enforced by `pnpm run check:error-reference` — any new code or new producing site is added there in the same change. | ||
|
|
||
| ## Deliverable 1: config loading returns diagnostics instead of throwing | ||
|
|
||
| Today `loadConfig` (`packages/1-framework/3-tooling/config-loader/src/load.ts`, validation in `packages/1-framework/1-core/config/`) throws `CONFIG.VALIDATION_FAILED` / `CONFIG.EVALUATION_FAILED`-shaped errors on the first problem. The target semantics: | ||
|
|
||
| - Evaluating a config module never takes down the command wholesale. Loading returns the evaluated config **plus a diagnostics list** (each diagnostic a `CliErrorEnvelope`-shaped structured error with a `meta.section` identifying the config section it concerns). | ||
| - A command that needs section X fails (exit 2, rendering that diagnostic) only if section X has a diagnostic; commands not touching X proceed. | ||
| - A config file that cannot be evaluated at all (module threw, unparseable) yields a single evaluation diagnostic attached to no section; every command then fails early with it. | ||
| - Existing error codes are reused; genuinely new conditions get new registered codes. No behavior change to what users *see* for currently-failing configs beyond message framing — pin representative `--json` envelopes before and after. | ||
|
|
||
| Design the exact return type first (the repo convention is the shared `Result` from `@internal/utils/result`, but a config-with-diagnostics is not a failure — a `{ config, diagnostics }` value inside `Ok` is the expected shape) and validate it against every `loadConfig` call site before writing code. | ||
|
|
||
| ## Deliverable 2: versioned `defineConfig` marker | ||
|
|
||
| `defineConfig` (`packages/1-framework/1-core/config/src/config-types.ts`) stamps the object it returns with a config-format version marker (non-enumerable; survives spreads is NOT required — document that configs must return the `defineConfig` result directly). The loader then enforces: | ||
|
|
||
| - Marker present and current → proceed. | ||
| - Evaluation succeeded but no marker (a plain object export, or a config produced by a different `defineConfig` — i.e. a classic Prisma 7 file once the unified filename lands) → **fail early** with a new registered code (suggested: `CONFIG.UNVERSIONED_CONFIG`) whose fix text names `defineConfig` and links the migration path. This ruling is settled: fail early; no best-effort reading of unmarked configs. | ||
|
|
||
| The marker's purpose is downstream: the future unified host loader will claim `prisma.config.ts`, a filename Prisma 7 already uses, and must distinguish the two by marker rather than misparse. Build the marker and enforcement here; do not build any Prisma-7-filename discovery in this repo. | ||
|
|
||
| ## Deliverable 3: published fixture-backed `ControlClient` test double | ||
|
|
||
| Hosts and product tests need to drive the CLI's control-api surface without a real database. Export a fixture-backed double of the control client (`packages/1-framework/3-tooling/cli/src/control-api/client.ts`) from a **published** entrypoint (decide placement against how `@prisma/orm-toolchain` composes its published surface; the double must not drag the real driver/database imports into consumers). It covers every seam operation the control API exposes, returns the shared `Result` shapes with realistic fixture payloads, and its per-operation fixtures are overridable per test. Add a conformance-style test asserting the double's surface stays in sync with the real client (compile-time: same operation names and signatures). | ||
|
|
||
| ## Verification (all must pass before pushing) | ||
|
|
||
| `pnpm turbo build --filter=@internal/cli...`; full test + typecheck + lint in config-loader, config, cli packages; `test/integration` typecheck; `pnpm run check:error-reference` with zero failures; `pnpm lint:deps`. | ||
|
|
||
| ## Commit discipline | ||
|
|
||
| Explicit staging only. `git commit -s --trailer "Signed-off-by: Will Madden <madden@prisma.io>"`, body ends with `Co-Authored-By: <your model attribution>`. Push via the `bot` remote, never origin. Verify the PR is open before any push to an existing PR branch. | ||
38 changes: 38 additions & 0 deletions
38
.drive/projects/prisma-cli-v8/assets/briefs/1c-leftovers-composer.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Brief: composer config-contract compliance and control-API test double | ||
|
|
||
| Repo: prisma/composer (main). Three deliverables. Operator: Will Madden. Process: verify every claim against current code first; stop and report numbered questions with options and a recommendation on anything this brief doesn't settle. | ||
|
|
||
| ## Context | ||
|
|
||
| Composer's error/result rules are recorded in its ADR-0043 and ADR-0044 (`docs/design/90-decisions/`): structured errors at origin with dotted codes from the closed registry, one `ok` discriminator, exit 1 = bug only. The registry in ADR-0044 is closed — a new subcode is an edit to that list in the same change. Constraint that must not move: the effect constellation stays pinned at `4.0.0-beta.103` via the consumer overrides block (alchemy is broken on effect >= beta.104; see `skills-contrib/upgrade-alchemy-effect/SKILL.md`). | ||
|
|
||
| ## Deliverable 1: config validation returns diagnostics instead of throwing | ||
|
|
||
| Today `load-config.ts` / `validate-coverage.ts` throw on the first invalid field. Target semantics (the config contract all products will share): | ||
|
|
||
| - Loading a config returns the evaluated value **plus a diagnostics list** (structured errors, each tagged with the config section/field it concerns via `meta`), instead of throwing per field. | ||
| - Commands fail (exit 2, rendering the diagnostic) only when a section they need is invalid. | ||
| - A config module that cannot be evaluated at all yields one evaluation diagnostic (`CONFIG.EVALUATION_FAILED` already exists) and every command fails early with it. | ||
| - No import-time side effects and no throwing from `defineConfig`-equivalent factories: constructing a config value never throws; problems surface as diagnostics at load time. | ||
| - Pin representative rendered/`--json` output before and after — user-visible behavior for currently-failing configs may only change in framing. | ||
|
|
||
| ## Deliverable 2: effect-resolution preflight becomes a diagnostic | ||
|
|
||
| `check-effect-resolution.ts` currently detects a mismatched `effect` in the consumer's tree by throwing during import, which takes out every command — including ones that never touch the deploy executor. Target: | ||
|
|
||
| - The preflight runs at config-load/command-dispatch time, not import time, and surfaces as a structured diagnostic (`DEPS.EFFECT_VERSION_CONFLICT`, already registered) carried in the diagnostics list from Deliverable 1. | ||
| - Commands that need the executor fail early rendering it; commands that don't (e.g. help, config inspection) still work. | ||
| - The lazy executor-load failure path (`DEPS.EXECUTOR_UNLOADABLE`) is unchanged — it remains the backstop when the preflight didn't fire. | ||
|
wmadden-electric marked this conversation as resolved.
|
||
| - The effect-CI probe and the `npm install effect dedupe` check must still pass; do not weaken either. | ||
|
|
||
| ## Deliverable 3: published test double for the control API | ||
|
|
||
| Hosts driving `@prisma/composer/control` (deploy/destroy/dev/log) need a double that never spawns alchemy or containers. Export a fixture-backed double from a published entrypoint (placement judged against the existing `./control` shim in `packages/9-public/composer`): same operation signatures, same `Result<…, CliStructuredError>` shapes, per-operation fixtures overridable per test, including a `DevSession` double whose lifecycle methods behave. Add a compile-time conformance check that the double's surface matches the real operations. | ||
|
|
||
| ## Verification (all must pass before pushing) | ||
|
|
||
| `pnpm build`, `pnpm typecheck`, `pnpm lint`, `pnpm lint:casts` (delta 0), `pnpm lint:deps` (all sub-checks), `@internal/cli` and integration test suites, `pnpm run check:npm-effect-resolution`. Known pre-existing failures that are not yours to fix: the `@internal/local-target` timeout pair. | ||
|
|
||
| ## Commit discipline | ||
|
|
||
| Explicit staging only. `git commit -s --trailer "Signed-off-by: Will Madden <madden@prisma.io>"`, body ends with `Co-Authored-By: <your model attribution>`. Composer's `origin` in the operator's clones is the bot SSH alias; verify the target PR is open before pushing to an existing PR branch. | ||
60 changes: 60 additions & 0 deletions
60
.drive/projects/prisma-cli-v8/assets/engine/daemon-library-notes.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Daemon library — design conclusions, parked | ||
|
|
||
| Status: **excluded from the CLI-engine scope** (Will, 2026-08-09) — it is a | ||
| runtime dependency of product control clients, orthogonal to the engine. | ||
| These notes preserve what the design conversation concluded so the work is | ||
| picked up, not re-derived. Evidence citations: `output-modes-survey.md` | ||
| (emulators/daemons section). | ||
|
|
||
| ## The finding that shaped the engine | ||
|
|
||
| "Daemon mode" needs **zero engine surface**. Commands touching daemons are | ||
| ordinary commands: `ls` is a result command presenting a table over | ||
| `scan()`; `stop` presents a result over `stop()`; `composer dev` calls | ||
| `ensure()` during startup then runs as a normal session command. The | ||
| daemon-ness lives in what handlers do (operations layer), like spawning | ||
| alchemy already does. | ||
|
|
||
| ## What the library is | ||
|
|
||
| The lifecycle-and-discovery primitives that Composer's | ||
| `dev-emulators/src/daemon.ts` and `@prisma/dev`'s state layer each | ||
| hand-built (convergent evolution — the evidence they're one concept): | ||
|
|
||
| - **ensure(name, entry, opts)** — idempotent start: read registry entry, | ||
| probe health (identity/version-matched), adopt a healthy same-version | ||
| daemon, terminate-and-replace a stale-version one, spawn detached+unref | ||
| when absent, record `{pid, port, version, logPath}`, await health — all | ||
| serialized under a lockfile so concurrent CLI invocations can't race. | ||
| - **stop(name)** — SIGTERM, grace, SIGKILL, remove entry. | ||
| - **scan() / status(name)** — registry entries probed to | ||
| running/starting/dead. | ||
| - **logs(name)** — per-daemon stdio log file. | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| - Daemon-side: an entry-script harness (bind localhost port, serve | ||
| /health + the product's admin API, SIGTERM cleanup). | ||
|
|
||
| Each daemon's **admin API stays product-owned**; the library owns only | ||
| lifecycle and discovery. Registry entries need a product-data extension | ||
| slot (same shape of reasoning as the engine's R14). | ||
|
|
||
| ## Open questions when picked up | ||
|
|
||
| 1. **Unified machine-wide registry vs per-product registries + an | ||
| aggregating command.** Unified (one `ls` shows Composer emulators and | ||
| dev servers; one stop semantics; the second liveness implementation | ||
| stops existing) costs a real `@prisma/dev` internal migration | ||
| (`server.json` format, its `proper-lockfile` usage) including | ||
| old-format servers; per-product costs nothing now but keeps two | ||
| liveness protocols forever and adds one per future daemon. | ||
| 2. **The package's home.** | ||
| 3. The management-command surface the grammar parked (`emulator` | ||
| root: ls/stop/status) — the gap that today lets Composer leave | ||
| daemons on the machine with no user-facing way to list or stop them | ||
| (`stopDaemon` is "not called by any v1 command"). | ||
|
|
||
| ## Effect on @prisma/dev (under unification) | ||
|
|
||
| Public API (`startPrismaDevServer`, scan/status surface) unchanged; | ||
| internals swap to the shared library; its domain fields (ports, exports) | ||
| ride the registry's extension slot; migration must handle servers created | ||
| under the old on-disk format. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.