Skip to content

ADFA-4128 (1/11): docs — how Quick Build works and why - #1713

Draft
fryanpan wants to merge 2 commits into
stagefrom
feature/ADFA-4128-qb-01-docs
Draft

ADFA-4128 (1/11): docs — how Quick Build works and why#1713
fryanpan wants to merge 2 commits into
stagefrom
feature/ADFA-4128-qb-01-docs

Conversation

@fryanpan

@fryanpan fryanpan commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Part 1/11 of the stacked split of #1669

PR Stack Overview

This is PR 1 of 11 in the stack that makes up the initial release of the Quick Build feature (behind the Experiments flag, FeatureFlags.isExperimentsEnabled).

Here's an overview of the whole sequence:

PR Branch What it does
1 feature/ADFA-4128-qb-01-docs Design docs and ADRs — the map every later PR is read against
2 feature/ADFA-4128-qb-02-plumbing Host-side groundwork: feature flag, asset staging, build-service hooks, shared utilities
3 feature/ADFA-4128-qb-03-protocol The daemon wire format — the contract the IDE and compile daemon share
4 feature/ADFA-4128-qb-04-runtime Inside the proxy app: swaps code, resources and assets into the running process
5 feature/ADFA-4128-qb-05-core-detection Core slice 1: watch the tree, coalesce a save burst, classify the cheapest correct route
6 feature/ADFA-4128-qb-06-core-deploy Core slice 2: reload-vs-restart policy, the binder deploy channel, stage-cost telemetry
7 feature/ADFA-4128-qb-07-core-provisioning Core slice 3: proxy-app install state and the compile-daemon client the pipeline needs first
8 feature/ADFA-4128-qb-08-core-orchestration Core slice 4: the session state machine tying the slices together; every transition narrated
9 feature/ADFA-4128-qb-09-daemon Long-lived compile service keeping kotlinc caches warm: incremental Kotlin/Java, d8, aapt2
10 feature/ADFA-4128-qb-10-gradle-plugin Generates the proxy app during a Gradle build: proxy classes, manifest rewrite, quickbuild.json
11 feature/ADFA-4128-qb-11-app Wires Quick Build into the IDE (toolbar, session lifecycle, provisioning) + the debug-only benchmark surface

What's In This PR?

This PR holds the overview documentation that helps understand all of the later PRs in the stack. It's the most important PR for reviewing the overall architecture and giving feedback. If you see any major architecture issues, feel free to bring them up in this PR and I can look into moving things around!

Quick Build (ADFA-4128) makes the on-device edit loop much faster: tap the lightning-bolt button once and CoGo installs a generated proxy app — a live-reloading build of the user's project. From then on every compatible save reaches the running app in 1-2s on a moderate spec phone (Samsung A56), with no Gradle build and no reinstall, entirely on device.

flowchart LR
    trig(["File saved, or Quick Build button tapped"]) --> app
    subgraph cogo["CoGo process"]
        app["<b>:app wiring</b> (PR 11)<br/>toolbar action, narration, DI"] --> core["<b>:quickbuild:core</b> (PRs 5-8)<br/>watch, classify, route;<br/>session state machine"]
    end
    core -- "compile requests, wire JSON<br/>(<b>:quickbuild:protocol</b>, PR 3)" --> daemon["<b>:quickbuild:daemon</b> (PR 9)<br/>separate JVM: incremental<br/>kotlinc/javac, d8, aapt2"]
    daemon -- "dex + resource payload" --> core
    core -- "live reload: AIDL + fds" --> rt["<b>:quickbuild:runtime</b> (PR 4)<br/>inside the proxy app:<br/>swap code/resources/assets, recreate"]
    core -- "fallback: full Gradle build" --> gp["<b>:gradle-plugin</b> (PR 10)<br/>generates the proxy app"]
    gp -- "install + relaunch" --> rt
Loading

Goals

  • Live reload fast enough to keep the user in flow — a compatible save reaches the running app in seconds, with no Gradle build and no reinstall, entirely on device.
  • The proxy app behaves like the real app and is never stale — same applicationId, permissions, components and resources; every edit either live-reloads or visibly falls back to a real Gradle build.
  • Never modify the user's code — the generated proxy app wraps the project; the user's sources stay untouched.
  • Not 100% Gradle-compatible, by design — where the proxy can't match a real build, the limit is stated to the user rather than papered over. Useful beats exact.
  • Tradeoffs are taken knowingly and kept small — some extra first-open time and a resident compile daemon's memory buy the fast loop.
  • Offline, on device — the same standard as CoGo itself.

(Condensed from quickbuild/README.md's Goals section, which is the authoritative version.)

What to review

  • Start from quickbuild/README.md (read it somewhere where you can see the Mermaid diagrams)
  • Then look in docs/quickbuild folder for additional detail. In particular, these docs might be the most useful:
    • pipeline.md has a deeper dive into each component
    • component-proxying-design.md explains how Code on the Go communicates with the proxy app
    • manual-qa.md is a manual test plan that the implementation passes(this is in addition to good automated test coverage)
  • ADR 0015 records the decision to revisit ADR 0002 and have a second build pipeline outside of Gradle

Note: these docs describe the whole feature, so their code and doc links resolve only once PRs 2-11 land — this docs PR merges first by design.

How this PR Was Tested

  • This is docs only -- so no code changes in the blast radius
  • Docs have been reviewed and edited by Bryan

Coverage — docs only, no code, no coverage.

What's Coming Next

Note that we've tried to keep the whole feature separate as possible from existing Code on the Go components. Most PRs are completely new modules.

The main changes where there's some blast radius/risk from integrating with Code on the Go happen in these PRs:

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kj9YeCDHGp9DU8LPtfWJ7W

… PR is read against

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kj9YeCDHGp9DU8LPtfWJ7W
- README ADR reference: 0012 -> 0015 (the ADR this branch actually adds)
- pipeline.md task table: dropped nonexistent components.json asset; task emits proxy sources + manifest-info.json intermediate (not shipped in the APK)
- debugging.md: dropped nonexistent assets/quickbuild/components.json; APK carries gen-0.dex + baseline-generation.txt, component names flow via manifest-info.json/setup.json intermediates
- README test trap: ignoreFailures is analysis-run-only (sonar/sonarqube/jacocoAggregateReport), ordinary test runs gate on failures

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kj9YeCDHGp9DU8LPtfWJ7W
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant