Skip to content

ADFA-4357 Add agent & contributor documentation set#1422

Open
hal-eisen-adfa wants to merge 12 commits into
stagefrom
ADFA-4357-add-markdown-files-for-agents
Open

ADFA-4357 Add agent & contributor documentation set#1422
hal-eisen-adfa wants to merge 12 commits into
stagefrom
ADFA-4357-add-markdown-files-for-agents

Conversation

@hal-eisen-adfa

Copy link
Copy Markdown
Collaborator

ADFA-4357 — Agent & contributor documentation set

Adds a coordinated set of Markdown docs to onboard both human and AI contributors and to record the project's architectural decisions. Docs only — no code or build changes.

What's included

File Purpose
CLAUDE.md Operational guide for Claude Code: build/test commands, ABI flavors, project constraints. Points to ARCHITECTURE.md for architecture.
AGENTS.md Operational rules for agents: CI-vs-local, Jira CLI, SonarQube MCP, git-message handling.
ARCHITECTURE.md Single source of truth for module layout, layering & data flow (UDF), dependency rules, tech stack, state management, testing.
REVIEW.md Code-review coaching: exception handling (Sentry crash wrapper), LeakCanary leaks, StrictMode, OWASP, tests/coverage, analytics, duplication, docstrings, strings.xml.
SECURITY.md How to avoid introducing new SonarQube/Snyk/Semgrep blocker findings; vulnerability classes for an Android/Kotlin IDE.
docs/adr/ 8 Architecture Decision Records (MADR/Nygard) + index.

ADRs

  1. Persistence without Room
  2. On-device builds via the Gradle Tooling API (out-of-process)
  3. Vendored/forked desktop toolchain via composite-build substitution
  4. Embedded Termux runtime
  5. Per-ABI product flavors (v7/v8)
  6. Koin for dependency injection
  7. Custom StrictMode whitelist engine
  8. Retaining the com.itsaky.androidide namespace after rebrand

Notes for reviewers

Content was written against the actual codebase (verified patterns: Koin DI, Firebase IAnalyticsManager, the StrictMode whitelist engine, Sentry global handler, tooling-api out-of-process, vendored toolchain). Two claims are author inferences worth a sanity check:

  • ARCHITECTURE.md / SECURITY.md: "Retrofit is in the catalog but effectively unused in app code."
  • ADR 0005: the per-ABI rationale assumes direct-APK-download is the primary distribution channel (Play App Bundle splits treated as not relied upon).

Follow-ups (intentionally out of scope)

  • Remove the unused Room Gradle deps in idetooltips (surfaced by ADR 0001/0003).
  • Optional: add a back-link from ARCHITECTURE.md to docs/adr/.

Add a coordinated set of Markdown docs to onboard both human and AI
contributors and to capture the project's architectural decisions.

- CLAUDE.md: operational guide for Claude Code (build/test commands,
  ABI flavors, project constraints); points to ARCHITECTURE.md for
  architecture rather than duplicating it.
- AGENTS.md: operational rules for agents (CI-vs-local, Jira CLI,
  SonarQube MCP, git message handling); persistence rule now points to
  ARCHITECTURE.md.
- ARCHITECTURE.md: single source of truth for module layout, layering &
  data flow (UDF), dependency rules, tech stack, state management, and
  the testing strategy.
- REVIEW.md: code-review coaching (exception handling vs the Sentry
  crash wrapper, LeakCanary leaks, StrictMode, OWASP, tests/coverage,
  analytics, duplication, docstrings, strings.xml).
- SECURITY.md: how to avoid introducing new SonarQube/Snyk/Semgrep
  blocker findings; vulnerability classes for an Android/Kotlin IDE.
- docs/adr/: 8 Architecture Decision Records (MADR/Nygard) plus an index
  covering persistence-without-Room, on-device builds via the Gradle
  Tooling API, the vendored toolchain, embedded Termux, per-ABI flavors,
  Koin DI, the StrictMode whitelist engine, and retaining the
  com.itsaky.androidide namespace.
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2852f88f-fb16-4088-894b-18421a007aec

📥 Commits

Reviewing files that changed from the base of the PR and between ff0383b and 3805e5f.

