Skip to content

Commit 5e8787f

Browse files
hyperpolymathclaude
andcommitted
chore: sync local changes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 06b2ad9 commit 5e8787f

10 files changed

Lines changed: 1056 additions & 0 deletions
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
name: ECHIDNA Validation
3+
4+
on:
5+
push:
6+
paths:
7+
- 'services/*/src/**'
8+
- 'cli/**'
9+
- 'opsm_ex/native/**'
10+
- '.github/workflows/echidna-validation.yml'
11+
pull_request:
12+
paths:
13+
- 'services/**'
14+
- 'cli/**'
15+
- 'opsm_ex/native/**'
16+
schedule:
17+
- cron: '0 6 * * 1' # Weekly on Monday at 06:00 UTC
18+
19+
permissions: read-all
20+
21+
jobs:
22+
echidna-audit:
23+
name: ECHIDNA Safety Audit
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Checkout code
27+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
28+
29+
- name: Install Rust toolchain
30+
uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable
31+
with:
32+
components: clippy
33+
34+
- name: Cache Rust dependencies
35+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
36+
37+
- name: Unsafe audit
38+
run: |
39+
echo "=== Unsafe Code Audit ==="
40+
UNSAFE_COUNT=0
41+
for dir in services/*/src cli/src opsm_ex/native/*/src; do
42+
if [ -d "$dir" ]; then
43+
COUNT=$(grep -rn "unsafe" "$dir" --include="*.rs" 2>/dev/null | grep -v "// SAFETY:" | wc -l || echo 0)
44+
if [ "$COUNT" -gt 0 ]; then
45+
echo "WARNING: $dir has $COUNT unsafe blocks without SAFETY comments"
46+
grep -rn "unsafe" "$dir" --include="*.rs" 2>/dev/null | grep -v "// SAFETY:"
47+
UNSAFE_COUNT=$((UNSAFE_COUNT + COUNT))
48+
fi
49+
fi
50+
done
51+
echo "Total unsafe without SAFETY comment: $UNSAFE_COUNT"
52+
echo "unsafe_count=$UNSAFE_COUNT" >> $GITHUB_OUTPUT
53+
54+
- name: Dangerous pattern scan
55+
run: |
56+
echo "=== Dangerous Pattern Scan ==="
57+
ISSUES=0
58+
for pattern in "transmute" "std::mem::forget" "Box::from_raw" "std::ptr::null"; do
59+
FOUND=$(grep -rn "$pattern" services/*/src cli/src opsm_ex/native/*/src --include="*.rs" 2>/dev/null | wc -l || echo 0)
60+
if [ "$FOUND" -gt 0 ]; then
61+
echo "CRITICAL: Found $FOUND instances of '$pattern'"
62+
grep -rn "$pattern" services/*/src cli/src opsm_ex/native/*/src --include="*.rs" 2>/dev/null
63+
ISSUES=$((ISSUES + FOUND))
64+
fi
65+
done
66+
echo "Total dangerous patterns: $ISSUES"
67+
if [ "$ISSUES" -gt 0 ]; then
68+
echo "WARNING: Dangerous patterns detected — review required"
69+
fi
70+
71+
- name: Clippy strict analysis
72+
run: |
73+
for dir in services/*/; do
74+
if [ -f "$dir/Cargo.toml" ]; then
75+
echo "=== Clippy: $dir ==="
76+
cd "$dir"
77+
cargo clippy -- -D warnings -W clippy::pedantic 2>&1 || true
78+
cd "$GITHUB_WORKSPACE"
79+
fi
80+
done
81+
82+
- name: Summary
83+
run: |
84+
echo "## ECHIDNA Validation Results" >> $GITHUB_STEP_SUMMARY
85+
echo "" >> $GITHUB_STEP_SUMMARY
86+
echo "- Scanned: services/, cli/, opsm_ex/native/" >> $GITHUB_STEP_SUMMARY
87+
echo "- Checks: unsafe audit, dangerous patterns, clippy strict" >> $GITHUB_STEP_SUMMARY
88+
echo "" >> $GITHUB_STEP_SUMMARY
89+
echo "*Powered by ECHIDNA property-based verification*" >> $GITHUB_STEP_SUMMARY

.hypatia/activity.jsonl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"timestamp":"2026-03-08T02:04:58Z","bot":"hypatia-autofix","action":"scan","details":"fixes=5"}

.hypatia/last-visit.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"last_visit": "2026-03-08T02:04:58Z",
3+
"last_bot": "hypatia-autofix",
4+
"last_action": "scan",
5+
"visits_total": 1
6+
}

.tool-versions

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Pinned runtime versions for OPSM
3+
# Managed via asdf (https://asdf-vm.com)
4+
elixir 1.19.5-otp-28
5+
erlang 28.3.1
6+
# Note: Rust managed via asdf global (nightly). Not pinned here to avoid
7+
# conflicting with cargo-audit and other cargo subcommands.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# PQ Crypto Standards Tracking
3+
4+
Tracks post-quantum cryptographic algorithm standardization status and OPSM's
5+
migration path from draft names to final NIST standard names.
6+
7+
Author: Jonathan D.A. Jewell
8+
Last updated: 2026-03-10
9+
10+
## Current Algorithms in OPSM
11+
12+
OPSM implements three post-quantum algorithms via Rust NIFs
13+
(`opsm_ex/native/opsm_pq_nif/src/lib.rs` and `opsm_ex/native/pq_crypto/src/lib.rs`):
14+
15+
| Algorithm (Code) | NIST Standard Name | FIPS | Purpose | Security Level |
16+
|-------------------|--------------------|------|---------|----------------|
17+
| Dilithium5 | **ML-DSA-87** | FIPS 204 | Digital signatures | Category 5 |
18+
| Kyber-1024 | **ML-KEM-1024** | FIPS 203 | Key encapsulation | Category 5 |
19+
| SPHINCS+-256f | **SLH-DSA-SHAKE-256f** | FIPS 205 | Hash-based signatures (fallback) | Category 5 |
20+
21+
## NIST Standardization Status
22+
23+
| Standard | Status | Published | Notes |
24+
|----------|--------|-----------|-------|
25+
| FIPS 203 (ML-KEM) | **Final** | August 2024 | Replaces CRYSTALS-Kyber |
26+
| FIPS 204 (ML-DSA) | **Final** | August 2024 | Replaces CRYSTALS-Dilithium |
27+
| FIPS 205 (SLH-DSA) | **Final** | August 2024 | Replaces SPHINCS+ |
28+
29+
All three standards were published as final on 13 August 2024. The draft
30+
names (Dilithium, Kyber, SPHINCS+) are superseded by the official NIST
31+
names (ML-DSA, ML-KEM, SLH-DSA).
32+
33+
## Rust Crate Status
34+
35+
### Current crates (used by OPSM)
36+
37+
| Crate | Version | Status | Advisory |
38+
|-------|---------|--------|----------|
39+
| `pqcrypto-dilithium` | 0.5.x | **Unmaintained** | RUSTSEC-2024-0380 — replaced by `pqcrypto-mldsa` |
40+
| `pqcrypto-kyber` | 0.8.x | **Unmaintained** | RUSTSEC-2024-0381 — replaced by `pqcrypto-mlkem` |
41+
| `pqcrypto-sphincsplus` | 0.7.x | Active | No advisory yet, but SLH-DSA crate expected |
42+
| `pqcrypto-traits` | 0.3.x | Active | Common trait definitions |
43+
| `rustler` | 0.35.x | Active | NIF bridge; 0.37.x available |
44+
45+
### Migration target crates
46+
47+
| New Crate | Replaces | Notes |
48+
|-----------|----------|-------|
49+
| `pqcrypto-mldsa` | `pqcrypto-dilithium` | FIPS 204 final standard names |
50+
| `pqcrypto-mlkem` | `pqcrypto-kyber` | FIPS 203 final standard names |
51+
| `pqcrypto-slhdsa` | `pqcrypto-sphincsplus` | FIPS 205 final standard names (when available) |
52+
53+
### Alternative implementations
54+
55+
| Crate | Notes |
56+
|-------|-------|
57+
| `oqs` / `oqs-sys` | liboqs bindings; covers all algorithms but adds C dependency |
58+
| `ml-kem` | Pure Rust ML-KEM from RustCrypto project |
59+
| `ml-dsa` | Pure Rust ML-DSA from RustCrypto project |
60+
| `slh-dsa` | Pure Rust SLH-DSA from RustCrypto project |
61+
62+
The RustCrypto pure-Rust implementations (`ml-kem`, `ml-dsa`, `slh-dsa`) are
63+
preferable long-term as they avoid C build dependencies and use the final
64+
NIST standard names natively.
65+
66+
## Migration Plan
67+
68+
### Phase 1: Cargo.toml updates (Target: Q2 2026)
69+
70+
Replace deprecated crates in both NIF locations:
71+
72+
```toml
73+
# Before (deprecated)
74+
pqcrypto-dilithium = "0.5"
75+
pqcrypto-kyber = "0.8"
76+
77+
# After (NIST standard names)
78+
pqcrypto-mldsa = "0.1" # or ml-dsa from RustCrypto
79+
pqcrypto-mlkem = "0.1" # or ml-kem from RustCrypto
80+
```
81+
82+
### Phase 2: API name migration (Target: Q2 2026)
83+
84+
Update Rust source to use NIST standard function/type names:
85+
86+
| Current (draft) | Target (final) |
87+
|-----------------|----------------|
88+
| `dilithium5::keypair()` | `mldsa87::keypair()` |
89+
| `dilithium5::sign()` | `mldsa87::sign()` |
90+
| `dilithium5::open()` | `mldsa87::open()` |
91+
| `kyber1024::keypair()` | `mlkem1024::keypair()` |
92+
| `kyber1024::encapsulate()` | `mlkem1024::encapsulate()` |
93+
| `kyber1024::decapsulate()` | `mlkem1024::decapsulate()` |
94+
| `sphincsshake256fsimple` | `slhdsa_shake_256f` (TBD) |
95+
96+
### Phase 3: Elixir API migration (Target: Q3 2026)
97+
98+
The NIF module name (`Opsm.Crypto.PostQuantum.Nif`) and Elixir-side atom
99+
names (`:dilithium5`, `:kyber1024`, `:sphincs_plus`) should be updated to
100+
use NIST names (`:ml_dsa_87`, `:ml_kem_1024`, `:slh_dsa_256f`).
101+
102+
Provide backward-compatible aliases during transition period.
103+
104+
### Phase 4: Rustler upgrade (Target: Q2 2026)
105+
106+
Upgrade `rustler` from 0.35.x to 0.37.x in both NIF Cargo.toml files.
107+
The `opsm_pq_nif` NIF already uses the newer `rustler::init!` macro
108+
without explicit function list (v0.35+ syntax), so this should be
109+
straightforward.
110+
111+
## Files Affected
112+
113+
| File | Role |
114+
|------|------|
115+
| `opsm_ex/native/pq_crypto/Cargo.toml` | PQ crypto NIF dependencies |
116+
| `opsm_ex/native/pq_crypto/src/lib.rs` | PQ crypto NIF implementation (has build errors) |
117+
| `opsm_ex/native/opsm_pq_nif/Cargo.toml` | PQ NIF dependencies (primary) |
118+
| `opsm_ex/native/opsm_pq_nif/src/lib.rs` | PQ NIF implementation (builds clean) |
119+
120+
## Audit Notes (2026-03-10)
121+
122+
- `cargo audit` reports RUSTSEC-2024-0380 and RUSTSEC-2024-0381 for the
123+
deprecated `pqcrypto-dilithium` and `pqcrypto-kyber` crates
124+
- `pq_crypto` NIF has 35 compile errors (pre-existing); `opsm_pq_nif` builds clean
125+
- Both NIFs use identical algorithms but `opsm_pq_nif` is the actively maintained one
126+
- Consider removing the duplicate `pq_crypto` NIF or consolidating

docs/REGISTRY-API-CHANGELOG.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Registry API Changelog and Monitoring
3+
4+
Tracks API version targets, upcoming deprecations, and monitoring priorities
5+
for OPSM's 103 registry adapters.
6+
7+
Author: Jonathan D.A. Jewell
8+
Last updated: 2026-03-10
9+
10+
## Registry Adapter Count
11+
12+
OPSM has **103 registry adapters** in `opsm_ex/lib/opsm/registries/`.
13+
14+
## Major Registry API Versions
15+
16+
| Registry | Adapter File | API Version / Endpoint | Notes |
17+
|----------|-------------|----------------------|-------|
18+
| **npm** | `npm.ex` | `registry.npmjs.org` (v1 packument + v1 search) | Uses `/-/v1/search` endpoint |
19+
| **PyPI** | `pypi.ex` | `pypi.org/pypi/{name}/json` (JSON API) | XML-RPC search deprecated; search is non-functional |
20+
| **crates.io** | `crates.ex` | `crates.io/api/v1` | Requires User-Agent header |
21+
| **Hex.pm** | `hex.ex` | `hex.pm/api` (v1) + `repo.hex.pm` (tarballs) | Fetches release-specific deps |
22+
| **RubyGems** | `rubygems.ex` | `rubygems.org/api/v1` | Stable |
23+
| **Docker Hub** | `docker_hub.ex` | `registry.hub.docker.com/v2` | Token auth required |
24+
| **NuGet** | `nuget.ex` | `api.nuget.org/v3` | Service index discovery |
25+
| **Maven Central** | `maven.ex` | `search.maven.org/solrsearch` | Solr-based |
26+
| **Go Modules** | `go_modules.ex` | `proxy.golang.org` | Module proxy protocol |
27+
| **Packagist** | `packagist.ex` | `packagist.org/p2` | v2 metadata endpoint |
28+
| **pub.dev** | `pub_dev.ex` | `pub.dev/api` | Dart/Flutter |
29+
| **CocoaPods** | `cocoapods.ex` | `cdn.cocoapods.org` | CDN-based |
30+
| **JSR** | `jsr.ex` | `jsr.io/api` | Deno/JS registry |
31+
| **Homebrew** | `homebrew.ex` | `formulae.brew.sh/api` | JSON API |
32+
33+
## Known API Deprecations and Changes
34+
35+
### CRITICAL (action required)
36+
37+
| Registry | Deprecation | Impact | Deadline |
38+
|----------|-------------|--------|----------|
39+
| **PyPI** | XML-RPC search (`search()`) fully removed | `Opsm.Registries.Pypi.search/2` already returns placeholder; no functional search | Already deprecated |
40+
| **Docker Hub** | Rate limiting tightened (100 pulls/6h anonymous) | May need authenticated pulls for high-volume resolution | Ongoing |
41+
42+
### WARNING (monitor closely)
43+
44+
| Registry | Change | Impact | Timeline |
45+
|----------|--------|--------|----------|
46+
| **npm** | Registry v2 discussions | Packument format may change; OPSM uses v1 packument | No firm date |
47+
| **crates.io** | Sparse index as default | `crates.ex` uses HTTP API (not git index), so minimal impact | Already default in cargo |
48+
| **NuGet** | v3 service index evolution | New resource types may be added | Rolling |
49+
| **Maven Central** | Central Portal replacing OSSRH | Publishing changes; read API stable | 2025+ rollout |
50+
| **Homebrew** | API versioning | `formulae.brew.sh` may version endpoints | No firm date |
51+
| **Go Modules** | GONOSUMCHECK patterns | Checksum database changes | Ongoing |
52+
53+
### LOW RISK (stable)
54+
55+
- **Hex.pm**: Stable API, well-documented
56+
- **RubyGems**: v1 API stable for years
57+
- **CPAN**: MetaCPAN API stable
58+
- **Hackage**: Stable API
59+
- **Elm packages**: Simple Git-based registry, unlikely to change
60+
- **pub.dev**: Google-maintained, stable
61+
62+
## Rate Limiting Summary
63+
64+
| Registry | Limit | Auth Helps? |
65+
|----------|-------|-------------|
66+
| npm | No published limit (fair use) | N/A |
67+
| PyPI | ~100 req/min (JSON API) | No |
68+
| crates.io | 1 req/sec (requires User-Agent) | No |
69+
| Hex.pm | No published limit | N/A |
70+
| Docker Hub | 100 pulls/6h (anon), 200 (auth) | Yes |
71+
| RubyGems | 10 req/sec | API key for higher |
72+
| NuGet | No published limit | N/A |
73+
| Go Modules | No published limit | N/A |
74+
| GitHub Packages | 5000 req/hr (auth) | Required |
75+
| GitLab Packages | Varies by instance | Required |
76+
77+
## Monitoring Checklist
78+
79+
### Tier 1 — Monitor Weekly (high traffic, critical)
80+
81+
These are the most-used registries and the ones most likely to have API changes:
82+
83+
- [ ] npm (`npm.ex`) — Check for registry v2 announcements
84+
- [ ] PyPI (`pypi.ex`) — Monitor for new search API replacement
85+
- [ ] crates.io (`crates.ex`) — Rate limit / sparse index changes
86+
- [ ] Hex.pm (`hex.ex`) — API changes
87+
- [ ] Docker Hub (`docker_hub.ex`) — Rate limiting changes
88+
- [ ] RubyGems (`rubygems.ex`) — API deprecations
89+
- [ ] NuGet (`nuget.ex`) — v3 resource changes
90+
- [ ] Maven Central (`maven.ex`) — Central Portal migration
91+
- [ ] Go Modules (`go_modules.ex`) — Proxy protocol changes
92+
- [ ] JSR (`jsr.ex`) — New registry, API may evolve rapidly
93+
94+
### Tier 2 — Monitor Monthly (moderate traffic)
95+
96+
- [ ] Packagist, pub.dev, CocoaPods, Homebrew, Homebrew Cask
97+
- [ ] Conda, CRAN, Hackage, Stackage
98+
- [ ] Helm, Terraform, Pulumi
99+
- [ ] VS Code Marketplace, JetBrains
100+
101+
### Tier 3 — Monitor Quarterly (low traffic, stable)
102+
103+
- [ ] All Linux distribution registries (apt, rpm, alpine, AUR, etc.)
104+
- [ ] Niche language registries (Nim, Raku, Chicken, etc.)
105+
- [ ] OPSM-specific registries (agentic, eclexia, error_lang, etc.)
106+
- [ ] Archive/legacy registries (Bower, PEAR, PECL)
107+
108+
## Adapter Architecture Notes
109+
110+
All adapters follow a consistent pattern:
111+
- `fetch_package(name, version)` — returns `{:ok, %ResolvedPackage{}}` or `{:error, reason}`
112+
- `search(query, opts)` — returns `{:ok, [results]}` or `{:error, reason}`
113+
- `exists?(name)` — returns boolean
114+
- `versions(name)` — returns `{:ok, [version_strings]}`
115+
- `tarball_url(name, version)` — returns `{:ok, url}`
116+
117+
HTTP calls go through `Opsm.Verified.Http` (aliased as `VerifiedHttp`) which
118+
handles TLS verification, timeouts, and response parsing.

0 commit comments

Comments
 (0)