android: build the shape a store takes, and target 36 - #1
Open
NoxToxCipher wants to merge 3 commits into
Open
Conversation
Everything on the Accrescent path that does not need the domain first. Target SDK 36. A store sets this floor, not us: Accrescent follows Google Play's target API policy, and from 31 August 2026 a new submission must target 36. Two things follow, and neither is left to be discovered on a handset. The first is 16 KB memory pages. An app targeting 35 or above has to load its native library on devices whose page size is 16 KB, so the .so is linked with max-page-size=16384, the archive is aligned with `zipalign -P 16` (which is why build-tools moves to 36.0.0), the manifest asks for the library to be mapped in place rather than unpacked, and the result is checked rather than assumed. The second is edge to edge. Android 15 lays every app out under the status and navigation bars and ignores the theme colours for them, which would have put the header behind the clock. The activity now reads the window insets and pads by them, with no support library. build-bundle.sh is new: a store takes an APK set from bundletool, not an APK, so this links the resources in proto form, assembles the bundle module by hand and has bundletool split and sign it. Still no Gradle. It refuses the debug key, checks bundletool's version against the published floor, and before claiming success verifies every APK in the set for 16 KB alignment and a valid signature, the set against the 128 MiB ceiling, and reports any that still carry a build timestamp. Both builds take the release key from the environment and let the tools ask for the passphrase, so it need not sit in a shell history. Version, SDK levels and the ABI list move into config.sh so the two builds cannot disagree about what they built. zip-time.py was only half doing its job. Flattening the DOS timestamps leaves Info-ZIP's 0x5455 extra field (and NTFS 0x000A) holding the same clock to the second, and `unzip -l` shows those in preference, so an archive could read as clean while still carrying the build time and the builder's UTC offset. Both are zeroed now, and --check reports what a signed archive cannot have patched. Still blocked on the app ID: the store verifies a domain matching it, and org.crake.metascrub means crake.org. That is permanent once published, so the name settles before the first upload. README carries the full state.
A listing needs a 512x512 PNG, the one piece of app art that cannot stay a vector. Drawing it separately would leave two copies of the mark that nobody notices have drifted until the store icon stops matching the icon on the phone, so it is rendered from the drawable the launcher already uses, on the adaptive icon's own background colour. Full bleed, not masked: a launcher applies its own shape and so does a store, and an icon that arrives pre-rounded gets rounded twice.
Kept in the repository rather than typed into a web form once, so it can be read like anything else and so the next store gets the same words. The listing says what the app refuses to claim, not only what it does: the three results and what each one means, video and audio being named but not cleaned, and the three things it cannot do at all. A store listing is the first place a tool like this can overstate itself, and it is the one place nobody would check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Everything on the Accrescent path that does not need the domain first.
Target SDK 36, and the two things that follow
A store sets this floor, not us: Accrescent follows Google Play's target API policy, and from 31 August 2026 a new submission must target 36. Neither consequence is left to be found on a handset.
16 KB memory pages. An app targeting 35 or above has to load its native library on devices whose page size is 16 KB. The
.sois linked withmax-page-size=16384, the archive is aligned withzipalign -P 16(which is why build-tools moves to 36.0.0), the manifest declaresextractNativeLibs="false"so the library is mapped in place rather than unpacked, and the result is checked rather than assumed.Edge to edge. Android 15 lays every app out under the status and navigation bars and ignores the theme colours for them, which would have put the header behind the clock. The activity reads the window insets and pads by them. No support library.
build-bundle.sh
A store takes an APK set from bundletool, not an APK. This links the resources in proto form, assembles the bundle module by hand, and has bundletool split and sign it. Still no Gradle: a bundle is a zip in a documented layout plus one tool invocation.
Before it claims success it verifies every APK in the set for 16 KB alignment and a valid signature, the set against the 128 MiB ceiling, and reports any that still carry a build timestamp. It refuses the debug key and checks bundletool's version against the published floor.
Both builds take the release key from the environment and let the tools ask for the passphrase, so it need not sit in a shell history. Version, SDK levels and the ABI list move into
config.shso the two builds cannot disagree about what they built.zip-time.py was only half doing its job
Flattening the DOS timestamps leaves Info-ZIP's
0x5455extra field (and NTFS0x000A) holding the same clock to the second, andunzip -lshows those in preference. An archive could read as clean while still carrying the build time, and with it the builder's UTC offset. Both are zeroed now, and--checkreports what a signed archive cannot have patched.The listing icon
Generated from the launcher drawable on the adaptive icon's own background, so the icon in a store cannot drift from the icon on the phone. Full bleed, since a launcher and a store each apply their own shape.
What is verified, and what is not
zip-time.pywas run against Info-ZIP,zip -Xandjararchives: byte length preserved, integrity intact, idempotent, no clock left in either field. The icon was rendered and inspected. The build scripts passbash -nbut have not been run against a real SDK, so the first run on the build machine is the test.armeabi-v7aremains untested on 32-bit hardware.Still blocked
The app ID. Accrescent verifies a domain matching it, so
org.crake.metascrubrequirescrake.org, and the ID is permanent once published. The name settles before the first upload.android/README.mdcarries the full state, including what Google's September 2026 developer verification means for a pseudonymous release.🤖 Generated with Claude Code
https://claude.ai/code/session_01VKf7mRc9hJhG2xhvLKGH8n
Generated by Claude Code