Proof: an existing Composer app runs locally with zero cloud credentials#166
Proof: an existing Composer app runs locally with zero cloud credentials#166wmadden-electric wants to merge 3 commits into
Conversation
…onciliation Proves the local-dev project end to end against the open-chat port (a separate repo, worked on as a full copy since the original is owned by a different user): pointed the port at this worktrees locally built @prisma/composer and @prisma/composer-prisma-cloud, switched its build descriptor to nodes directory form, replaced its hand-rolled scripts/dev.ts with prisma-composer dev, and proved sign-in, chat history, live-tail SSE, and generation-fails-at-OpenRouter-with-the-placeholder all work credential-free. Findings and the port-side patch land in .drive/projects/local-dev/assets/open-chat-port/. Measures restart latency on examples/store (median 3.24s over 5 runs, method + numbers in assets/latency.md) using the S5 proving scripts own touch-rebuild-reconverge-poll technique. Reconciles local-dev.md and ADR-0041 against what shipped, including a significant unresolved finding from the open-chat proof: a warm restart after Ctrl-C can leave every service stopped because Alchemys own no-op diffing skips the local Deployment providers reconcile when nothing in a resources props changed (a Ctrl-C stop is invisible to that diff). The existing store proving scripts own criterion-6 check does not catch this because it verifies port stability and reads Postgres directly rather than making an HTTP round-trip against the restarted service. Adds prisma-composer dev to deploy-cli.mds Scope section (moved out of Out of scope). Syncs spec.md/plan.md wholesale from the design branch tip. Signed-off-by: Will Madden <madden@prisma.io> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Rebase-equivalent of claude/local-dev-s6-proof onto main: the branch is rebuilt as the single S6 assets/docs commit cherry-picked onto main (the 35 production-code commits underneath it all merged via #158-#164), plus this refresh for two things that changed since the proof ran: - The warm-restart bug the proof found (services stayed stopped while dev printed ready, because a Ctrl-C stop is invisible to Alchemy props diffing) was fixed on #164: LocalTargetAttachment.startServices() runs on every attachment after each converge, before the front door. The finding stays in FRICTION-S6.md/local-dev.md/ADR-0041 with a fixed note referencing #164 instead of being deleted. - The seam rename: ExtensionDescriptor.localTarget (a lazy thunk) / LocalTargetDescriptor, subpaths @prisma/composer/local-target and @prisma/composer-prisma-cloud/local-target; "dev" names only the user-facing command, [dev] prefix and .prisma-composer/dev/. Stale pre-rename names (dev field, DevDescriptor, Dev*Input, the old @internal/lowering src/dev/ path) are updated in ADR-0041, the ADR index, local-dev.md and the latency probe, verified against main source (app-config.ts, local-target.ts, run-dev.ts, build.ts). Also records that Bundle.watch is now populated by both build adapters, so the latency method note about the missing watch loop is historical. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 39 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
An 1866-line format-patch blob dominated the PR diff and is not reviewable material; PORT.md now summarizes the port commit by file, and the friction log points there. The raw diff stays with the port copy. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Closing unmerged per review: the assets are transient project artifacts destined for deletion at close-out, and the doc reconciliation belongs with the close-out itself. One close-out PR replaces this — doc reconciliation + durable-evidence migration + removal of .drive/projects/local-dev/. The evidence remains on this branch. |
Against that URL, with no cloud credentials of any kind in the shell: sign-in worked, chat history loaded, and the live-tail stream delivered events. Chat generation failed — at exactly one place: the outbound OpenRouter call, because the local run minted a placeholder for the
OPENROUTER_API_KEYsecret instead of demanding a real one.This PR records the evidence that the local-dev project's founding claim holds: an existing Composer app runs locally with zero cloud credentials, through the same pipeline a deploy uses, failing only where the app itself reaches for a real external service. It contains no production code — the implementation is already on main (#158, #159, #160, #162, #164). What lands here is the proof material and the design-doc reconciliation that closes the project.
The exercise
prisma-composer dev(ADR-0041, on main) runs the deploy pipeline — load the app's graph, assemble each service from the user's own built output, lower to resources, converge — but substitutes local providers that talk to on-machine emulator daemons instead of the platform. The claim worth proving was never "a fixture app works"; it was that an app written before local dev existed, in its own repo, comes up with one command.open-chat is that app. Porting it took one commit, summarized file-by-file in
assets/open-chat-port/PORT.md: point its framework dependency at the locally built packages, switch its service tonode()'s directory build form, fix a launcher path that only worked un-moved, catch up with two API changes that had landed since the app was written — and delete its 169-line hand-rolledscripts/dev.ts, which is the point: the framework command replaces the app's own process-juggling script. Everything that hurt along the way is inassets/open-chat-port/FRICTION-S6.md(six findings; the one blocker is below).Two measurements ride along:
examples/store; method and script inassets/latency.md/assets/latency-probe.ts.What the proof found and what happened to it
The port surfaced one real bug: after Ctrl-C, a second
devrun could print the app ready while every service stayed stopped — stopping changes no resource properties, so the converge engine saw nothing to do and never restarted anything. That fix landed in #164 (the dev command now explicitly starts stopped services after every converge, before printing the ready lines). The finding stays in the friction log with a fixed-in note rather than being deleted — the log is a record of what the proof hit, not a list of open issues.Because the proof ran before the stack's final naming pass, this PR also reconciles the design docs with what shipped: ADR-0041, the ADR index,
local-dev.md, anddeploy-cli.mdnow describe thelocalTargetseam (the extension field and descriptor actually in the code) instead of the earlierdev-prefixed names, and note that both build adapters now populate the watch paths the dev loop uses. Every such claim was checked against main's source before being written down.Files
assets/open-chat-port/PORT.md— the port commit, summarized by file.assets/open-chat-port/FRICTION-S6.md— the six findings, with outcomes.assets/latency.md,assets/latency-probe.ts— the latency numbers and how they were taken.docs/design/…— the reconciliation described above.Alternatives considered
git format-patchoutput as an asset — the first cut did, and an 1,866-line patch blob dominated the diff while being unreviewable; replaced with the file-by-file summary. The raw diff stays with the port working copy.This repo is proof-of-concept stage; the proof shows the claim holds for this app on this machine, nothing broader.
🤖 Generated with Claude Code