Docs-only change (README.md, action.yml) implementing the model bit settled
on weblib-viewer#19: the builder signs, this repo only distributes.
action.yml's header comment no longer shows sign-apk.sh as a
default-flow step; its description: no longer advertises signing as
this action's headline job. action.yml itself never called any of the
scripts (it only exposes their path), so no behavioural change there --
only what the comments and description claim.
README: new intro paragraphs state the builder-signs/repo-distributes
model and, explicitly, that this repo is never handed an app signing
key -- only the repo index key -- with the sign-apk.sh exception
carved out by name.
README "Using it": the default pipeline example no longer includes the sign-apk.sh step; it moved into a new "The exception: a consumer whose
build does not already sign" subsection with its own snippet.
README "The repo index key is not the APK signing key": records that the
index key is, for now, the same keystore as the APK key but is expected
to split later (so the config/secret names already have to stay
distinct), and that the index key must be RSA 4096, never 2048 --
overriding F-Droid's own docs.
Does not touch publish.sh's ordering, its credential check, its
refuse-on-existing check, or next_version_code.py.
Test plan
bash run_tests.sh -- 98 passed / 4 skipped / 0 failed, matching the
documented offline baseline exactly (unaffected by a docs-only
change, run to confirm nothing else regressed).
Read through action.yml and README.md diffs for internal
consistency (no leftover reference to sign-apk.sh/APK_KEYSTORE in
the default flow).
Closes #9.
Docs-only change (README.md, action.yml) implementing the model bit settled
on weblib-viewer#19: the builder signs, this repo only distributes.
- `action.yml`'s header comment no longer shows `sign-apk.sh` as a
default-flow step; its `description:` no longer advertises signing as
this action's headline job. `action.yml` itself never called any of the
scripts (it only exposes their path), so no behavioural change there --
only what the comments and description claim.
- README: new intro paragraphs state the builder-signs/repo-distributes
model and, explicitly, that this repo is never handed an app signing
key -- only the repo index key -- with the `sign-apk.sh` exception
carved out by name.
- README "Using it": the default pipeline example no longer includes the
`sign-apk.sh` step; it moved into a new "The exception: a consumer whose
build does not already sign" subsection with its own snippet.
- README "The repo index key is not the APK signing key": records that the
index key is, for now, the same keystore as the APK key but is expected
to split later (so the config/secret *names* already have to stay
distinct), and that the index key must be RSA 4096, never 2048 --
overriding F-Droid's own docs.
Does not touch `publish.sh`'s ordering, its credential check, its
refuse-on-existing check, or `next_version_code.py`.
## Test plan
- [x] `bash run_tests.sh` -- 98 passed / 4 skipped / 0 failed, matching the
documented offline baseline exactly (unaffected by a docs-only
change, run to confirm nothing else regressed).
- [x] Read through `action.yml` and `README.md` diffs for internal
consistency (no leftover reference to `sign-apk.sh`/`APK_KEYSTORE` in
the default flow).
bit settled the model on weblib-viewer#19: the builder signs an APK, and
this repo only distributes it -- the same signature has to work whether the
APK reached a device via a git release or via F-Droid, and fdroid update
never creates a signature of its own. sign-apk.sh remains for a consumer
whose build genuinely produces an unsigned artifact, but action.yml's
header comment and the README's "Using it" example no longer show it as a
default-flow step, and both now say explicitly that this repo is never
handed an app signing key -- only the repo index key.
Also records two decisions that had nowhere to live yet: the index key's
config/secret names must stay distinct from the APK key's even while both
resolve to the same keystore for now (bit intends to split them later), and
the index key must be generated as RSA 4096, overriding F-Droid's own docs,
which suggest 2048.
Fixes#9.
Co-authored-by: bit <bit@das-labor.org>
98 passed, 4 skipped, 0 failed — re-run here, unchanged as expected for a docs-only change, but worth confirming rather than assuming a README edit cannot break anything. Secret scan of the diff clean.
The invariant is stated where someone adding a step will hit it, and — better — it says what a violation looks like:
A workflow change that starts passing an APK keystore or its password into this repo's scripts … is a sign the invariant has been broken
An invariant that only states the rule gets followed until someone has a reason not to. One that describes the symptom gets noticed.
Also right: fdroid-update.sh and sign-apk.sh take independently-named keystore arguments even though bit has said the index and APK keys are the same keystore for now. That is precisely so splitting them later is a value change and not a refactor, and the README says so.
The correction in the report is the useful part
I briefed this as "action.yml must not call sign-apk.sh". The agent checked and found it never did — action.yml only test -fs the scripts and outputs a path, exactly like weblib-ci's composite action. My premise was wrong.
The real defect was narrower and arguably worse: the documentation and the copy-pasteable example presented signing as a normal step. Nobody reads action.yml's internals; they copy the README block. So the thing that would have propagated the wrong model was the example, and that is what changed.
Worth recording because it generalises: for a composite action that only exposes a path, the README is the interface. Auditing the YAML would have found nothing wrong.
## Cold re-read. Merging.
**98 passed, 4 skipped, 0 failed** — re-run here, unchanged as expected for a docs-only change, but worth confirming rather than assuming a README edit cannot break anything. Secret scan of the diff clean.
The invariant is stated where someone adding a step will hit it, and — better — it says what a **violation looks like**:
> A workflow change that starts passing an APK keystore or its password into this repo's scripts … is a sign the invariant has been broken
An invariant that only states the rule gets followed until someone has a reason not to. One that describes the symptom gets noticed.
Also right: `fdroid-update.sh` and `sign-apk.sh` take **independently-named** keystore arguments even though bit has said the index and APK keys are the same keystore for now. That is precisely so splitting them later is a value change and not a refactor, and the README says so.
## The correction in the report is the useful part
I briefed this as "`action.yml` must not call `sign-apk.sh`". The agent checked and found **it never did** — `action.yml` only `test -f`s the scripts and outputs a path, exactly like weblib-ci's composite action. My premise was wrong.
The real defect was narrower and arguably worse: the **documentation and the copy-pasteable example** presented signing as a normal step. Nobody reads `action.yml`'s internals; they copy the README block. So the thing that would have propagated the wrong model was the example, and that is what changed.
Worth recording because it generalises: for a composite action that only exposes a path, *the README is the interface*. Auditing the YAML would have found nothing wrong.
claude
merged commit ec4d950e18 into main2026-09-09 12:42:12 +00:00
claude
deleted branch builder-signs-repo-distributes2026-09-09 12:42:12 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #9.
Docs-only change (README.md, action.yml) implementing the model bit settled
on weblib-viewer#19: the builder signs, this repo only distributes.
action.yml's header comment no longer showssign-apk.shas adefault-flow step; its
description:no longer advertises signing asthis action's headline job.
action.ymlitself never called any of thescripts (it only exposes their path), so no behavioural change there --
only what the comments and description claim.
model and, explicitly, that this repo is never handed an app signing
key -- only the repo index key -- with the
sign-apk.shexceptioncarved out by name.
sign-apk.shstep; it moved into a new "The exception: a consumer whosebuild does not already sign" subsection with its own snippet.
index key is, for now, the same keystore as the APK key but is expected
to split later (so the config/secret names already have to stay
distinct), and that the index key must be RSA 4096, never 2048 --
overriding F-Droid's own docs.
Does not touch
publish.sh's ordering, its credential check, itsrefuse-on-existing check, or
next_version_code.py.Test plan
bash run_tests.sh-- 98 passed / 4 skipped / 0 failed, matching thedocumented offline baseline exactly (unaffected by a docs-only
change, run to confirm nothing else regressed).
action.ymlandREADME.mddiffs for internalconsistency (no leftover reference to
sign-apk.sh/APK_KEYSTOREinthe default flow).
Cold re-read. Merging.
98 passed, 4 skipped, 0 failed — re-run here, unchanged as expected for a docs-only change, but worth confirming rather than assuming a README edit cannot break anything. Secret scan of the diff clean.
The invariant is stated where someone adding a step will hit it, and — better — it says what a violation looks like:
An invariant that only states the rule gets followed until someone has a reason not to. One that describes the symptom gets noticed.
Also right:
fdroid-update.shandsign-apk.shtake independently-named keystore arguments even though bit has said the index and APK keys are the same keystore for now. That is precisely so splitting them later is a value change and not a refactor, and the README says so.The correction in the report is the useful part
I briefed this as "
action.ymlmust not callsign-apk.sh". The agent checked and found it never did —action.ymlonlytest -fs the scripts and outputs a path, exactly like weblib-ci's composite action. My premise was wrong.The real defect was narrower and arguably worse: the documentation and the copy-pasteable example presented signing as a normal step. Nobody reads
action.yml's internals; they copy the README block. So the thing that would have propagated the wrong model was the example, and that is what changed.Worth recording because it generalises: for a composite action that only exposes a path, the README is the interface. Auditing the YAML would have found nothing wrong.