📒 Files selected for processing (14)
  • AGENTS.md
  • ARCHITECTURE.md
  • CLAUDE.md
  • REVIEW.md
  • docs/adr/0001-persistence-without-room.md
  • docs/adr/0002-on-device-builds-via-gradle-tooling-api.md
  • docs/adr/0003-vendored-forked-desktop-toolchain.md
  • docs/adr/0004-embedded-termux-runtime.md
  • docs/adr/0005-per-abi-product-flavors.md
  • docs/adr/0006-koin-dependency-injection.md
  • docs/adr/0007-strictmode-whitelist-engine.md
  • docs/adr/0008-retain-androidide-namespace.md
  • docs/adr/0009-jetpack-compose-for-new-ui.md
  • docs/adr/README.md
✅ Files skipped from review due to trivial changes (10)
  • docs/adr/0009-jetpack-compose-for-new-ui.md
  • docs/adr/README.md
  • docs/adr/0002-on-device-builds-via-gradle-tooling-api.md
  • docs/adr/0007-strictmode-whitelist-engine.md
  • docs/adr/0001-persistence-without-room.md
  • docs/adr/0003-vendored-forked-desktop-toolchain.md
  • docs/adr/0008-retain-androidide-namespace.md
  • docs/adr/0006-koin-dependency-injection.md
  • docs/adr/0004-embedded-termux-runtime.md
  • ARCHITECTURE.md

📝 Walkthrough

A detailed high-level summary could not be generated for this review. Here is an overview derived from the analyzed file changes:

  • AGENTS.md: ## AI-generated summary of changes
  • ARCHITECTURE.md: ## AI-generated summary of changes
  • CLAUDE.md: ## AI-generated summary of changes
  • REVIEW.md: ## AI-generated summary of changes
  • SECURITY.md: ## AI-generated summary of changes
  • docs/adr/0001-persistence-without-room.md: ## AI-generated summary of changes
  • docs/adr/0002-on-device-builds-via-gradle-tooling-api.md: ## AI-generated summary of changes
  • docs/adr/0003-vendored-forked-desktop-toolchain.md: ## AI-generated summary of changes
  • docs/adr/0004-embedded-termux-runtime.md: ## AI-generated summary of changes
  • docs/adr/0005-per-abi-product-flavors.md: ## AI-generated summary of changes
  • docs/adr/0006-koin-dependency-injection.md: ## AI-generated summary of changes
  • docs/adr/0007-strictmode-whitelist-engine.md: ## AI-generated summary of changes
  • docs/adr/0008-retain-androidide-namespace.md: ## AI-generated summary of changes
  • docs/adr/README.md: ## AI-generated summary of changes
  • docs/adr/0009-jetpack-compose-for-new-ui.md: ## AI-generated summary of changes

Walkthrough

Adds a complete project documentation baseline: AGENTS.md and CLAUDE.md for contributor/AI agent operating rules, ARCHITECTURE.md for module/stack/state-management conventions, REVIEW.md for code review standards, SECURITY.md for vulnerability policy, and nine Architecture Decision Records (ADRs 0001–0009) covering persistence, build engine, toolchain vendoring, Termux runtime, ABI flavors, Koin DI, StrictMode, namespace retention, and Jetpack Compose adoption.

Changes

Project Documentation Suite

