Ecosystem metrics

New Repos
27
up 8.0%
Commits
766
up 0.3%
Releases
9
up 125.0%
Contributors
60
up 22.4%
Merges
19
down 36.7%

Repository Explorer

10709 commits in all time May 12, 2026 19:36 – Aug 10, 2026 19:36 UTC
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))
Git Commit fbc9926b Branch main Document 1/13 ++ 0 --
Merge 49d40eeb4a52e1fedc5f9cb801a13cba87a9ec46 into 7d2d52615e262b1e35612c8890f0001f480f3758
Git Commit 502ea667 Branch pull/385/merge Document 13/906 ++ 296 --
Merge a3e3b1fe733d6eb7d1b8529f326f18494e6dcdf9 into b0a3e71a91adfd1dfb97b5060d054618c2a147aa
Git Commit 5ea57b2b Branch pull/66/merge Document 10/1,277 ++ 1,261 --
chore(deps): Update all non-major dependencies
Git Commit a3e3b1fe Branch renovate/all-non-major-dependencies Document 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>
Git Commit 2bb186e0 Branch main Document 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>
Git Commit bcaaab5e Branch main Document 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>
Git Commit 0271ada2 Branch pull/11/head Document 1/14 ++ 4 --
cce go-algorand
Merge 4fb7d5a74e855225413c33831502e171122cbad8 into 68e036affd9e62d0a64dcdb3f252eb0ee2e052d3
Git Commit ba9076ed Branch pull/6659/merge Document 13/2,549 ++ 168 --
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>
Git Commit a6fa1064 Branch security/env-hygiene Document 3/68 ++ 0 --
joe-p js-algorand-sdk
Merge efb12bf68ef57697270740cc8f19d6b6af7f2873 into d72c48ca0920788637c210c90f8b18a534bb2062
Git Commit ff2aa3f7 Branch pull/1124/merge Document 4/116 ++ 29 --
joe-p js-algorand-sdk
Merge branch 'main' into ci/beta-release
Git Commit efb12bf6 Branch ci/beta-release Document 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>
Git Commit 1d9b0187 Branch docs/threat-model-det-signing Document 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>
Git Commit abe58202 Branch main Document 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>
Git Commit fb92996c Branch pull/9/head Document 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>
Git Commit ad20b423 Branch main Document 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>
Git Commit ca986548 Branch ci/supply-chain-hardening Document 2/36 ++ 19 --
joe-p js-algorand-sdk
Merge branch 'main' into feat/pq
Git Commit 8f885fcb Branch feat/pq Document No file changes