Ecosystem metrics

New Repos
8
down 68.0%
Commits
878
up 21.8%
Releases
11
up 120.0%
Contributors
59
up 28.3%
Merges
13
down 53.6%

Repository Explorer

10603 commits in all time May 14, 2026 09:26 – Aug 12, 2026 09:26 UTC
Reconstruct M from the artifact hash, not from the record header
Step [5] is the reviewer's "byte-exact reconstruction of the message M a
live inscription must have signed". It read the wrong bytes.

InscriptionRecord is an arc4.Struct, so the ARC4 head packs fixed-size
fields in declaration order:

  version         UInt8                  rec[0:1]
  cell_id         UInt64                 rec[1:9]
  artifact_hash   StaticArray[Byte,32]   rec[9:41]   <- the signed bytes
  inscribed_round UInt64                 rec[41:49]
  inscriber       Address                rec[49:81]
  payload_uri     DynamicBytes           rec[81:83] -> tail

The code used rec[0:32], which is version || cell_id || the first 23 bytes
of the hash. Confirmed against live TestNet cell 763809098: rec[0] == 1 and
rec[1:9] == 763809098, matching the box name exactly, so the layout is not
in doubt. The script displayed

  rec[0:32] = 01000000002d86cd4a5680fc4ddf9d331b585198239ab41bdc768e3192efc477
  rec[9:41] = 5680fc4ddf9d331b585198239ab41bdc768e3192efc477793a9daa1445dd4574

and rebuilt M from the first. No signature has ever covered those bytes.

It went unnoticed because the sole assertion was len(M_live) == 102, and
build_message validates both inputs are 32 bytes and then concatenates
fixed-width fields - so it either raises or returns exactly 102. The check
could not observe a wrong hash. Same shape as the approval-program pin
this branch already replaced: an assertion with no reachable failure.

Replaced with checks that can fail:
  - version == 1
  - the cell_id INSIDE the record equals the cell_id in the box NAME. Two
    independent sources for one claim, and the check that actually pins the
    offsets above. Mutation-tested: reading rec[0:8] instead of rec[1:9]
    yields "record 72057594040911565 vs box 763809098" and fails.
  - M matches the spec layout at every field offset, so a drift in
    build_message surfaces instead of being absorbed.

Note the tempting check is NOT sufficient: comparing M's embedded hash to
art32 would have passed under the old bug too, since both sides shift
together. That is why the layout is pinned by the cross-source comparison.

Also states plainly that M is reconstructed, not verified: the signature is
a call argument the AVM checks, and is not stored on-chain, so no local
signature verification is possible from box state alone.

Live: 17 passed, 1 failed (the failure is the deployment drift). Standalone,
without the committed artifact: 17 passed, 0 failed.

Found by an adversarial claim-vs-enforcement sweep (TCE-02).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Git Commit 24031544 Branch fix/non-circular-deployment-verification Document 1/30 ++ 4 --
Merge 609869bec3b88224002130546b9a4e827e6dae8d into 337211c9b279ae7ee811998064b3de3f0ced7f73
Git Commit cb992068 Branch pull/387/merge Document 2/11 ++ 19 --
Export the audited symbols from the Windows Falcon DLL
Adding the previous step revealed why the Windows leg was skipping: the
DLL built, linked and loaded with an EMPTY export table.

MSVC exports nothing from a DLL without __declspec(dllexport) or an
explicit /EXPORT, whereas ELF and Mach-O export every non-static symbol.
The upstream Falcon sources carry no dllexport annotations. Evidence from
the failing run: the linker never printed "Creating library", which MSVC
emits only when at least one symbol is exported.

So on Windows every ctypes lookup raised, _lib_available() caught it under
a bare `except Exception`, and the tests skipped with the reason
"FALCON_DET1024_LIB not built/set" - which was FALSE. The log shows the
variable set correctly to a real file that exists. The diagnostic named
the one thing that was not wrong.

Consequence: the Windows leg of the 3-OS byte-identity matrix has verified
nothing since it was written, while reporting green. The cross-platform
reproducibility claim it exists to support (reviewer Q11/Q7, and the
"byte-identical on Linux, macOS and Windows" language in the KAT header)
held on two platforms of the three it names.

S2.6 forbids editing the audited reference, so the exports are declared at
link time rather than by annotating the C sources. The four names are
exactly the SDK's audited binding surface, which makes the Windows export
table an enforcement of that allowlist: a binding added without a matching
export now fails loudly here.

Not reproducible locally - no MSVC on this machine - so CI is the
verification. The preceding step's grep is what will confirm it: if the
exports work, no test can report "FALCON_DET1024_LIB not" and the job
goes green having actually run the cryptography on Windows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Git Commit 8aea860f Branch fix/lib-gated-security-tests-never-run Document 1/22 ++ 1 --
Run the lib-gated security tests, which never ran in CI
Thirteen tests behind skipif(not _lib_available()) had never executed in
CI, on any event, since the workflow was written. The two jobs each had
half of what was needed and neither had both:

  wire-format    runs `pytest tests` (the whole suite) but never builds
                 the Falcon C library, so every lib-gated test skipped.
  signature-kat  builds the library on 3 OSes but ran only
                 `pytest tests/test_signature_kat.py`.
  testnet-e2e    builds the library, runs no pytest, and is manual-gated.

The intersection was empty. The never-run set is not incidental - it is
where the constitution's hardest crypto rules are actually enforced:

  test_seal_wipes_private_key_buffer             S2.3 zeroization
  test_worker_stdout_carries_only_public_values  S2.3 no secrets in output
  test_isolated_result_has_no_private_key
  test_isolated_require_locked_fails_closed_when_mlockall_unavailable
  test_bad_build_fails_closed_without_consuming_cell
  test_seal_signature_verifies_and_has_0xBA_header
  test_second_seal_of_same_cell_raises
  test_isolated_seal_produces_verifying_signature
  test_isolated_second_seal_raises
  + 3 signature fuzzers and 1 interop cross-verify

Every green CI run has reported success while the private-key
zeroization check and the secret-leak-to-stdout check did not run.

This adds one step to signature-kat, the only job that builds the
library, running the full suite there.

The grep is not belt-and-braces, it is the substance: without it a failed
library build silently returns all thirteen tests to "skipped" and the job
goes green again, reintroducing this exact defect in the exact place it
was removed from. Passing must require that they RAN, not merely that
nothing failed. Same reasoning as TRELYAN_REQUIRE_KAT one step above,
which was applied to the KAT and never extended to its neighbours.

set -o pipefail so the tee does not swallow pytest's exit code.

Found by an adversarial sweep for claims that nothing mechanically
enforces; this was the highest-severity survivor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Git Commit 6d7d771e Branch fix/lib-gated-security-tests-never-run Document 1/27 ++ 0 --
Make the Falcon "unreachable" risk acceptance enforceable
The pinned build (ce15e75b = tag v0.1.0, the release go-algorand vendors)
has a confirmed size_t underflow in falcon_det1024_convert_compressed_to_ct
giving an unbounded read. TRELYAN's documented position is accept-and-
document, and it rests on exactly one fact: the SDK never binds that
function. The pin is deliberately NOT bumped - ce15e75b is the network's
release, and the untagged fix commit would make TRELYAN stricter than the
deployed on-chain verifier for no reachable benefit.

That makes the acceptance only as durable as the binding surface, and
nothing was watching it. A later commit adding CT-format support would
convert a documented non-issue into a live out-of-bounds read silently.

sdk/tests/test_binding_surface.py derives the bound symbol set by parsing
the AST of _bind() and compares it to a declared allowlist. Note this is
NOT the tautology it resembles: the two sides come from independent sources
- one parsed from the source, one the security policy - so it can fail. A
constant compared against itself cannot. The correct response to a failure
is to justify the binding, not to edit the allowlist green.

A second test sweeps all shipped sources textually, catching dynamic access
(getattr(lib, ...)) that the AST check on _bind() alone would miss. A third
asserts the extraction itself works, so the guard cannot pass vacuously.

Static only - no shared library is loaded, so it runs in the no-native-lib
CI job.

