Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
41a0d7b
docs(design): ADR-0041 — local dev runs the deploy pipeline against l…
wmadden-electric Jul 22, 2026
102625d
docs(drive): exhaustive local-dev implementation spec + five-slice plan
wmadden-electric Jul 22, 2026
ef88a07
docs(design): record the three dev process lifetimes in local-dev.md
wmadden-electric Jul 22, 2026
f1bc071
docs(design): all backing services are machine-scoped emulator daemon…
wmadden-electric Jul 22, 2026
6f5e579
docs(design): one emulator per node kind; the Compute emulator owns s…
wmadden-electric Jul 22, 2026
10ae4b0
docs(drive): close every implementer-facing gap in the local-dev spec
wmadden-electric Jul 22, 2026
1db9540
feat(core): Bundle gains an optional watch field for the dev watch loop
wmadden-electric Jul 22, 2026
40ab238
feat(nextjs): populate Bundle.watch with the standalone output dir
wmadden-electric Jul 22, 2026
165fade
refactor(node): share directory-form assemble machinery, populate watch
wmadden-electric Jul 22, 2026
cc3911f
feat(dir): add the dir() build adapter, published as @prisma/composer…
wmadden-electric Jul 22, 2026
f0e2a44
test(dir): cover the dir() adapter's assemble path and authoring surface
wmadden-electric Jul 22, 2026
12ce0cc
docs(dir): document the dir() build adapter in the guide and the skill
wmadden-electric Jul 22, 2026
928f4a3
fix(node): drop an import rename that no-bare-cast misflags as a cast
wmadden-electric Jul 22, 2026
df7164b
docs(drive): fix the dir() return shape in the spec — dir is the work…
wmadden-electric Jul 22, 2026
64d67a0
docs(design): per-app bucket credential scoping, sanitized ORM diagno…
wmadden-electric Jul 22, 2026
365cb32
docs(drive): sync spec.md with the design branch tip
wmadden-electric Jul 22, 2026
6d45a63
fix(node): hard-error when dir itself is a symlink, not just its cont…
wmadden-electric Jul 22, 2026
8ea6f27
docs(drive): sync spec/plan/ADR-index to the design branch tip
wmadden-electric Jul 23, 2026
5837c0e
Revert "feat(dir): add the dir() build adapter, published as @prisma/…
wmadden-electric Jul 23, 2026
4b73ae0
fix(node): symlink-as-dir hard error + directory-form watch, fold ass…
wmadden-electric Jul 23, 2026
d3df738
docs(design): sync local-dev.md to the design tip (scoped env materia…
wmadden-electric Jul 23, 2026
2f3f2cf
docs(drive): reword a wrapped line that markdownlint reads as a malfo…
wmadden-electric Jul 23, 2026
185e156
Merge remote-tracking branch 'bot/main' into claude/local-dev-s2-dir-…
wmadden-electric Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .drive/deferred.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,11 @@ registry). What we deliberately didn't do:
ADR-0022 §Alternatives ("Deferred, not rejected"). Prerequisite spike before
pickup: confirm PN handles multiple peer app-authored spaces in one database
end-to-end (PN ADR 212's monorepo-aggregator case).
- **Dev-time story** — parked sketch: `prisma dev` serves identical local
copies of the management API; Alchemy treats the local machine as one more
deploy target, lowering unchanged.
- **Dev-time story** — resolved by ADR-0041: the "lowering unchanged" half of
the parked sketch survives, but substitution happens at the Alchemy provider
boundary (local providers for the same resource types), not by serving a
local copy of the Management API — see
`docs/design/90-decisions/ADR-0041-local-dev-runs-the-deploy-pipeline-against-local-providers.md`
and `docs/design/10-domains/local-dev.md`.
- **Factory name** — `pnPostgres` is a placeholder; Prisma Next → Prisma Data
rename incoming at GA. Rename the factory when the product name lands.
127 changes: 127 additions & 0 deletions .drive/projects/local-dev/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Project plan: local dev (`prisma-composer dev`)

**Spec:** `.drive/projects/local-dev/spec.md` (exhaustive — the contract).
Design: ADR-0041 + `docs/design/10-domains/local-dev.md` (committed).

Six slices, one PR each. S1 and S2 are independent and can run in parallel;
S3 needs S1; S4 needs S3; S5 needs S4; S6 needs S2 + S5.

## Validation gates

Per slice unless stated: `pnpm typecheck`, `pnpm test`, `pnpm lint`,
`pnpm lint:deps` at the workspace root, plus the touched packages' own
scripts. Implementer dispatches use Sonnet-4.6-mid, reviewers Opus-4.8-mid
(operator's standing rule). No PR opens with a failing or skipped check.

## Slices

### S1 — `@internal/s3-protocol` extraction + disk store

- **Outcome:** new lowering-layer package holding `store.ts`, `sigv4.ts`
(incl. `mintKeyPair`), `handler.ts`, `memory-store.ts` (moved) plus new
`fs-store.ts` (resolver-based, sidecar metadata, dropped-file adoption).
Pure protocol — no server/daemon. Storage module consumes it; public
surface byte-compatible; its tests pass unmodified.
`architecture.config.json` declares the package (spec § 1 — including the
plane check that both import directions pass `lint:deps` **first**; a
rejection is a stop condition).
- **Proves:** fs-store contract tests (sidecar lazily written for dropped
files, path-escape rejection, list pagination, temp-then-rename), handler
round-trip over fs-store via a real S3 client (`@aws-sdk/client-s3`
devDependency in tests only) incl. presigned GET/PUT.
- **Spec sections:** § 1, behavior contracts.

### S2 — `dir()` build adapter

- **Outcome:** `@prisma/composer/dir` authoring + assemble per spec § 7:
verbatim tree copy, named entry, symlink hard error, wrapper bundling
identical to `node()`'s. Also lands the `Bundle.watch` contract (spec
§ 3): the optional core field plus `watch` population in `node()`,
`nextjs()`, and `dir()`. Guide/docs entry.
- **Proves:** assemble tests (missing dir/entry errors verbatim, symlink
error, tree fidelity); a fixture app with a multi-file runnable deploys
through the full assemble path (no cloud needed — assemble-level test).
- **Spec sections:** § 7.

### S3 — `@internal/dev-emulators`: daemon layer + Compute & bucket emulators

- **Outcome:** the new package per spec § 2: `daemon.ts` (registry, stable
ports ≥ 4300, readiness, version-skew restart, ensure/stop),
`compute-main.ts` (service registry, per-(app,service) stable ports ≥
3000, deployment PUT with hash/env diffing, bun spawn, crash
backoff/held policy, log files + follow streams, app stop/delete),
`buckets-main.ts` (S3 wire over fs-store with registered per-bucket dirs,
`<app>--<name>` physical names, `/_pcdev/` admin, 501 multipart),
`client.ts` typed loopback clients.
- **Proves:** standalone daemon tests driving the APIs directly: ensure →
health → version-bump restart; deployment lifecycle (spawn, restart on
hash change only, backoff, held after 5 fast crashes, log follow);
multi-app isolation (two apps, same service and bucket names, no
collisions); bucket admin + SigV4 round-trip via the S3 client; daemon
survives its parent exiting.
- **Depends on:** S1.
- **Spec sections:** § 2.

### S4 — the dev target: core seam + local providers + extension `dev` field

- **Outcome:** `DevDescriptor` (+ `DevEmulatorsInput` / `DevAttachInput` /
`DevAttachment`, `DEV_DIR`) in core; `LowerOptions.dev` +
`mergedDevProviders`; `serviceAddress` threading
(`ComputeSerialized.address` → `DeploymentProps.serviceAddress`);
`@internal/lowering/dev` (dev-store, compute/postgres/bucket providers as
emulator clients, `devProviders()`, `artifact-extract.ts`,
`resolve-bin.ts`); target extension `src/dev/*` (container, preflight +
shared `preflight-names.ts`, emulators, attach, teardown) and
`prismaCloud()`'s `dev` field; the lazy `resolveOptions` restructure
(factory constructs with no env).
- **Proves:** integration test (no CLI): a fixture topology (compute +
postgres + bucket) lowered with `dev: true` and driven through
`alchemy deploy --stage dev` programmatically leaves the app SERVING —
emulator listings correct, env store correct (port override + poison rows
+ secret pointers), `prisma dev` instance running (including the spec's
pinned stop→start port-stability verification, run FIRST — its outcome
selects the pinned primary or fallback path), HTTP round-trip against
the deployed fixture service; a second converge with an unchanged build is
a full no-op (no restarts); a changed artifact restarts exactly one
service. Plus: scrubbed-env test (`prismaCloud()` with no `PRISMA_*`);
ustar extract round-trips `packageComputeArtifact`'s output; placeholder
minting stable across two preflight runs; env-param missing → listing
error.
- **Depends on:** S3.
- **Spec sections:** § 3, § 4, § 5, value-sourcing + determinism contracts.

### S5 — the `dev` command: pipeline, attach view, watch, error surface

- **Outcome:** `DevCommand` + `run-dev.ts` + shared `pipeline.ts` refactor of
`run()`; `generate-dev-stack.ts`; the attach rendering (front door,
merged prefixed logs); `watch.ts` (debounced rebuild → re-assemble →
re-converge; converge failure leaves the running app untouched);
`--fresh`; Ctrl-C = `stopServices()` + exit; every error string from the
spec verbatim.
- **Proves:** the spec's acceptance criteria 1–6 on `examples/store`,
scripted as an integration test where feasible (bring-up, single-service
restart on rebuild, warm restart after Ctrl-C with stable ports/URLs,
`--fresh` wipe, placeholder warning) plus manual verification of log/TTY
output; unit tests for watch debounce and endpoint ordering.
- **Depends on:** S4.
- **Spec sections:** § 6, § 8 (gitignore check), error surface.

### S6 — proof on the open-chat port + measurement + close-out docs

- **Outcome:** the open-chat port (separate repo) switched to `dir()` +
`prisma-composer dev`, replacing `scripts/dev.ts`; sign-in/history/
live-tail verified; friction found lands here as fixes (re-triaged if
large); restart latency for `examples/store` measured and recorded;
`deploy-cli.md` scope updated; `local-dev.md` + ADR-0041 reconciled with
what shipped; port-repo changes committed there.
- **Depends on:** S2 + S5.
- **Spec sections:** acceptance criteria 7–10.

## Close-out (required)

- [ ] Verify all acceptance criteria in `.drive/projects/local-dev/spec.md`
- [ ] Final retro
- [ ] Migrate long-lived docs into `docs/` (local-dev.md/deploy-cli.md/ADR
already live there — reconcile, don't duplicate)
- [ ] Strip repo-wide references to `.drive/projects/local-dev/**`
- [ ] Delete `.drive/projects/local-dev/`
Loading
Loading