Layer / File(s) Summary
AI agent and contributor operating guides
AGENTS.md, CLAUDE.md
AGENTS.md establishes emulator targeting, persistence restrictions (no Room), dependency constraints, Jira/SonarQube/CI tooling conventions, and tempfile-based git/gh workflows. CLAUDE.md documents flox-wrapped Gradle usage, ABI flavor task naming, CI command sourcing from .github/workflows/*.yml, code-style rules, and branch naming conventions.
Architecture overview: modules, tech stack, and state management
ARCHITECTURE.md
Documents the UI → ViewModel → Repository → data-source layering, module dependency rules, composite-build substitution, ABI flavor policy, Koin/Coroutines/Flow technology choices, persistence policy (no Room for new code), UDF UiState/UiEffect/UiEvent patterns with Kotlin examples, and UDF ViewModel testing guidance.
Architecture Decision Records 0001–0009 and ADR index
docs/adr/README.md, docs/adr/000*
README.md defines ADR format and indexes all nine decisions. ADRs cover: no-Room persistence (0001), out-of-process Gradle Tooling API builds (0002), vendored desktop toolchain via dependencySubstitution (0003), embedded Termux runtime (0004), per-ABI v7/v8 product flavors (0005), Koin DI adoption (0006), custom StrictMode whitelist engine (0007), namespace retention after rebrand (0008), and Jetpack Compose for new IDE UI (0009).
Code review guide and quality enforcement
REVIEW.md
Adds a 60-second preflight checklist and detailed sections for exception handling, leak prevention, StrictMode enforcement, OWASP-aligned security criteria, testing expectations with SLF4J fallback, observability standards (IAnalyticsManager, no PII in analytics), accessibility requirements (cd_ convention, contentDescription), contextual help wiring, offline-first requirements, experimental feature flag gating, and PR hygiene rules.
Security baseline and vulnerability guidance
SECURITY.md
Defines the frozen blocker baseline policy, roles of SonarQube/Snyk/Semgrep in CI, vulnerability classes to avoid (hardcoded secrets, injection types, weak crypto, insecure TLS, WebView/XML/deserialization risks, CVEs via Snyk), a pre-push checklist, and private vulnerability reporting instructions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • itsaky-adfa
  • jatezzz

Poem

🐇 Hop hop, the docs arrive at last,
Architecture rules and ADRs cast!
Nine decisions, neatly in a row,
Review checklists help the codebase grow.
No Room for new code, Compose shall reign—
This bunny's happy with every refrain! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: the addition of agent and contributor documentation set.
Description check ✅ Passed The description comprehensively explains what documentation is being added, why, and what architectural decisions are recorded, directly relating to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ADFA-4357-add-markdown-files-for-agents

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/adr/0005-per-abi-product-flavors.md (1)

39-39: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Trailing artifact at end of file.

Line 39 contains a stray 39 character that appears to be a formatting artifact or incomplete truncation.

Verify the file ends cleanly. If this is the intended end, remove the stray character.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/adr/0005-per-abi-product-flavors.md` at line 39, The file
docs/adr/0005-per-abi-product-flavors.md has a stray character "39" at the end
that appears to be a formatting artifact. Locate the end of the file and remove
this trailing character to ensure the markdown file ends cleanly without any
extraneous content.
🧹 Nitpick comments (2)
REVIEW.md (1)

80-80: 💤 Low value

Minor: replace "exactly" with more specific verb.

LanguageTool flags "exactly" as an over-used intensifier. Consider "are" or "represent" depending on intended emphasis, or rephrase to avoid the intensifier.

Example:

-- **No duplication.** If you copy-pasted a block, extract a function/extension into the right `common`/`utils` module. Before adding a helper, grep — we likely already have it. Repeated literals/magic numbers → named constants.
+- **No duplication.** If you copy-pasted a block, extract a function/extension into the right `common`/`utils` module. Before adding a helper, grep — we likely already have it. Repeated literals/magic numbers become named constants.

Alternatively, keep the intensity but rephrase: "those are the error paths the crash wrapper would otherwise catch" → "those represent the error paths the crash wrapper would otherwise catch".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@REVIEW.md` at line 80, In the REVIEW.md file, locate the sentence containing
"those are exactly what the crash wrapper would otherwise catch in production"
and remove the over-used intensifier "exactly" by replacing it with a more
specific verb such as "represent" or rephrase the sentence to eliminate the
intensifier entirely (for example, change "those are exactly what" to "those
represent what" or similar phrasing that conveys the same meaning without the
weak intensifier).
docs/adr/0005-per-abi-product-flavors.md (1)

9-9: 💤 Low value

Minor: replace "very large" with a stronger adjective for clarity.

LanguageTool flags "very large" as an over-used intensifier. Consider "substantial", "sizable", or "prohibitive" depending on emphasis.

Example:

-Code On The Go is distributed primarily as a **direct APK download** from the App Dev for All website, not exclusively through Google Play, so we cannot rely on Play's automatic per-ABI splitting to slim downloads.
+Code On The Go is distributed primarily as a **direct APK download** from the App Dev for All website, not exclusively through Google Play, so we cannot rely on Play's automatic per-ABI splitting to slim substantial downloads.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/adr/0005-per-abi-product-flavors.md` at line 9, In the file
docs/adr/0005-per-abi-product-flavors.md, replace the phrase "very large" with a
stronger, more specific adjective in the sentence describing universal APK size.
Consider using alternatives such as "substantial", "sizable", or "prohibitive"
to provide clearer emphasis on why per-ABI splitting is necessary, as "very
large" is flagged as an over-used intensifier. Choose the adjective that best
conveys the intended severity of the size concern in the context of direct APK
distribution.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/adr/0005-per-abi-product-flavors.md`:
- Line 39: The file docs/adr/0005-per-abi-product-flavors.md has a stray
character "39" at the end that appears to be a formatting artifact. Locate the
end of the file and remove this trailing character to ensure the markdown file
ends cleanly without any extraneous content.

---

Nitpick comments:
In `@docs/adr/0005-per-abi-product-flavors.md`:
- Line 9: In the file docs/adr/0005-per-abi-product-flavors.md, replace the
phrase "very large" with a stronger, more specific adjective in the sentence
describing universal APK size. Consider using alternatives such as
"substantial", "sizable", or "prohibitive" to provide clearer emphasis on why
per-ABI splitting is necessary, as "very large" is flagged as an over-used
intensifier. Choose the adjective that best conveys the intended severity of the
size concern in the context of direct APK distribution.

In `@REVIEW.md`:
- Line 80: In the REVIEW.md file, locate the sentence containing "those are
exactly what the crash wrapper would otherwise catch in production" and remove
the over-used intensifier "exactly" by replacing it with a more specific verb
such as "represent" or rephrase the sentence to eliminate the intensifier
entirely (for example, change "those are exactly what" to "those represent what"
or similar phrasing that conveys the same meaning without the weak intensifier).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 636711f5-1206-408a-9727-feafce7276a9

📥 Commits

Reviewing files that changed from the base of the PR and between 8082c92 and d279292.

📒 Files selected for processing (14)
  • AGENTS.md
  • ARCHITECTURE.md
  • CLAUDE.md
  • REVIEW.md
  • SECURITY.md
  • docs/adr/0001-persistence-without-room.md
  • docs/adr/0002-on-device-builds-via-gradle-tooling-api.md
  • docs/adr/0003-vendored-forked-desktop-toolchain.md
  • docs/adr/0004-embedded-termux-runtime.md
  • docs/adr/0005-per-abi-product-flavors.md
  • docs/adr/0006-koin-dependency-injection.md
  • docs/adr/0007-strictmode-whitelist-engine.md
  • docs/adr/0008-retain-androidide-namespace.md
  • docs/adr/README.md

Promote accessibility from a proposed item to an enforced review section
and add a parallel contextual-help (long-press 3-tier) rule, both keyed
to existing patterns (ADFA-2667 screen-reader work, the idetooltips module).

- REVIEW.md: new sections for content-description coverage and long-press
  help; matching 60-second-checklist entries; renumber trailing sections.
- idetooltips/README.md: state the long-press-for-help-everywhere principle
  and the three-tier (tooltip / tooltip / web page) help model.
@hal-eisen-adfa hal-eisen-adfa marked this pull request as draft June 19, 2026 03:37
- ADR 0009: new IDE UI is Jetpack Compose, no new XML View screens; the
  UDF/Koin/StateFlow stack is unchanged. Indexed in docs/adr/README.md.
- ARCHITECTURE.md: tech-stack UI row + overview now point to ADR 0009
  instead of claiming the IDE is 'Not Compose'.
- REVIEW.md: new Compose-only rule in Architecture alignment; accessibility
  (§8) now gives View + Compose forms for each rule (semantics,
  clearAndSetSemantics, the HardcodedText lint gap); contextual help (§9)
  notes idetooltips has no Compose entry point yet (displayTooltipOnLongPress
  is View-based); promote Offline-first from proposed to an accepted section.
…idge

The Compose-only mandate (ADR 0009) and the long-press-everywhere rule
(REVIEW.md section 9) need a Compose entry point into the View-based
idetooltips system, which does not exist yet. Reference the follow-up
ticket from both docs so the gap is tracked, not forgotten. Docs only.
…4382

The README's usage examples document a showIDETooltip() API that no longer
exists (real API: TooltipManager.showTooltip / displayTooltipOnLongPress)
and claim a Room store the module doesn't use (it's raw SQLite). Add a
banner so contributors trust the code until the refresh lands. Docs only.
Leave idetooltips/README.md untouched on this PR. Removes both the
design-principle section and the staleness banner added earlier; the
README refresh is handled wholesale in ADFA-4382 instead.
- REVIEW.md: new Code-quality rule + 60-second-checklist entry requiring a
  change to update any module README/ARCHITECTURE.md/ADR it affects, or
  leave a tracked note.
- AGENTS.md: one-line operational pointer to the REVIEW.md rule, so agents
  that read AGENTS.md (but not REVIEW.md) still apply it.
Tighten prose across CLAUDE.md, AGENTS.md, ARCHITECTURE.md, REVIEW.md, and
the ADRs — cut hedging, doubled phrasings, and restated context; no facts,
paths, commands, or decisions changed. Also:
- REVIEW.md §9: drop the stale showIDETooltip reference in the intro.
- ARCHITECTURE.md: reconcile the data-flow UI note with ADR 0009 (existing
  UI is Views; new UI is Compose) instead of a flat 'not Compose'.
- Experimental feature flag: clarify it's a user-facing early-access opt-in
  (singular flag), not a kill switch for us to disable features in the field.
- Remove the performance-budget proposal; captured as ADFA-4383 instead.
Move it out of 'Open for discussion' into a numbered review section; gate
not-yet-stable features behind the user-facing early-access flag. Renumber
PR hygiene to §13.
…scussion section

The MIN_SDK guard concern doesn't arise in practice; remove the item. It was
the last proposal, so remove the empty section scaffolding too. REVIEW.md now
ends at §13 PR hygiene.
@hal-eisen-adfa hal-eisen-adfa marked this pull request as ready for review June 19, 2026 06:57
Comment on lines +15 to +17
New persistence uses **raw SQLite** (`SQLiteOpenHelper` / `SQLiteDatabase`) or the **filesystem / preferences**. Room is **not** used for new code.

The one exception is the **Recent Projects** feature (`app/src/main/java/com/itsaky/androidide/roomData/recentproject/`, `@Database version = 4`), which predates this decision and is grandfathered in. Do not extend it with new entities or tables. (`idetooltips` still declares unused Room Gradle deps; its tooltip store is raw SQLite — remove those deps.)

@itsaky-adfa itsaky-adfa Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not true. AFAIK, raw SQLite is only used for indexing symbols from libraries (and the web server) because we want granular control over the index schema and queries, while also reducing the number of object allocations and overall memory use. Room should be preferred in most cases, but raw SQLite can be used for similar use cases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably be removed if we add a statement somewhere that Room should be preferred, while raw SQLite should be used when the use case is justified (control over the actual schema, performance-critical code, etc.).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is almost entirely incorrect, but I do believe that we should have a document that distinguishes between the vendored toolchains, their use cases and how they differ from the tooling api toolchains.

  1. Modules in composite-build/build-deps* are included in the final APK. They're part of the IDE's runtime and are used to provide certain features to the IDE.
  2. They're kept in composite-builds to reduce build times - composite builds are a separate Gradle build from the main build, they're not built unless their sources are changed, even when we do a clean-build in the main build. Read more here: https://docs.gradle.org/current/userguide/composite_builds.html
  3. The toolchains in composite builds (javac, jdk-compiler, jdk-jdeps, jdt, etc.) are used in the IDE's runtime. They're NOT used for providing ANY tooling API features, nor they're used to run the tooling API itself. For example, the javac, jdk-compiler composite builds and used to provide Java LSP features, like parsing and analyzing Java source files within the IDE's runtime - without having to invoke the JDK's javac via ProcessBuilder, or building our own custom parser/analyzer.
  4. The tooling API is invoked using a full-blown JDK/JVM using ProcessBuilder and runs as a daemon. The JDK used to run the tooling API and invoke Gradle builds is built from our appdevforall/terminal-packages repository and packaged within our terminal bootstrap packages. The IDE communicates with the tooling API (running as a daemon) using the JSONRpc protocol (the models/interfaces are defined in subprojects/tooling-api, subprojects/tooling-api-model and subprojects/tooling-api-events modules).


Code On The Go is the rebranded successor to **AndroidIDE**. The product name, branding, and assets changed, but the inherited codebase carries the original identity deeply: the application id and Gradle namespace are `com.itsaky.androidide` (`BuildConfig.PACKAGE_NAME`), `rootProject.name` is `AndroidIDE`, plus many thousands of references, the generated `R` class, the manifest, package-qualified vendored substitutions, signing identity, and existing installs in the field.

Changing an Android **application id** breaks the update path for installed users (a different app id is a different app) and disrupts signing/identity continuity. A rename of this size also ripples through the vendored `com.itsaky.androidide.build:*` substitutions ([ADR 0003](0003-vendored-forked-desktop-toolchain.md)).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification worth adding: the major reason we have the package name set to com.itsaky.androidide is that it requires us to re-build terminal packages with the updated package name. Also, it is not possible to change package name incrementally (i.e. change in terminal packages first, then the app - or vice-versa). The change needs to be a big-bang change such that we have the package name changed in the terminal packages as well as this codebase (the application) as an atomic change.

Comment thread AGENTS.md
@@ -0,0 +1,37 @@
Code On The Go is an Android IDE — it lets users edit, build, and deploy their own Android apps on-device, like Eclipse or VSCode.

There is at least one Android emulator available. Find it with `adb devices -l | grep -v offline`, then use the `ANDROID_SERIAL` env var.

@itsaky-adfa itsaky-adfa Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily. x86_64 machines can't run the arm64/arm apps, sometimes not even with a translation layer. In that case, we might end up using physical devices instead (like I have to do right now, although I plan to work on getting the arm64 variant to work on devices with arm64 translation layer - like Waydroid).

Comment thread ARCHITECTURE.md

## State Management

- **UI state is a single immutable `data class`** exposed as a `StateFlow<…UiState>`; the ViewModel mutates a private `MutableStateFlow` via `update { it.copy(...) }`. Derived booleans live as computed properties on the state class (so the UI stays dumb).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

State should not necessarily be a data class, especially for UI that has multiple, mutually-exclusive states. It can lead to problems like "boolean hell" and state explosion. If a UI has multiple states (loading, installing, processing, completed, failed, cancelled, etc.) - they must almost always be represented with sealed classes. The goal of using sealed classes is to make the state machine explicit and ensure that incompatible states cannot co-exist at the same time.

Comment thread ARCHITECTURE.md
Comment on lines +117 to +125
data class PluginManagerUiState(
val isLoading: Boolean = false,
val plugins: List<PluginInfo> = emptyList(),
val isPluginManagerAvailable: Boolean = false,
val isInstalling: Boolean = false,
) {
val isEmpty: Boolean get() = plugins.isEmpty() && !isLoading // derived in state
val showEmptyState: Boolean get() = isEmpty && isPluginManagerAvailable
}

@itsaky-adfa itsaky-adfa Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually a good example of why it should use sealed classes: isLoading, isInstalling and isEmpty can be true at the same time.

The example should be changed to demonstrate mutually-exclusive state definition using sealed classes.

Comment thread CLAUDE.md

## Code style

2-space indents everywhere. Java: Google style (`google-java-format`); Kotlin: `ktfmt` Google-internal style; XML: Android Studio formatter. Branch names must match `.../ADFA-#####` (3–5 digits) — see CONTRIBUTING.md; a pre-commit hook enforces it (`sh ./scripts/install-git-hooks.sh`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect. Codebase is configured to use Spotless for formatting files. Spotless is configured to use tabs instead of spaces.

Comment thread REVIEW.md
## How to use this

- **Author:** self-review against this list *before* requesting review. Most of it you can check in five minutes.
- **Reviewer:** you own correctness, leaks, security, and tests. Don't rubber-stamp; don't bikeshed style the formatter already enforces (`ktfmt` / `google-java-format`, 2-space indents).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tabs as indents, not spaces.

Comment thread REVIEW.md
- [ ] **Tests:** non-UI logic has unit coverage. Where coverage is thin, there's logging to diagnose it in the field.
- [ ] **No duplication:** the change reuses existing helpers instead of copy-pasting.
- [ ] **Docs:** public classes/functions have KDoc/Javadoc explaining *why*, not *what*; any module `README`/`ARCHITECTURE.md`/ADR the change affects is updated in the same PR.
- [ ] **Strings** are in `strings.xml`, not inline literals.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding: strings should be added in the :resources module's strings.xml, not per-module. This is to ensure ease of translation.

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.

2 participants