Skip to content

About

Pre-production readiness checker for Android — catches the classic "10 production mistakes" before code ships, and auto-fixes them with your permission.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ProdCheck 🛡️

Pre-production readiness checker for Android — catches the classic "10 production mistakes" before code ships, and auto-fixes them with your permission.

Layer Engine Covers Needs API key?
1 — Deterministic Custom Detekt rules via detekt-cli !! usage · main-thread blocking (UI files only) · sensitive logging · hardcoded secrets No — offline
2 — Agentic Claude (tool-use loop over your git diff) duplicate API calls · logic in Activities/Composables · missing error/empty states · token refresh · config change/process death · crash monitoring gaps Yes
Auto-fix Validated propose_edit agent pipeline Fixes findings from both layers; edits are exact-match validated; patches generated by the tool, never by the model Yes

1. One-time setup

# 1. Unpack to its permanent home
unzip prodcheck-v3.zip && mv prodcheck ~/prodcheck && cd ~/prodcheck

# 2. Gradle wrapper (zip ships without one — borrow from any Android project)
cp ~/AndroidStudioProjects/<AnyProject>/gradlew .
cp -R ~/AndroidStudioProjects/<AnyProject>/gradle .
chmod +x gradlew

# 3. Build the rules jar + agent binary
./gradlew :detekt-rules:jar :agent:installDist

# 4. Standalone detekt-cli
mkdir -p tools && cd tools
curl -L -o detekt-cli.zip https://github.com/detekt/detekt/releases/download/v1.23.7/detekt-cli-1.23.7.zip
unzip -q detekt-cli.zip && mv detekt-cli-1.23.7 detekt-cli
cd ..

# 5. PATH + API key (Layer 2 / auto-fix only — Layer 1 works without it)
echo 'export PATH="$HOME/prodcheck/bin:$PATH"' >> ~/.zshrc
echo 'export ANTHROPIC_API_KEY=sk-ant-...' >> ~/.zshrc     # your REAL key
source ~/.zshrc
chmod +x ~/prodcheck/bin/prodcheck

# 6. Self-test — expect 4 findings from BadExampleActivity.kt
prodcheck --l1 ~/prodcheck
cat ~/prodcheck/build/reports/prodcheck-layer1.md

API credits: console.anthropic.com → Plans & Billing. $5 covers hundreds of diff-scoped runs; a typical fix run costs cents.


2. Modes

prodcheck --l1 <project>       # Layer 1 scan only. Offline, free, whole project.
prodcheck --l1fix <project>    # L1 scan + auto-fix. Asks [y/N] before touching files.
prodcheck <project>            # L1 scan + L2 diff review -> writes a fix PATCH (no auto-apply).
prodcheck --all <project>      # Everything: L1 -> ask -> fix -> re-scan ->
                               #             L2 review -> ask -> fix -> compile check.
prodcheck --all --yes <proj>   # Same, but skips prompts (CI / scripted use).

<project> defaults to the current directory (prodcheck --all .).

Always use the exact folder name (HotfixAgent, not hotfixagent) — macOS is case-insensitive but patch paths are not.


3. The daily workflow

# 1. Finish a feature/bugfix. DO NOT commit yet —
#    Layer 2 reviews your uncommitted diff (git diff HEAD).
cd ~/AndroidStudioProjects/MyApp
prodcheck --all .

# 2. Read the findings shown before each [y/N] prompt.
#    y  -> fixes are applied to your working tree
#    n  -> skipped (L1 mode falls back to writing a patch file)

# 3. ALWAYS review what the agent changed before committing:
git diff                # or: git diff | cat  (no pager)

# 4a. Happy -> commit code + fixes together:
git add -A
git commit -m "Add <feature> (ProdCheck verified)"

# 4b. Unhappy with a specific fix -> undo just that file:
git checkout -- path/to/File.kt

# 4c. Undo ALL applied fixes:
git checkout -- .

Golden rules

  • Run from a state where everything except your current work is committed — that makes git diff review clean and undo safe.
  • Never commit an auto-fix you haven't read. The agent's edits are validated mechanically (exact-match, compile-checked) but semantic correctness is yours to confirm — we have watched it produce a plausible, confidently justified, wrong fix (see Lessons below).
  • A clean tree means Layer 2 reviews the last commit instead — useful for post-hoc review, but the intended flow is pre-commit.

Intentional violations

Real !! on purpose (crash tests, fixtures)? Suppress instead of fixing:

