Repository navigation
[Feature]: Finalize one-shot provisioning bundle and publish the next GitHub Release #6
Description
Activity
awatchar commented
on Aug 13, 2026 OwnerAuthorMore actionsImplemented the offline/code-complete portion in e3657bf7.
Provisioning workflow changes
- The only final
PASSis now emitted after Ready before reboot, reboot/return, the same Device ID, and Ready after reboot. -SkipRebootnow ends as explicitINCOMPLETEwith a non-zero exit instead of a false PASS.- Added Windows PowerShell 5.1-safe handling for
INSTALL_FAILED_UPDATE_INCOMPATIBLE, with actionable signature-mismatch guidance and no automatic uninstall/data clear. - Updated the operator flow to use tokenless six-character Device ID registration.
- Expanded documentation for supported hardware identities, T56 Location consent, checksum verification, recovery, and intentional manual safety boundaries.
Release workflow safeguards
- Added an exact allowlist for bundle files/directories.
- Rejects symlinks/non-regular entries, unsafe paths, duplicate or extra raw ZIP members, credential/signing paths, and high-confidence credential-like text in both staged and freshly extracted content.
- Ensures a fresh output ZIP and checksum.
- Release notes now include the supported-model matrix, physical-test status, known limitations, and an ancestor-safe generated change range.
- Sol High review approved these scoped changes.
Verification completed
- PowerShell AST parsing passed.
- Workflow YAML and all Bash
run:blocks parsed successfully. - Android local and GitHub CI gates passed.
- No tag or release was created.
Still required before closing
This issue remains open. We still need an actual protected signing/release workflow execution plus extracted-bundle smoke testing and physical provisioning on T56, T99, and RYKS, including same-ID Ready before/after reboot and model-specific PTT/audio/room-switching/Location acceptance. The next release must not be promoted as stable before those gates pass.
- The only final
T56 recovery acceptance — PASS (not a pristine one-shot)
A factory T56 provisioning attempt exposed two source-owned blockers. The reviewed fixes are published in draft PR #13 / commit 5545afc:
- Android 5.1 has no usable
un-as for the temporary Wi-Fi helper and does not reliably return nested ordered-broadcast JSON. The helper now uses a DUMP-protected exported receiver, non-exported Activity, nonce/path-bound request, fsynced private import/status, sanitized ASCII status markers, host deletion only after private import proof, and verified request/helper cleanup. - The radio config trial previously rolled back after the first generic connection error while Wi-Fi was connected. The bounded policy now retains/retries the first two transient connection errors, rejects the third, and still rejects server/other permanent errors immediately.
Automated/security verification
- Windows PowerShell 5.1 parser/security fixtures: passed.
- Wi-Fi helper Gradle build and merged manifest review: passed.
- Complete FOSS debug unit suite: passed.
- FOSS debug APK assembly: passed.
- No Wi-Fi credential, token, private config, or raw helper result was logged or committed.
Hardware evidence
- Hardware: UNIPRO / ZX, Android 5.1/API 22
- ADB serial: cc7e49d on port 5037; other models were never targeted
- Device ID created by Minimum: E7ROW7`n- Portal registration was performed by the operator; automation did not open or modify the Portal
- Managed config: active Device ID E7ROW7, config v14, pending=false, lastSuccessMs>0`n- Visible Ready marker verified before reboot
- Reboot target reidentified as the same cc7e49d UNIPRO/ZX with sys.boot_completed=1`n- Same Device ID/config and visible Ready verified after reboot
- Zello absent for user 0; Location remained device-only GPS; approved Wi-Fi reconnects; temporary helper and /data/local/tmp/minimum-wifi-*.json were absent
- Installed recovery APK SHA-256: 4A316203FEA998797D3225B2B2E4DF11D5CEE0BB6545C5336EE843C0A85C5712
n- Signing certificate SHA-256: 168F42ED412DA80ADAF27BED0984DBEE191168E9DF04F08AFA240A3F9DE45972n- Package/version: se.lublin.mumla, vc 3070300, 3.7.3-minimum.1-11-ge3657bf7-debug`n
Acceptance limitation
This is a successful recovery and same-ID pre/post-reboot acceptance on the originally factory T56, but it is not evidence of a pristine uninterrupted factory one-shot: earlier attempts had already installed Minimum and partially changed Wi-Fi/Location state before the final corrected run. Issue #6 therefore remains open. A clean extracted standalone bundle/release run plus the remaining profile/release gates in the issue are still required before stable promotion or closure.
- Android 5.1 has no usable
Integration completed
The reviewed T56 recovery fixes from draft PR #13 have passed all required pull-request checks and are now merged to main.
- PR: Harden T56 one-shot provisioning #13
- Reviewed branch commit: 5545afc
n- Merge commit now at GitHub main: �e08e6d5e9eee2a63ee497a1b78ce7623fc1dbf4n- Android tests, FOSS debug APK assembly, unsigned release assembly, and release lint: PASS - Portal tests, type-check, and production build: PASS
- Vercel status: PASS (portal source was unchanged; ignored-build behavior was expected)
The hardware result remains the same: recovered T56 cc7e49d / Device ID E7ROW7 reached visible Ready on active config v14 before reboot and returned to the same ID/config and visible Ready after reboot.
Issue #6 intentionally remains open. This merged recovery proves the corrected code path on the partially prepared T56, not an uninterrupted pristine factory run from an extracted standalone release bundle. The issue's remaining release/tag/artifact, clean-bundle smoke test, and any still-unclaimed device-profile acceptance gates must be completed before closure or stable promotion.
2026-08-14 release-readiness update
The updater/cellular integration merged through #14 as main commit
d4bbaf4be9432433994e7526d2efc0b040a767f6. PR CI and post-merge main CI run31726824727passed Android and portal jobs. The exact standalone bundle contract, checksums, package/version/signer verification, updater docs and T56 same-debug-signer physical acceptance are implemented.A signed
3.7.3-minimum.2prerelease was not tagged or dispatched. Security review found that GitHub environmentreleasecurrently has the required signing secrets andMINIMUM_RELEASE_APPLICATION_ID, but has no deployment protection rules or required reviewers. The repository currently has only one collaborator/admin, so an independent protected approval cannot be fabricated. This is a nonwaivable release-provenance gate.Remaining before prerelease:
- add an independent trusted reviewer/collaborator;
- configure the
releaseenvironment with required-reviewer protection and reviewed tag/branch policy; - independently review exact main commit/tag and dispatch inputs (
3.7.3-minimum.2, versionCode3070301, prerelease true); - validate all four published assets, checksums, exact one-signer binding and extracted bundle on the workstation;
- run only an official-signer
SIGNER_MISMATCHReportOnly/dry-run against E7ROW7—never install the release APK over its debug build; - retain T99/RYKS physical provisioning/updater limitations in prerelease notes.
This issue remains open and no stable promotion is claimed.
Prerelease tag audit (2026-08-14): the first annotated tag 3.7.3-minimum.2 (tag object d50d8ceb826c02ee76668b34989c0cfa7a75d3a9, peeled commit d4bbaf4) produced failed workflow run https://github.com/awatchar/minimum/actions/runs/31727479600. The run failed safely while packaging the standalone updater because PowerShell on Linux wrapped apksigner output; signing and identity verification had already passed. No GitHub Release or assets were created. PR #15 fixes and tests that cross-platform parser, was independently reviewed, and merged as 8ddf60a; PR and post-merge CI are green. Because the failed tag was never published as a Release and has no assets, I will now explicitly delete and recreate the same prerelease tag on exact main 8ddf60a, then rerun the protected signing workflow. This comment is the audit trail for that one-time ref replacement; it is not a stable-release promotion or a claim of an environment-required reviewer (the release environment currently has no enforced reviewer).
Second prerelease packaging audit (2026-08-14): workflow run https://github.com/awatchar/minimum/actions/runs/31728926851 on tag 3.7.3-minimum.2 at commit 8ddf60a again failed safely before publication. Signed build, APK signature/identity, updater tests, and helper build passed; extracted bundle verification exposed that PowerShell had already lost/wrapped apksigner stdout before the parser. No GitHub Release or assets exist. PR #16 replaces native stream adaptation with bounded raw Process capture, exact release-APK identity/signer integration coverage, concurrent stdout/stderr drains, timeout/tree cleanup, and injection-resistant platform-specific launch; it was independently reviewed and merged as cc9587a with green PR CI. I will wait for post-merge main CI, then explicitly replace the still-unpublished/no-assets annotated tag once more on exact cc9587a and rerun. The release environment reviewer-protection gap remains unchanged and disclosed.
Third prerelease workflow audit (2026-08-14): run https://github.com/awatchar/minimum/actions/runs/31730892695 on tag 3.7.3-minimum.2 at cc9587a failed safely in the newly strengthened updater test, before bundle construction or publication. The signed release build and independent Bash APK signature/identity verification passed; no GitHub Release or assets exist. The log identified two fixture/argv issues: the adversarial .bat test assumed Windows ComSpec on Ubuntu, and the extensionless Linux launcher still received a single reparsed Arguments string. The focused correction uses ProcessStartInfo.ArgumentList for exact Unix argv, validates unsafe .bat paths before checking ComSpec, and adds the real Linux debug APK/apksigner updater suite to ordinary PR/main CI so this path is proven before another signing run. The tag remains unchanged while that fix is reviewed and merged; any later no-assets tag replacement will again be explicit, not silent.
Prerelease rerun gate update (2026-08-14): PR #17's final reviewed signer contract is merged as 192ee37 and post-merge CI https://github.com/awatchar/minimum/actions/runs/31733710073 is green, including the ordinary-CI real Linux apksigner/debug-APK test. Verified PEM certificates are authoritative, the single anchored signer-count line must equal the unique PEM set, and any textual digest set must exactly match it. The existing unpublished tag object 481f95ec04436e3df37785c36f32214134812d3e still peels to cc9587a; no Release/assets exist. Per the prior failure audit, I will explicitly replace it on exact 192ee37 and rerun. This remains a prerelease with the already-disclosed missing enforced environment reviewer.
2026-08-20 PR #17 / signed prerelease audit
PR #17 is merged as
192ee37a146ad245cf5482656c410115ec1f82ce; its PR CI and post-merge CI passed. The protected signing workflow also completed successfully:- Release: https://github.com/awatchar/minimum/releases/tag/3.7.3-minimum.2
- Workflow: https://github.com/awatchar/minimum/actions/runs/31734123092
- Annotated tag peels to exact commit
192ee37a146ad245cf5482656c410115ec1f82ce - Dispatch contract: tag
3.7.3-minimum.2, expected versionCode3070301, prereleasetrue - Four expected assets are present: signed APK, APK checksum, standalone ZIP, ZIP checksum
A fresh download/extraction on the current project workstation passed the release contract: GitHub asset digests and published checksum hashes matched; the ZIP had exactly 19 reviewed raw members with no duplicates, unsafe paths, reparse points or credential-like text; the manifest had the exact 15-file allowlist and all hashes matched; the standalone and bundled APKs were identical; package
se.lublin.mumla, versionCode3070301, versionName/tag3.7.3-minimum.2, and exactly one manifest-bound release signer all verified.The audit found one packaging portability defect: the published ZIP checksum contains the correct hash but names the GitHub runner's absolute path. The published
.2tag/Release/assets were not mutated. PR #18 fixes future releases to emit and verify the exact asset basename; it merged as655d89234051c795176341808db19d93b1388d54, and post-merge CI https://github.com/awatchar/minimum/actions/runs/32347826798 passed.No radio is currently attached on either configured ADB server, so the release-signer
SIGNER_MISMATCHReportOnly/no-mutation gate on E7ROW7 cannot truthfully be claimed in this audit. No APK installation, reset, uninstall, clear-data, Portal mutation or hardware state change was attempted. Thereleaseenvironment also still has no enforced protection rules/reviewer. Therefore.2remains an immutable prerelease and this issue remains open; no stable promotion is claimed.
Problem to solve
Minimum should provide an operator-friendly one-shot provisioning package, similar to the provisioning workflow previously completed and verified for the T56.
The package should allow an operator to prepare a supported radio from a Windows workstation without requiring a complete source checkout, Android Studio, Gradle, or manual execution of multiple PowerShell scripts.
The completed application and provisioning tools should also be published together as versioned assets on the GitHub Releases page.
Existing implementation
The repository already contains the main components of this workflow:
Provision Minimum Device.cmdscripts/provision-minimum-device.ps1scripts/prepare-t56.ps1scripts/prepare-t99.ps1scripts/prepare-ryks.ps1docs/PROVISIONING_BUNDLE_README.txt.github/workflows/release-apk.ymlAn earlier prerelease,
3.7.3-minimum.1, already published a signed APK and provisioning ZIP.This Issue is therefore intended to:
Desired outcome
An operator should be able to:
Provision Minimum Device.cmd.Readystate.Ready.PASSor actionable failure message.The operator should not need a source checkout, Gradle, Android Studio, or manual knowledge of the individual provisioning scripts.
Supported device profiles
The one-shot launcher should support only explicitly approved hardware profiles:
UNIPRO / ZXYoudotech / QM011ELINK / ym_258Unknown or ambiguous hardware must be reported and rejected before APK installation or any provisioning change is performed.
Model-specific behavior must remain isolated. Hardware mappings, PTT rules, Location policy, and other settings must not be copied between device models without physical acceptance evidence.
Provisioning requirements
The one-shot provisioning workflow should:
5037and the existing Minimum lab port5041.Ready.PASSonly after post-rebootReadyverification succeeds.Standalone provisioning bundle
The GitHub Release should include a ZIP archive named using the release tag, for example:
The extracted bundle should contain at least:
The bundle must be self-contained for normal provisioning use and must not depend on files outside the extracted directory, except for documented workstation requirements such as Android Platform Tools.
GitHub Release requirements
Publish a new versioned GitHub Release from an exact reviewed tag.
The Release should contain:
minimum-<version>-foss.apkminimum-<version>-foss.apk.sha256minimum-provisioning-<version>.zipminimum-provisioning-<version>.zip.sha256The Release workflow should:
versionCode.versionNamematches the Git tag.Documentation requirements
Update the provisioning documentation so that an operator can complete the workflow without reading the source code.
The documentation should clearly explain:
PASSand common failure messages.Verification
Before publishing the Release:
Readybefore and after reboot.Acceptance criteria
Provision Minimum Device.cmdstarts the guided one-shot workflow by double-clicking.Readybefore reboot.Readyagain after reboot.PASSonly after all required checks succeed.Safety and security considerations