Skip to content

Instantly share code, notes, and snippets.

View LethalMaus's full-sized avatar

James Cullimore LethalMaus

View GitHub Profile
@LethalMaus
LethalMaus / qa-agent-scenario-metadata.yaml
Created July 11, 2026 21:31
QA agent scenario metadata example
scenario_id: checkout-payment-failure
manual_cases:
- CASE-123
recommended_layer: robolectric
status: review
confidence:
current: 82
remaining_caveat: Real backend handoff is still verified manually.
@LethalMaus
LethalMaus / qa-agent-generated-prompt.md
Created July 11, 2026 21:31
QA agent generated prompt example

Write the recommended JVM UI test for case CASE-123 mapped to scenario checkout-payment-failure.

First read the shared testing rules and follow the existing nearby test style.

Use the lowest-cost layer that gives useful confidence. If the test changes coverage, update the scenario mapping and confidence note.

Case-specific notes:

  • mirror nearby payment failure tests
  • cover the error state and retry action
  • do not claim full confidence because backend settlement is still manual
@LethalMaus
LethalMaus / qa-agent-workflow-flow.txt
Created July 11, 2026 21:31
QA agent workflow flow
Manual test case export
-> one local record per case
-> mapped to an internal scenario
-> current automation is matched
-> report classifies confidence
-> missing-tests queue suggests the next layer
-> QA copies the generated prompt
-> coding agent writes or updates the test
-> mapping and confidence are updated
-> report shows the new state
@LethalMaus
LethalMaus / android-parallel-ci-shape.txt
Created July 11, 2026 21:31
Android parallel CI shape
Verify
+-- Assemble
+-- Lint
+-- Unit tests
+-- Security analysis
SonarQube
@LethalMaus
LethalMaus / android-wait-helper-before.java
Created July 11, 2026 21:31
Android wait helper before fix
do {
try {
onView(withId(resourceId)).check(matches(isDisplayed()));
} catch (AssertionError | RuntimeException ignored) {
// keep waiting
}
} while (System.currentTimeMillis() < endTime);
@LethalMaus
LethalMaus / article4-provider-query-secure-vs-vuln.kt
Created July 11, 2026 21:23
Android Security Training article 4 provider query secure versus vulnerable
// secure
override fun tryQueryDemoProvider(context: Context, uri: String): String {
return try {
val u = uri.toUri()
context.contentResolver.query(u, null, null, null, null)?.use { c ->
if (c.moveToFirst()) {
val valIdx = c.getColumnIndex("value")
val msg = if (valIdx >= 0) c.getString(valIdx) else "row count=${c.count}"
"query ok: $msg"
} else {
@LethalMaus
LethalMaus / article4-service-start-secure-vs-vuln.kt
Created July 11, 2026 21:23
Android Security Training article 4 service start secure versus vulnerable
// secure
override fun tryStartProtectedService(context: Context): String {
return try {
val intent = Intent()
intent.setClassName(context, "dev.jamescullimore.android_security_training.perm.DemoService")
val cn = context.startService(intent)
"startService result: $cn (expected: may fail for external callers; internal allowed)"
} catch (t: Throwable) {
"startService error: ${t.javaClass.simpleName}: ${t.message}"
}
@LethalMaus
LethalMaus / article4-vulnerable-minimal-signing-info.kt
Created July 11, 2026 21:23
Android Security Training article 4 vulnerable minimal signing info
override fun uidGidAndSignatureInfo(context: Context): String {
// Minimal info; no signing digest calculation
return "PID=${Process.myPid()} UID=${Process.myUid()}\npackage=${context.packageName}\n(signing digest not checked)"
}
@LethalMaus
LethalMaus / article4-secure-signer-digest-and-uid-info.kt
Created July 11, 2026 21:22
Android Security Training article 4 secure signer digest and UID info
override fun uidGidAndSignatureInfo(context: Context): String {
val pm = context.packageManager
val pkg = context.packageName
val signingBytes: ByteArray? = try {
@Suppress("DEPRECATION")
val pInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNING_CERTIFICATES)
pInfo.signingInfo?.apkContentsSigners?.firstOrNull()?.toByteArray()
} catch (t: Throwable) {
null
}
@LethalMaus
LethalMaus / article3-secure-signature-verification-and-dynamic-load-block.kt
Created July 11, 2026 21:22
Android Security Training article 3 secure signature verification and dynamic load block
override fun verifyExpectedSignature(context: Context): Boolean {
val actual = runCatching { signingCertSha256B64(context) }.getOrNull() ?: return false
val expected = EXPECTED_CERT_DIGEST_B64 // Release signing certificate SHA-256 (Base64 NO_WRAP)
return expected.isNotBlank() && actual == expected
}
override suspend fun tryDynamicDexLoad(context: Context, dexOrJarPath: String): String {
val path = if (dexOrJarPath.equals("self", ignoreCase = true)) context.packageCodePath else dexOrJarPath
return "Dynamic code loading is blocked by policy in secure builds (requested='$path')."
}