@Suppress("DoubleBang") // intentional: NPE crash-test entry
value!!.length

Detekt honours @Suppress natively; the finding disappears from every future scan.


4. Reports & outputs

All inside the target project (wiped by ./gradlew clean — copy out anything you want to keep):

File What
build/reports/prodcheck-layer1.md L1 findings with code snippets + line pointers
build/reports/prodcheck-layer2.md Agent verdict (PASS / WARN / BLOCK) + findings + fixes
build/reports/prodcheck-fix.patch Fix patch when you declined direct apply — git apply it
build/reports/prodcheck-layer2-raw.txt Raw agent output, only written if JSON parsing failed

Exit code is 1 on a BLOCK verdict — wire prodcheck --all --yes . straight into CI.


5. Android Studio one-click

Settings → Tools → External Tools → +

Field Value
Name ProdCheck L1
Program /Users/<you>/prodcheck/bin/prodcheck
Arguments --l1 $ProjectFileDir$
Working directory $ProjectFileDir$

Then: Tools → External Tools → ProdCheck L1 in any project. Add a second entry with arguments --all --yes $ProjectFileDir$ for the full pipeline (External Tools consoles can't answer prompts, hence --yes — review with git diff after).

For interactive --all, use the Studio Terminal tab instead.


6. Updating rules

Edit detekt-rules/src/main/kotlin/.../ProdCheckRules.kt, then:

cd ~/prodcheck && ./gradlew :detekt-rules:jar

Agent prompt / fixer guidance lives in agent/src/main/kotlin/.../Main.kt (review rules R2–R10) and Layer1Fix.kt (per-rule fix guidance), then:

cd ~/prodcheck && ./gradlew :agent:installDist

Every project picks the changes up on its next run — zero per-project config.

Tuning history (why the rules look like this)

  • MainThreadBlocking fires only in UI-adjacent files (*Activity.kt, *Fragment.kt, *Screen.kt, @Composable) — repository/store code usually already runs on Dispatchers.IO, which Layer 1 can't verify. That judgement belongs to Layer 2.
  • get was removed from the blocking-call list (JSONArray.get etc. = pure noise).
  • Layer 1 policy: precision over recall. A rule developers can't trust is a rule they'll ignore.

7. Lessons learned (read before trusting auto-fix)

  1. The agent once replaced an intentional !! (NPE crash-test) with requireNotNull and confidently claimed the behaviour was identical. It is not — requireNotNull throws IllegalArgumentException, not NullPointerException. On retry it defended the same error with a more elaborate wrong justification. Fluency ≠ correctness.
  2. Mitigation: intent-first guidance in the fixer prompt (deliberate !! → propose @Suppress, never behaviour changes). Measured result: the next real fix (LKRRate smart-cast refactor) was textbook-correct.
  3. Every harness bug we hit (loop control, path case-sensitivity, non-JSON final answers) was in the deterministic plumbing, not the LLM. Agentic reliability = harness engineering.

8. Troubleshooting

Symptom Fix
command not found: prodcheck source ~/.zshrc && hash -r; check ls ~/prodcheck/bin
permission denied: prodcheck chmod +x ~/prodcheck/bin/prodcheck
no such file: ./gradlew Copy wrapper from any Android project (setup step 2)
no repositories are defined Your settings.gradle.kts is outdated — needs the dependencyResolutionManagement block from v3
credit balance is too low console.anthropic.com → Plans & Billing → add credits
ANTHROPIC_API_KEY not set Real key in ~/.zshrc (not the sk-ant-YOUR-KEY placeholder), then source ~/.zshrc
Patch has a/../... paths You ran with a wrong-case path — use the exact folder name
No diff found — nothing to review Tree is clean; L2 needs uncommitted changes (or reviews last commit)
Junk findings from unexpected folders A stray copy of prodcheck (or other vendored code) inside the project — delete it
Output stuck at : That's the git pager — press q (or use git --no-pager diff)

9. Roadmap

  • Self-verification loop — agent applies patch → compiles → re-scans → rejects/retries on failure, automatically (today compile check only warns)
  • Baseline file — suppress legacy findings, gate only new code
  • GitHub Actions PR bot — findings as PR review comments, zero-install for teams
  • Compose-specific L1 rules (remember vs rememberSaveable, unkeyed calls)
  • Fix-acceptance tracking → precision metrics over time

About

Pre-production readiness checker for Android — catches the classic "10 production mistakes" before code ships, and auto-fixes them with your permission.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages