Ecosystem metrics
- New Repos
- 27
- up 8.0%
- Commits
- 762
- down 0.5%
- Releases
- 9
- up 125.0%
- Contributors
- 60
- up 20.0%
- Merges
- 17
- down 46.9%
Activity Overview
Commits and releases over time
- Commits
- Releases
- Authors
Repository Explorer
No repositories match that filter.
10711 commits in all time
May 12, 2026 19:38 – Aug 10, 2026 19:38 UTC
Merge c1e4f98e2b8631b67cfdb30b69ca2d57b5049ca3 into 7d2d52615e262b1e35612c8890f0001f480f3758
e82de8c5
pull/385/merge
15/1,014 ++ 321 --
multiple viewer channel id handle for multiple viewer
c1e4f98e
pull/385/head
5/168 ++ 85 --
Notes added by 'git notes add'
3212f2a2
notes/semantic-release
1/1 ++ 0 --
chore: v2026.31.0 (release)
## [2026.31.0](https://github.com/michaeltchuang/a-day-in-my-bobalife/compare/v2026.30.0...v2026.31.0) (2026-08-10) ### Updates & Maintenance * log greeting (2026-08-04) ([fc03fd7](https://github.com/michaeltchuang/a-day-in-my-bobalife/commit/fc03fd78afdeb17b61ba4c72cb8eea91105c3e55)) * log greeting (2026-08-05) ([b2dc060](https://github.com/michaeltchuang/a-day-in-my-bobalife/commit/b2dc0607dc14660aa53700584ed440a4e657be2d)) * log greeting (2026-08-06) ([7a51aa9](https://github.com/michaeltchuang/a-day-in-my-bobalife/commit/7a51aa91b63d0cec65aa23ea85bcb306f02952bc)) * log greeting (2026-08-07) ([302f3ac](https://github.com/michaeltchuang/a-day-in-my-bobalife/commit/302f3aca1aa14b2e76231998b4ac8fe6e7ca693f)) * log greeting (2026-08-08) ([1983fbe](https://github.com/michaeltchuang/a-day-in-my-bobalife/commit/1983fbe80a09ad6595bd05619b73caacb69a1f51)) * log greeting (2026-08-09) ([6baba73](https://github.com/michaeltchuang/a-day-in-my-bobalife/commit/6baba735cf3be2945400293fc827fdaf68de013b)) * log greeting (2026-08-10) ([dced428](https://github.com/michaeltchuang/a-day-in-my-bobalife/commit/dced4288ce950b4492b94b7a5a582f3dce4a9cd0))
fbc9926b
main
1/13 ++ 0 --
Merge 49d40eeb4a52e1fedc5f9cb801a13cba87a9ec46 into 7d2d52615e262b1e35612c8890f0001f480f3758
502ea667
pull/385/merge
13/906 ++ 296 --
fix: push up authorizedSignerPublicKey debug tool fix
49d40eeb
pull/385/head
1/43 ++ 19 --
Merge a3e3b1fe733d6eb7d1b8529f326f18494e6dcdf9 into b0a3e71a91adfd1dfb97b5060d054618c2a147aa
5ea57b2b
pull/66/merge
10/1,277 ++ 1,261 --
chore(deps): Update all non-major dependencies
a3e3b1fe
renovate/all-non-major-dependencies
10/1,277 ++ 1,261 --
docs(threat-model): add the deterministic-signing key-extraction threat (#11)
* docs(threat-model): add the deterministic-signing key-extraction threat
Docs only. No code, contract, or crypto changed.
Sections 1-6 cover the ON-CHAIN trust surface: forgery, replay, ownership,
write-once. There is no entry anywhere for extracting the private key from
the signer itself - which is exactly what the known attack on derandomized
Falcon does, and the first thing a cryptographic reviewer will raise about
any deterministic Falcon deployment. Added as a dated addendum (section 7)
so the 1 June record stays intact.
Covers: the attack (Lin/Tibouchi/Yu/Zhang, EUROCRYPT 2025, eprint
2024/1709); why TRELYAN is unavoidably in scope (the AVM falcon_verify
opcode accepts only the deterministic form, so P1 cannot be avoided); a
precondition table with honest per-item status; and the controls ranked by
actual strength.
Two things stated plainly because an auditor will test them:
- The strongest control, fresh-key-per-seal, is NOT the deployed default:
keygen_sign_seal has no call sites outside sdk/tests/, while every
example, tutorial and deploy script uses the retained-key API.
- The repo over-credits FALCON_FPEMU=1. The paper is explicit that
exposure is possible even with integer-emulated FP because its
demonstrated discrepancy source is algorithmic (dynamic vs tree
signing), not FP rounding. What holds is the conjunction: FPEMU +
dyn-path-only + pinned tree + the UBSan gate. And the pin is a
build-time CI-only control - _load() does no runtime attestation, and
the seal's self-verification cannot catch an off-pin signer because an
off-pin signature is still a valid Falcon signature.
Also records the standards consequence: FN-DSA will only allow randomized
signing, so det1024 can never be FIPS 206 conformant as specified. Algorand
owns the identical problem for its opcode, so migration is coupled to their
roadmap. Public materials must not claim FIPS 206 conformance for the
deterministic path.
Scoped to avoid overstatement: signing DIFFERENT messages under one key is
not the attack; exposure needs an identical message re-signed under an
identical key across divergent evaluations. And the eprint PDF body returns
403, so the experimental section was not read - the addendum therefore makes
no numeric claim about the divergence rate, and says so.
Security Impact: documentation of an existing off-chain threat; no control
changed, nothing to re-KAT. It records that runtime signer attestation is
absent, and that the sealed path should become the documented default -
both are follow-up work, not shipped here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(threat-model): add caller-side retry as the most reachable P2 path
Surfaced by an independent multi-model review of the section added in
1d9b018, then verified against the source.
The addendum framed the "same (key, message) signed twice" precondition as
needing a deliberate re-inscription of an identical artifact. That
understated it. TrelyanInscriptionClient.inscribe() signs INTERNALLY
(inscription.py:136), so every call re-signs. A caller wrapping it in an
ordinary retry loop - network blip, fee spike - re-signs the identical
(privkey, cell_id, artifact_hash, genesis_hash), yielding an identical M.
Precondition P2 is then met by accident rather than by intent, which makes
it the most reachable path in the whole section.
Verified the SDK's own two-strategy submit is NOT affected: sig is computed
once at :136 and the fallback at :149 re-sends the same args tuple rather
than re-signing. The exposure is external retry, not internal fallback -
stating that precisely matters, because an auditor who checks :149 and
stops would wrongly conclude the whole class is handled.
Recorded fix: document that inscribe() must not be wrapped in a retry, and
provide a sign-once/submit-many entry point that caches the signed args.
Security Impact: documentation only; no control changed, nothing to re-KAT.
It widens a known threat's reachable surface and names the remediation.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Brandon Sellam <brandon.sellam@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2bb186e0
main
1/98 ++ 0 --
security: gitignore .env, add .env.example, and actually run gitleaks (#10)
Three gaps that compound into one real exposure. The repo's documented
deployment path uses DEPLOYER_MNEMONIC - an Algorand 25-word mnemonic,
i.e. a private key that controls its account outright - and:
1. `.env` was NOT gitignored. The .gitignore covered logs, __pycache__,
*.so and .DS_Store, but nothing named .env. A developer doing the
natural thing (put the mnemonic in .env) had nothing between them and
`git add .`. A committed mnemonic is an irrevocable disclosure: it is
in the history even after a later deletion.
2. There was no .env.example, so nothing told a developer which
variables exist, that one of them is a private key, or that the other
must be an absolute path.
3. .gitleaks.toml has existed since publication but NOTHING RAN IT - no
CI job, no pre-commit hook, no .pre-commit-config.yaml. Its only
references in the whole repo are itself and a SECURITY.md sentence
about allow-listing the KAT test vector. It was configuration without
enforcement, which reads as coverage that does not exist.
Constitution §5 requires exactly this: "Never hardcode mnemonics, private
keys, or API tokens. Environment/KMS only; .env is git-ignored." The
second half was not implemented here.
Changes:
- .gitignore: ignore .env and .env.* while explicitly un-ignoring
.env.example. Verified with `git check-ignore` that .env, .env.local
and .env.production are ignored and .env.example is not.
- .env.example: documents FALCON_DET1024_LIB (absolute path, why there
is deliberately no cwd-relative default - CWE-426, and why it must come
from the pinned FPEMU build), DEPLOYER_MNEMONIC (flagged in the
strongest terms as a private key, testnet-only, CI secret not file),
and TRELYAN_REQUIRE_KAT.
- ci.yml: new `secret-scan` job running gitleaks against .gitleaks.toml
with fetch-depth: 0, so full history is scanned rather than just the
diff and a secret introduced earlier is still caught. Action
SHA-pinned, consistent with the rest of the workflow.
No SDK, contract, or crypto source touched. Workflow YAML validated;
jobs: secret-scan, wire-format, verify-live, signature-kat, testnet-e2e.
Security Impact: closes the path by which an operational Algorand private
key could reach git history, and turns a dormant scanner config into an
enforced gate. Note this does NOT retroactively clean history - the new
job scans full history, so if it reports a pre-existing finding, treat
that as a real disclosure and rotate the affected credential rather than
allow-listing it.
Co-authored-by: Brandon Sellam <brandon.sellam@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
bcaaab5e
main
3/68 ++ 0 --
docs(threat-model): add caller-side retry as the most reachable P2 path
Surfaced by an independent multi-model review of the section added in 1d9b018, then verified against the source. The addendum framed the "same (key, message) signed twice" precondition as needing a deliberate re-inscription of an identical artifact. That understated it. TrelyanInscriptionClient.inscribe() signs INTERNALLY (inscription.py:136), so every call re-signs. A caller wrapping it in an ordinary retry loop - network blip, fee spike - re-signs the identical (privkey, cell_id, artifact_hash, genesis_hash), yielding an identical M. Precondition P2 is then met by accident rather than by intent, which makes it the most reachable path in the whole section. Verified the SDK's own two-strategy submit is NOT affected: sig is computed once at :136 and the fallback at :149 re-sends the same args tuple rather than re-signing. The exposure is external retry, not internal fallback - stating that precisely matters, because an auditor who checks :149 and stops would wrongly conclude the whole class is handled. Recorded fix: document that inscribe() must not be wrapped in a retry, and provide a sign-once/submit-many entry point that caches the signed args. Security Impact: documentation only; no control changed, nothing to re-KAT. It widens a known threat's reachable surface and names the remediation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0271ada2
pull/11/head
1/14 ++ 4 --
Merge 4fb7d5a74e855225413c33831502e171122cbad8 into 68e036affd9e62d0a64dcdb3f252eb0ee2e052d3
ba9076ed
pull/6659/merge
13/2,549 ++ 168 --
Merge 1d9b018759224897aff993fb5d8295ec2ce373fc into abe58202b6b795a4f917f90579e81a66910e6ec7
5f2a8b72
pull/11/merge
1/88 ++ 0 --
Merge a6fa1064357417baf89bb846342460eea24874f3 into abe58202b6b795a4f917f90579e81a66910e6ec7
053c44ed
pull/10/merge
3/68 ++ 0 --
security: gitignore .env, add .env.example, and actually run gitleaks
Three gaps that compound into one real exposure. The repo's documented
deployment path uses DEPLOYER_MNEMONIC - an Algorand 25-word mnemonic,
i.e. a private key that controls its account outright - and:
1. `.env` was NOT gitignored. The .gitignore covered logs, __pycache__,
*.so and .DS_Store, but nothing named .env. A developer doing the
natural thing (put the mnemonic in .env) had nothing between them and
`git add .`. A committed mnemonic is an irrevocable disclosure: it is
in the history even after a later deletion.
2. There was no .env.example, so nothing told a developer which
variables exist, that one of them is a private key, or that the other
must be an absolute path.
3. .gitleaks.toml has existed since publication but NOTHING RAN IT - no
CI job, no pre-commit hook, no .pre-commit-config.yaml. Its only
references in the whole repo are itself and a SECURITY.md sentence
about allow-listing the KAT test vector. It was configuration without
enforcement, which reads as coverage that does not exist.
Constitution §5 requires exactly this: "Never hardcode mnemonics, private
keys, or API tokens. Environment/KMS only; .env is git-ignored." The
second half was not implemented here.
Changes:
- .gitignore: ignore .env and .env.* while explicitly un-ignoring
.env.example. Verified with `git check-ignore` that .env, .env.local
and .env.production are ignored and .env.example is not.
- .env.example: documents FALCON_DET1024_LIB (absolute path, why there
is deliberately no cwd-relative default - CWE-426, and why it must come
from the pinned FPEMU build), DEPLOYER_MNEMONIC (flagged in the
strongest terms as a private key, testnet-only, CI secret not file),
and TRELYAN_REQUIRE_KAT.
- ci.yml: new `secret-scan` job running gitleaks against .gitleaks.toml
with fetch-depth: 0, so full history is scanned rather than just the
diff and a secret introduced earlier is still caught. Action
SHA-pinned, consistent with the rest of the workflow.
No SDK, contract, or crypto source touched. Workflow YAML validated;
jobs: secret-scan, wire-format, verify-live, signature-kat, testnet-e2e.
Security Impact: closes the path by which an operational Algorand private
key could reach git history, and turns a dormant scanner config into an
enforced gate. Note this does NOT retroactively clean history - the new
job scans full history, so if it reports a pre-existing finding, treat
that as a real disclosure and rotate the affected credential rather than
allow-listing it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a6fa1064
security/env-hygiene
3/68 ++ 0 --
Merge efb12bf68ef57697270740cc8f19d6b6af7f2873 into d72c48ca0920788637c210c90f8b18a534bb2062
ff2aa3f7
pull/1124/merge
4/116 ++ 29 --
Merge branch 'main' into ci/beta-release
efb12bf6
ci/beta-release
44/3,489 ++ 330 --
docs(threat-model): add the deterministic-signing key-extraction threat
Docs only. No code, contract, or crypto changed.
Sections 1-6 cover the ON-CHAIN trust surface: forgery, replay, ownership,
write-once. There is no entry anywhere for extracting the private key from
the signer itself - which is exactly what the known attack on derandomized
Falcon does, and the first thing a cryptographic reviewer will raise about
any deterministic Falcon deployment. Added as a dated addendum (section 7)
so the 1 June record stays intact.
Covers: the attack (Lin/Tibouchi/Yu/Zhang, EUROCRYPT 2025, eprint
2024/1709); why TRELYAN is unavoidably in scope (the AVM falcon_verify
opcode accepts only the deterministic form, so P1 cannot be avoided); a
precondition table with honest per-item status; and the controls ranked by
actual strength.
Two things stated plainly because an auditor will test them:
- The strongest control, fresh-key-per-seal, is NOT the deployed default:
keygen_sign_seal has no call sites outside sdk/tests/, while every
example, tutorial and deploy script uses the retained-key API.
- The repo over-credits FALCON_FPEMU=1. The paper is explicit that
exposure is possible even with integer-emulated FP because its
demonstrated discrepancy source is algorithmic (dynamic vs tree
signing), not FP rounding. What holds is the conjunction: FPEMU +
dyn-path-only + pinned tree + the UBSan gate. And the pin is a
build-time CI-only control - _load() does no runtime attestation, and
the seal's self-verification cannot catch an off-pin signer because an
off-pin signature is still a valid Falcon signature.
Also records the standards consequence: FN-DSA will only allow randomized
signing, so det1024 can never be FIPS 206 conformant as specified. Algorand
owns the identical problem for its opcode, so migration is coupled to their
roadmap. Public materials must not claim FIPS 206 conformance for the
deterministic path.
Scoped to avoid overstatement: signing DIFFERENT messages under one key is
not the attack; exposure needs an identical message re-signed under an
identical key across divergent evaluations. And the eprint PDF body returns
403, so the experimental section was not read - the addendum therefore makes
no numeric claim about the divergence rate, and says so.
Security Impact: documentation of an existing off-chain threat; no control
changed, nothing to re-KAT. It records that runtime signer attestation is
absent, and that the sealed path should become the documented default -
both are follow-up work, not shipped here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1d9b0187
docs/threat-model-det-signing
1/88 ++ 0 --
chore: stop committing build artifacts (they shipped the pre-fix SDK) (#9)
Pre-audit TF-04. sdk/dist/ held a wheel and sdist committed on 2026-06-16
(2ec798e). The SDK source has moved since - most recently eb67e4a
(2026-08-10), the TF-01/TF-02 load-path hardening - so the committed
artifacts were two months stale.
Concretely, not theoretically: unpacking the committed wheel shows
_DEFAULT_LIB_PATH = os.environ.get("FALCON_DET1024_LIB",
"./libfalcondet1024.so")
i.e. it still carries the cwd-relative shared-library default that TF-02
identified as CWE-426 and that eb67e4a removed. So the repo was shipping
a wheel containing a known-vulnerable load path, sitting next to fixed
source, under version 0.1.0 - the SAME version string as the artifact on
PyPI. Nothing about the version distinguished them, so
`pip install sdk/dist/*.whl` and `pip install trelyan-pq` were different
code claiming to be the same release.
Removed both artifacts and added dist/, build/, *.egg-info/ to
.gitignore with a note on why.
Nothing referenced them: no doc, workflow, or Makefile target points at
sdk/dist/, and release.yml builds its own artifacts fresh into
$GITHUB_WORKSPACE/dist - which is the only provenance-bearing path
(SLSA + cosign). Removing these therefore cannot affect a release.
SDK suite unchanged: 20 passed, 18 skipped.
Security Impact: no crypto, contract, or SDK source changed. Removes a
distributable that contained an already-fixed vulnerability under a
version number colliding with the published release. Anyone who
installed from the in-repo wheel should reinstall from PyPI or source;
the PyPI 0.1.0 artifact is unaffected by this commit and still predates
the TF-01/TF-02 fix - a release carrying that fix is the real remedy.
Co-authored-by: Brandon Sellam <brandon.sellam@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
abe58202
main
3/8 ++ 0 --
chore: stop committing build artifacts (they shipped the pre-fix SDK)
Pre-audit TF-04. sdk/dist/ held a wheel and sdist committed on 2026-06-16
(2ec798e). The SDK source has moved since - most recently eb67e4a
(2026-08-10), the TF-01/TF-02 load-path hardening - so the committed
artifacts were two months stale.
Concretely, not theoretically: unpacking the committed wheel shows
_DEFAULT_LIB_PATH = os.environ.get("FALCON_DET1024_LIB",
"./libfalcondet1024.so")
i.e. it still carries the cwd-relative shared-library default that TF-02
identified as CWE-426 and that eb67e4a removed. So the repo was shipping
a wheel containing a known-vulnerable load path, sitting next to fixed
source, under version 0.1.0 - the SAME version string as the artifact on
PyPI. Nothing about the version distinguished them, so
`pip install sdk/dist/*.whl` and `pip install trelyan-pq` were different
code claiming to be the same release.
Removed both artifacts and added dist/, build/, *.egg-info/ to
.gitignore with a note on why.
Nothing referenced them: no doc, workflow, or Makefile target points at
sdk/dist/, and release.yml builds its own artifacts fresh into
$GITHUB_WORKSPACE/dist - which is the only provenance-bearing path
(SLSA + cosign). Removing these therefore cannot affect a release.
SDK suite unchanged: 20 passed, 18 skipped.
Security Impact: no crypto, contract, or SDK source changed. Removes a
distributable that contained an already-fixed vulnerability under a
version number colliding with the published release. Anyone who
installed from the in-repo wheel should reinstall from PyPI or source;
the PyPI 0.1.0 artifact is unaffected by this commit and still predates
the TF-01/TF-02 fix - a release carrying that fix is the real remedy.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fb92996c
pull/9/head
3/8 ++ 0 --
CI: build the TestNet signer from the pinned Falcon source; SHA-pin actions (#8)
* docs: correct two stale claims an auditor would check first Docs only; no code, no contract, no crypto. Both corrections make claims weaker and more precise, never stronger. 1. "validated 20/20 on localnet" was stale in two ways The suite has 22 tests, not 20 (2ec798e, 2026-06-16 added two). More importantly that same commit changed contracts/inscription.py and regenerated the emitted TEAL, so the 2026-06-01 validation record predates the current contract. The 22-test suite has no recorded localnet run, and CI cannot supply one (no localnet in CI). The weekly verify-live job checks the deployed app's bytecode fingerprint against the committed TEAL. That proves the live app matches this tree; it does not re-run the functional suite. The docs conflated the two. LOCALNET_VALIDATION_2026-06-01.md is kept as the dated record it is and now carries a banner saying so. README, SECURITY, AUDIT_READINESS, CONTRIBUTING, ROADMAP and REVIEWER now date the 20/20 result and state the current suite size instead of implying a current pass. Deliberately NOT claiming "22/22": nothing has verified that. Someone must re-run the suite on localnet and supersede the record. 2. PINNED_BUILD.md said upstream had "been frozen for three years" True when written, false now: algorand/falcon resumed in June-July 2026 and the pin is several commits behind main. Replaced with a note naming the security-relevant delta (PR #16, merged 2026-07-01: trailing-byte malleability in convert_compressed_to_ct, and a size_t overflow ordering fix in verify_compressed), why on-chain consensus is unaffected while off-chain accept/reject can diverge, and that any pin bump must be gated on re-running the byte-identity KAT. SDK suite unchanged: 20 passed, 18 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * CI: build the TestNet signer from the pinned Falcon source; SHA-pin actions Two supply-chain gaps in the workflows (pre-audit TF-06, TF-07). CI config only; no SDK, contract, or crypto source touched. 1. testnet-e2e built its signer from an UNPINNED clone (TF-06) The job did `git clone --depth 1 https://github.com/algorand/falcon`, i.e. whatever the default branch happens to be, and then skipped the digest gate entirely - while every other job fetches the pinned ce15e75b tarball and runs sdk/ci/verify_pinned_digest.py first. This mattered more than it looks. The job SIGNS REAL TESTNET TRANSACTIONS (DEPLOYER_MNEMONIC, live inscribe). Upstream algorand/falcon was dormant 2023-06 to 2026-06 but resumed in June-July 2026, so the clone now resolves to a DIFFERENT commit than the pin - meaning this job was signing on-chain with a build nothing had verified, and whose behavior changes whenever upstream changes. For a deterministic signer, a silent sampler or encoding divergence is precisely the failure that must never go unnoticed. Now uses the same pinned tarball + digest/FPEMU gate as signature-kat. 2. Third-party actions were on mutable refs (TF-07) All actions pinned to full commit SHAs with the version in a trailing comment. The notable one: pypa/gh-action-pypi-publish was on `@release/v1` - a BRANCH ref, the weakest possible pin, on the job that publishes to PyPI. A branch moves on every push, so the code handling release artifacts could change with no change here. slsa-framework/slsa-github-generator is deliberately LEFT at @v2.1.0: its documentation states the generator "MUST be referenced by a tag of the form @vX.Y.Z, because the build will fail ... if you reference it by a hash." Pinning it by SHA would break provenance generation. Both workflow files validated with yaml.safe_load; job sets unchanged. Security Impact: no crypto or contract code changed. Strengthens the build/release supply chain: the TestNet signing job can no longer run an unverified Falcon build, and release-path actions can no longer change underneath a tag. Nothing to re-KAT - the pinned source and the goldens are unchanged. Worth re-checking that testnet-e2e still passes on its next manual dispatch, since its build directory moved from falcon/ to falcon-src/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Brandon Sellam <brandon.sellam@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ad20b423
main
10/81 ++ 36 --
Merge ca986548661ea958a495dd344a487b9d2c214825 into eb67e4ac9c62f4316ba9cd730cb56695fe8fcb2e
3c488924
pull/8/merge
10/81 ++ 36 --
CI: build the TestNet signer from the pinned Falcon source; SHA-pin actions
Two supply-chain gaps in the workflows (pre-audit TF-06, TF-07). CI config only; no SDK, contract, or crypto source touched. 1. testnet-e2e built its signer from an UNPINNED clone (TF-06) The job did `git clone --depth 1 https://github.com/algorand/falcon`, i.e. whatever the default branch happens to be, and then skipped the digest gate entirely - while every other job fetches the pinned ce15e75b tarball and runs sdk/ci/verify_pinned_digest.py first. This mattered more than it looks. The job SIGNS REAL TESTNET TRANSACTIONS (DEPLOYER_MNEMONIC, live inscribe). Upstream algorand/falcon was dormant 2023-06 to 2026-06 but resumed in June-July 2026, so the clone now resolves to a DIFFERENT commit than the pin - meaning this job was signing on-chain with a build nothing had verified, and whose behavior changes whenever upstream changes. For a deterministic signer, a silent sampler or encoding divergence is precisely the failure that must never go unnoticed. Now uses the same pinned tarball + digest/FPEMU gate as signature-kat. 2. Third-party actions were on mutable refs (TF-07) All actions pinned to full commit SHAs with the version in a trailing comment. The notable one: pypa/gh-action-pypi-publish was on `@release/v1` - a BRANCH ref, the weakest possible pin, on the job that publishes to PyPI. A branch moves on every push, so the code handling release artifacts could change with no change here. slsa-framework/slsa-github-generator is deliberately LEFT at @v2.1.0: its documentation states the generator "MUST be referenced by a tag of the form @vX.Y.Z, because the build will fail ... if you reference it by a hash." Pinning it by SHA would break provenance generation. Both workflow files validated with yaml.safe_load; job sets unchanged. Security Impact: no crypto or contract code changed. Strengthens the build/release supply chain: the TestNet signing job can no longer run an unverified Falcon build, and release-path actions can no longer change underneath a tag. Nothing to re-KAT - the pinned source and the goldens are unchanged. Worth re-checking that testnet-e2e still passes on its next manual dispatch, since its build directory moved from falcon/ to falcon-src/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ca986548
ci/supply-chain-hardening
2/36 ++ 19 --