Owner decisions required. Four signature questions from the README 1.0
roadmap, with empty answer slots. Like the format questions, these freeze at
1.0 — a signature scheme cannot be changed without breaking every already
signed manifest.
7. Does the outer SHA-256 cover compressed or uncompressed data? The
code currently hashes the compressed bytes, which is good — it lets a
verifier check integrity before spending resources decompressing, which
matters given the decompression bomb surface. But this is not documented
anywhere.
Recommendation: keep hashing compressed data, and document it
explicitly. This is not really a decision so much as an undocumented
invariant that needs writing down before someone "fixes" it.
8. Should signatureString() sign raw bytes instead of a hex string?
The canonical string is currently MAGIC-UUID-MULTIHASH with hex encoding.
Signing the raw sha256 bytes, or the compressed innerMessage directly,
removes a transformation layer.
Recommendation: this is the one I would change. Every encoding layer
between the data and the signature is a place where two implementations
can disagree — and there is a second implementation planned in JavaScript.
A canonical string with hex encoding and delimiters has more ways to be
subtly wrong (case, delimiter, field order) than signing raw bytes does.
If the string form is kept for human debuggability, the spec must nail
down hex case and delimiter exactly.
9. Support detached .mf.sig files? Embedded signatures are better for
single-file distribution. Detached files follow the familiar SHASUMS/SHASUMS.asc pattern the README explicitly sets out to replace.
Recommendation: embedded only for 1.0. The README's stated goal is to
replace the detached-sidecar pattern; supporting both doubles the
verification surface and the test matrix to re-introduce the thing being
replaced. Detached support can be added post-1.0 additively if demand
appears.
10. GPG subprocess or pure-Go crypto? Shelling out to gpg is fragile:
it may not be installed, output is version-dependent, and it currently hangs
without a deadline (#62). Alternatives are github.com/ProtonMail/go-crypto
for pure-Go OpenPGP, or Ed25519/signify for something much simpler.
Recommendation: this is the highest-stakes question in the milestone and
deserves a real decision rather than a default. Shipping 1.0 with a hard
runtime dependency on an external gpg binary means the library does not
work in a FROM scratch container — which is what this repo's own
Dockerfile produces. Pure-Go OpenPGP keeps compatibility with existing PGP
keys and the ?key=FINGERPRINT URL idea in the README; Ed25519/signify is
dramatically simpler but abandons the PGP web of trust. I lean pure-Go
OpenPGP for compatibility, but if the web of trust is not actually valued
here, signify is a much smaller thing to own.
Definition of done
Each question answered inline in a comment here.
Question 10's answer becomes its own implementation issue if it is
anything other than "keep the subprocess" — it is a large change.
The final scheme is fully documented in docs/FORMAT.md: what is signed,
in what encoding, how a verifier reconstructs it, and how the public key
is embedded and located. The current documentation is insufficient for
anyone to write a second interoperable implementation, which is the
project's stated goal.
Please answer and reassign to clawbot.
Owner decisions required. Four signature questions from the README 1.0
roadmap, with empty answer slots. Like the format questions, these freeze at
1.0 — a signature scheme cannot be changed without breaking every already
signed manifest.
---
**7. Does the outer SHA-256 cover compressed or uncompressed data?** The
code currently hashes the compressed bytes, which is good — it lets a
verifier check integrity before spending resources decompressing, which
matters given the decompression bomb surface. But this is not documented
anywhere.
> _Recommendation:_ keep hashing compressed data, and document it
> explicitly. This is not really a decision so much as an undocumented
> invariant that needs writing down before someone "fixes" it.
**8. Should `signatureString()` sign raw bytes instead of a hex string?**
The canonical string is currently `MAGIC-UUID-MULTIHASH` with hex encoding.
Signing the raw sha256 bytes, or the compressed `innerMessage` directly,
removes a transformation layer.
> _Recommendation:_ this is the one I would change. Every encoding layer
> between the data and the signature is a place where two implementations
> can disagree — and there is a second implementation planned in JavaScript.
> A canonical string with hex encoding and delimiters has more ways to be
> subtly wrong (case, delimiter, field order) than signing raw bytes does.
> If the string form is kept for human debuggability, the spec must nail
> down hex case and delimiter exactly.
**9. Support detached `.mf.sig` files?** Embedded signatures are better for
single-file distribution. Detached files follow the familiar
`SHASUMS`/`SHASUMS.asc` pattern the README explicitly sets out to replace.
> _Recommendation:_ embedded only for 1.0. The README's stated goal is to
> replace the detached-sidecar pattern; supporting both doubles the
> verification surface and the test matrix to re-introduce the thing being
> replaced. Detached support can be added post-1.0 additively if demand
> appears.
**10. GPG subprocess or pure-Go crypto?** Shelling out to `gpg` is fragile:
it may not be installed, output is version-dependent, and it currently hangs
without a deadline (#62). Alternatives are `github.com/ProtonMail/go-crypto`
for pure-Go OpenPGP, or Ed25519/signify for something much simpler.
> _Recommendation:_ this is the highest-stakes question in the milestone and
> deserves a real decision rather than a default. Shipping 1.0 with a hard
> runtime dependency on an external `gpg` binary means the library does not
> work in a `FROM scratch` container — which is what this repo's own
> Dockerfile produces. Pure-Go OpenPGP keeps compatibility with existing PGP
> keys and the `?key=FINGERPRINT` URL idea in the README; Ed25519/signify is
> dramatically simpler but abandons the PGP web of trust. I lean pure-Go
> OpenPGP for compatibility, but if the web of trust is not actually valued
> here, signify is a much smaller thing to own.
---
## Definition of done
- Each question answered inline in a comment here.
- Question 10's answer becomes its own implementation issue if it is
anything other than "keep the subprocess" — it is a large change.
- The final scheme is fully documented in `docs/FORMAT.md`: what is signed,
in what encoding, how a verifier reconstructs it, and how the public key
is embedded and located. The current documentation is insufficient for
anyone to write a second interoperable implementation, which is the
project's stated goal.
Please answer and reassign to `clawbot`.
clawbot
added this to the 1.0.0 milestone 2026-08-09 03:44:20 +02:00
sneak
was assigned by clawbot2026-08-09 03:44:20 +02:00
Context for question 8, found while reviewing the tree for #99:
FORMAT.md says the third component of the canonical string is "the hex-encoded SHA-256 hash from the outer message". The code (mfer/manifest.go, signatureString) hex-encodes the multihash encoding of that hash, so the string carries a 1220 prefix before the 64 hex digits. The spec and the implementation already disagree, which is the interoperability risk the recommendation describes. Whichever way question 8 goes, the answer should say which of the two is the format, and #84 will write it down.
Model: fable-5-1
Context for question 8, found while reviewing the tree for https://git.eeqj.de/sneak/mfer/issues/99:
`FORMAT.md` says the third component of the canonical string is "the hex-encoded SHA-256 hash from the outer message". The code (`mfer/manifest.go`, `signatureString`) hex-encodes the *multihash* encoding of that hash, so the string carries a `1220` prefix before the 64 hex digits. The spec and the implementation already disagree, which is the interoperability risk the recommendation describes. Whichever way question 8 goes, the answer should say which of the two is the format, and https://git.eeqj.de/sneak/mfer/issues/84 will write it down.
Model: fable-5-1
these are DUMB questions. of course the hash is over compressed bytes. signaturebytes is over a multihash intentionally, the multi-implementation issue is overblown and is a non issue. this entire project exists to eradicate detached signature files. why would we EVER shell out when pure go crypto exists???
these are DUMB questions. of course the hash is over compressed bytes. signaturebytes is over a multihash intentionally, the multi-implementation issue is overblown and is a non issue. this entire project exists to eradicate detached signature files. why would we EVER shell out when pure go crypto exists???
Ruling (sneak, 2026-10-07, above), all four questions:
7: the outer SHA-256 covers the compressed bytes, as the code already does. docs/FORMAT.md says so explicitly.
8: the signature is over the multihash, intentionally; it does not change. The worry about a second implementation disagreeing is not a concern. Where docs/FORMAT.md and the code disagree (the code hex-encodes the multihash, 1220 prefix included), the document is corrected to describe the code.
9: embedded signatures only, never detached .mf.sig files: removing detached signature files is why this project exists.
10: pure Go crypto, never a gpg subprocess. Between the two pure-Go options he named none, so the recommendation stands: pure-Go OpenPGP, which keeps existing PGP keys and the README's key-fingerprint URL.
Reassigned to clawbot: question 10 becomes its own implementation unit, as the definition of done above says, and the docs/FORMAT.md corrections land with the work that writes the final format down (#84).
Model: opus-5-5
Ruling (sneak, 2026-10-07, above), all four questions:
- 7: the outer SHA-256 covers the compressed bytes, as the code already does. `docs/FORMAT.md` says so explicitly.
- 8: the signature is over the multihash, intentionally; it does not change. The worry about a second implementation disagreeing is not a concern. Where `docs/FORMAT.md` and the code disagree (the code hex-encodes the multihash, `1220` prefix included), the document is corrected to describe the code.
- 9: embedded signatures only, never detached `.mf.sig` files: removing detached signature files is why this project exists.
- 10: pure Go crypto, never a `gpg` subprocess. Between the two pure-Go options he named none, so the recommendation stands: pure-Go OpenPGP, which keeps existing PGP keys and the README's key-fingerprint URL.
Reassigned to clawbot: question 10 becomes its own implementation unit, as the definition of done above says, and the `docs/FORMAT.md` corrections land with the work that writes the final format down (https://git.eeqj.de/sneak/mfer/issues/84).
Model: opus-5-5
sneak
was unassigned by clawbot2026-10-07 23:17:44 +02:00
clawbot
self-assigned this 2026-10-07 23:17:44 +02:00
Every answer is tracked: question 10 is the pure-Go OpenPGP signing work (#181), and the docs/FORMAT.md corrections for questions 7 to 9 are in the specification work (#84 (comment)). Closing.
Model: opus-5-5
Every answer is tracked: question 10 is the pure-Go OpenPGP signing work (https://git.eeqj.de/sneak/mfer/issues/181), and the `docs/FORMAT.md` corrections for questions 7 to 9 are in the specification work (https://git.eeqj.de/sneak/mfer/issues/84#issuecomment-132674). Closing.
Model: opus-5-5
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.
Owner decisions required. Four signature questions from the README 1.0
roadmap, with empty answer slots. Like the format questions, these freeze at
1.0 — a signature scheme cannot be changed without breaking every already
signed manifest.
7. Does the outer SHA-256 cover compressed or uncompressed data? The
code currently hashes the compressed bytes, which is good — it lets a
verifier check integrity before spending resources decompressing, which
matters given the decompression bomb surface. But this is not documented
anywhere.
8. Should
signatureString()sign raw bytes instead of a hex string?The canonical string is currently
MAGIC-UUID-MULTIHASHwith hex encoding.Signing the raw sha256 bytes, or the compressed
innerMessagedirectly,removes a transformation layer.
9. Support detached
.mf.sigfiles? Embedded signatures are better forsingle-file distribution. Detached files follow the familiar
SHASUMS/SHASUMS.ascpattern the README explicitly sets out to replace.10. GPG subprocess or pure-Go crypto? Shelling out to
gpgis fragile:it may not be installed, output is version-dependent, and it currently hangs
without a deadline (#62). Alternatives are
github.com/ProtonMail/go-cryptofor pure-Go OpenPGP, or Ed25519/signify for something much simpler.
Definition of done
anything other than "keep the subprocess" — it is a large change.
docs/FORMAT.md: what is signed,in what encoding, how a verifier reconstructs it, and how the public key
is embedded and located. The current documentation is insufficient for
anyone to write a second interoperable implementation, which is the
project's stated goal.
Please answer and reassign to
clawbot.Context for question 8, found while reviewing the tree for #99:
FORMAT.mdsays the third component of the canonical string is "the hex-encoded SHA-256 hash from the outer message". The code (mfer/manifest.go,signatureString) hex-encodes the multihash encoding of that hash, so the string carries a1220prefix before the 64 hex digits. The spec and the implementation already disagree, which is the interoperability risk the recommendation describes. Whichever way question 8 goes, the answer should say which of the two is the format, and #84 will write it down.Model: fable-5-1
these are DUMB questions. of course the hash is over compressed bytes. signaturebytes is over a multihash intentionally, the multi-implementation issue is overblown and is a non issue. this entire project exists to eradicate detached signature files. why would we EVER shell out when pure go crypto exists???
Ruling (sneak, 2026-10-07, above), all four questions:
docs/FORMAT.mdsays so explicitly.docs/FORMAT.mdand the code disagree (the code hex-encodes the multihash,1220prefix included), the document is corrected to describe the code..mf.sigfiles: removing detached signature files is why this project exists.gpgsubprocess. Between the two pure-Go options he named none, so the recommendation stands: pure-Go OpenPGP, which keeps existing PGP keys and the README's key-fingerprint URL.Reassigned to clawbot: question 10 becomes its own implementation unit, as the definition of done above says, and the
docs/FORMAT.mdcorrections land with the work that writes the final format down (#84).Model: opus-5-5
Every answer is tracked: question 10 is the pure-Go OpenPGP signing work (#181), and the
docs/FORMAT.mdcorrections for questions 7 to 9 are in the specification work (#84 (comment)). Closing.Model: opus-5-5