Verified by mutation, not just by passing: injecting
lib.falcon_det1024_convert_compressed_to_ct into _bind() turns both guards
red with the quarantine reason attached; reverting turns them green. Full
SDK suite 24 passed / 18 skipped (skips are the native-lib tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Git Commit eefb222d Branch test/falcon-binding-surface-guard Document 1/154 ++ 0 --
Make deployment verification able to fail
The deployed application has not matched the committed contract since
2ec798e (2026-06-16), and nothing could observe it. Three defects combined:

1. ci.yml filtered on sdk/** only, so no change under contracts/ ever
   triggered CI. inscription.py was edited, merged and released without a
   single test run.
2. verify_trelyan.py pinned EXPECTED_APPROVAL_SHA512_256 - a constant copied
   from the deployed program - and compared it to the chain. The contract
   blocks Update/Delete (I1/I5), so the deployed bytecode is immutable and
   that comparison cannot fail. It was a tautology reported as a PASS, and
   the weekly schedule has been re-proving it every Monday since June.
3. The pin was recorded 2026-06-17, one day AFTER the divergence, so it
   captured the superseded value.

Changes:

- contracts/verify_deployment.py (new): derives the expected bytecode by
  assembling the committed TEAL artifact and compares it to the deployed
  program. No stored expected hash. Exit 1 = drift, exit 2 = could not
  check; an unreachable node must read as neither agreement nor drift, and
  an unexpected crash exits 2 rather than masquerading as a finding.
  --compile-url lets a reviewer split the trust so one endpoint does not
  both assemble and serve. --recompile re-derives the TEAL from
  inscription.py so the artifact is not trusted either.
- ci.yml: add contracts/** to the path filters; add the contract-drift job.
- verify_trelyan.py: separate the two claims that were conflated. The pinned
  constant now asserts only "the app was not replaced", which is what it can
  actually support. Source correspondence is checked properly when the
  committed artifact is present, and reported as NOT CHECKED when it is not,
  rather than being silently covered by the weaker check.

Verified against live TestNet: drift detected (exit 1, committed source
builds to 112fcad3 / 667 B, chain serves d24d9071 / 660 B). The MATCH path
is reachable and was proven separately by round-tripping the deployed
program through algod disassemble/assemble (exit 0, byte-identical).

contract-drift and verify-live are both expected to be RED until the
committed contract is redeployed. That red is the finding, not a broken job.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Git Commit d4e82888 Branch fix/non-circular-deployment-verification Document 4/259 ++ 9 --
Merge d952b8ee2105f52c40d6b397a76db4e061cd01d4 into b0a3e71a91adfd1dfb97b5060d054618c2a147aa
Git Commit 6cf91489 Branch pull/66/merge Document 10/1,149 ++ 1,264 --
chore(deps): Update all non-major dependencies
Git Commit d952b8ee Branch renovate/all-non-major-dependencies Document 10/1,149 ++ 1,264 --
JBScaled devportal
Merge abbda88afe997b8223bdb5a99f00ad76726533cb into 3373832646a00d4285576642c42c4776cbf71f24
Git Commit eb248832 Branch pull/631/merge Document 10/6,345 ++ 969 --
JBScaled devportal
fix: AVM versions typo
Git Commit abbda88a Branch feat/script-to-update-opcodes Document 1/1 ++ 1 --
Merge f86b979bac1da5e2e08e9ae7094ef6110b7e56a8 into 0e26b4b274a282ae273b68b29140379d39803971
Git Commit f2e9af4c Branch pull/606/merge Document 1/73 ++ 3 --
chore(deps-dev): bump js-yaml from 4.1.1 to 4.3.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.1 to 4.3.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.1/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.1...4.3.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Git Commit f86b979b Branch dependabot/npm_and_yarn/js-yaml-4.3.1 Document 1/73 ++ 3 --
Merge 07c02b794d45de4833b95f5186ca93bfaf60dd29 into 361d3066ffaca4241991cc6563403417bf562ecf
Git Commit c4b03155 Branch pull/23/merge Document 1/4,204 ++ 3,550 --
chore(deps): lock file maintenance
Git Commit 07c02b79 Branch renovate/lock-file-maintenance Document 1/4,204 ++ 3,550 --
Merge febd339f8fbf30c877566b6d575f0f5595d99c00 into 361d3066ffaca4241991cc6563403417bf562ecf
Git Commit 1af84dd0 Branch pull/32/merge Document 2/346 ++ 520 --
chore(deps): update commitlint monorepo to v21
Git Commit febd339f Branch renovate/major-commitlint-monorepo Document 2/346 ++ 520 --
Merge ae1969d7bebd846a94b2bdb2e98ce3d053ec5f09 into 361d3066ffaca4241991cc6563403417bf562ecf
Git Commit a7649b80 Branch pull/17/merge Document 4/3,363 ++ 1,954 --