Skip to content

Commit 603cda5

Browse files
hyperpolymathclaude
andcommitted
feat(coprocessor): Phase 6B — Dsp + Io + Graphics + Audio + Fpga backends
Completes the coprocessor kind ladder begun in Phase 0 + 6A. All 11 CoprocessorKind variants (Math, Vector, Tensor, Crypto, Physics, FlintMath, Dsp, Io, Graphics, Audio, Fpga) now have full Rust impls with no stubs. Dsp (src/rust/coprocessor/dsp.rs): - 4 ops: DspFft, DspIfft, DspHannWindow, DspHammingWindow. - Backed by rustfft 6 (Apache-2.0 / MIT). FFT input/output uses FloatVec with re/im interleaved (avoids inventing a Complex outcome variant). IFFT scales by 1/N for round-trip identity — verified to 1e-9 over a sine-wave test. Length checks classify odd-length spectra as Failure. Tier 3 (LibraryWrapped). Io (src/rust/coprocessor/io.rs): - 3 ops: IoReadAll (16 MiB cap, returns Hex), IoLineCount (BigInt), IoSha256OfFile (streams 64 KiB chunks, returns Hex). Async via tokio::fs. Missing files return Empty; permission errors return Failure with diagnostic. RFC SHA-256("abc") test vector green. Tier 3. Graphics (src/rust/coprocessor/graphics.rs): - 2 ops: GraphicsProofGraphSvg (depth-aware vertical-waterfall layout with edges + rounded-rect nodes), GraphicsBarChartSvg (normalised heights, escaped labels). Pure Rust, no GPU dependency, no svg crate — emits SVG strings directly and Hex-wraps for wire safety. XML escape verified against `<dangerous & "chars">` input. Tier 3. Audio (src/rust/coprocessor/audio.rs): - 2 ops: AudioSineWave (frequency + duration + sample_rate → WAV bytes, Nyquist-checked, sample_rate range [8 kHz, 192 kHz]), AudioCompletionChime (pre-baked C5/E5/G5 100 ms each). Pure Rust PCM-16 + RIFF packing — no audio library dep. RIFF/WAVE/fmt /data chunk magic numbers verified. Tier 3. Fpga (src/rust/coprocessor/fpga.rs): - 1 op: FpgaYosysSynth — subprocess to `yosys -p "synth -top X; write_verilog"`. Health flips Unhealthy at construction if yosys not on PATH so the MetaController can route around. top_module name validated against shell-injection (alphanum + underscore, no leading digit). Tier 1 (ExternalSubprocess) — yosys is a witness oracle, not certifying. Wiring: - CoprocessorKind: + Dsp, Io, Graphics, Audio, Fpga. CoprocessorFactory ::native dispatches all five. julia_bridge kind_name covers all eleven kinds. - src/abi/CoprocessorForeign.idr: + 6 kind discriminants (5..10), extended kindEncodeDecodeId proof — case analysis still discharges every variant constructively. Zero believe_me. - Cargo.toml: + rustfft 6. Also: `tptp_output.rs` was orphan-tracked in cbd9449 (used by 4 HO-ATPs but missing from the commit) — fixed in 1ad49f8 alongside this work. Tests: 54 coprocessor tests green (10 Math + 6 Vector + 6 Tensor + 6 Crypto + 4 Physics + 1 factory + 5 Dsp + 4 Io + 4 Graphics + 4 Audio + 4 Fpga). panic-attack assail clean on all five new files (the Graphics 1 "weak point" is allocation-counting noise, not a defect). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1ad49f8 commit 603cda5

12 files changed

Lines changed: 1533 additions & 39 deletions

File tree

.machine_readable/6a2/STATE.a2ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ notes = "4 new CoprocessorKind variants (Vector / Tensor / Crypto / Physics) wit
7979
[[expansion-roadmap.phase]]
8080
id = "phase-6b"
8181
title = "Coprocessor wiring — DSP + IO + Graphics + Audio + FPGA"
82-
status = "available-for-claim"
82+
status = "complete"
83+
landed = "2026-04-26"
8384
adds-backends = []
84-
target-claim-id = "echidna-phase6b-coproc-rest"
85-
notes = "Each kind lands with full implementation. DSP: rustfft (FFT/IFFT/window). IO: tokio::fs (read/write/line-count). Graphics: SVG ProofGraph render (no GPU dep). Audio: pure Rust sine-wave / completion chime. FPGA: subprocess to yosys (synth flow). Tier 3 for native; Tier 1 for FPGA subprocess."
85+
notes = "5 new CoprocessorKind variants (Dsp/Io/Graphics/Audio/Fpga) with full Rust impls. New deps: rustfft 6 (Apache-2.0/MIT) for DSP. Dsp: 4 ops (FFT/IFFT/Hann/Hamming) — FFT round-trip identity verified to 1e-9. Io: 3 ops (ReadAll/LineCount/Sha256OfFile) — RFC SHA-256 vector green, 16 MiB read cap. Graphics: 2 ops (ProofGraphSvg/BarChartSvg) — depth-aware DAG layout, XML escape verified. Audio: 2 ops (SineWave/CompletionChime) — RIFF header validated, Nyquist enforced, three-note C5/E5/G5 chime. Fpga: 1 op (YosysSynth) Tier 1 — health flips Unhealthy when yosys absent, top_module name validated against shell injection. Idris2 ABI extended with 6 new kind discriminants (5..10) and constructive round-trip proof. 21 new tests (54 total coprocessor)."
8686

8787
[[expansion-roadmap.phase]]
8888
id = "phase-7"

Cargo.lock

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ sha2 = "0.10"
9494
# Ed25519 signature verification (Apache-2.0 / MIT, MPL-2.0 compat).
9595
ed25519-dalek = { version = "2", default-features = false, features = ["std"] }
9696

97+
# DSP coprocessor — FFT/IFFT (Apache-2.0 / MIT).
98+
rustfft = "6"
99+
97100
# TypedWasm engine — standalone crate at crates/typed_wasm.
98101
# Provides the pure parse/analyse engine; provers/typed_wasm.rs is a thin
99102
# adapter that maps its `Analysis` onto echidna core types, and routes the

src/abi/CoprocessorForeign.idr

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -87,47 +87,71 @@ encodeDecodeId PureFormal = Refl
8787
--------------------------------------------------------------------------------
8888

8989
||| The kind of a coprocessor backend. Only variants with a fully
90-
||| functional Rust + Idris2 implementation appear here. Phase 6A adds
91-
||| Vector / Tensor / Crypto / Physics; Phase 6B will add Dsp / Fpga /
92-
||| Graphics / Audio / Io alongside their implementations.
90+
||| functional Rust + Idris2 implementation appear here. Phase 6A added
91+
||| Vector / Tensor / Crypto / Physics; Phase 6B adds Dsp / Io / Graphics /
92+
||| Audio / Fpga. FlintMath (Phase 2A) is feature-gated in Rust but the
93+
||| ABI surface is unconditional.
9394
public export
9495
data CoprocessorKind : Type where
95-
Math : CoprocessorKind -- Phase 0 (num-bigint + num-integer)
96-
Vector : CoprocessorKind -- Phase 6A (auto-vectorised f64 loops)
97-
Tensor : CoprocessorKind -- Phase 6A (nalgebra dense linalg)
98-
Crypto : CoprocessorKind -- Phase 6A (sha2 + blake3 + ed25519-dalek)
99-
Physics : CoprocessorKind -- Phase 6A (RK4 + harmonic energy oracles)
100-
101-
||| Encoding to u8 — pinned for FFI stability.
96+
Math : CoprocessorKind -- Phase 0 (num-bigint + num-integer)
97+
Vector : CoprocessorKind -- Phase 6A (auto-vectorised f64 loops)
98+
Tensor : CoprocessorKind -- Phase 6A (nalgebra dense linalg)
99+
Crypto : CoprocessorKind -- Phase 6A (sha2 + blake3 + ed25519-dalek)
100+
Physics : CoprocessorKind -- Phase 6A (RK4 + harmonic energy oracles)
101+
FlintMath : CoprocessorKind -- Phase 2A (FLINT C library FFI, --features flint)
102+
Dsp : CoprocessorKind -- Phase 6B (rustfft FFT/IFFT + windows)
103+
Io : CoprocessorKind -- Phase 6B (tokio::fs file ops)
104+
Graphics : CoprocessorKind -- Phase 6B (SVG rendering, no GPU)
105+
Audio : CoprocessorKind -- Phase 6B (PCM/WAV synthesis)
106+
Fpga : CoprocessorKind -- Phase 6B (yosys subprocess, Tier 1)
107+
108+
||| Encoding to u8 — pinned for FFI stability. Reordering is an ABI break.
102109
public export
103110
coprocessorKindToU8 : CoprocessorKind -> Bits8
104-
coprocessorKindToU8 Math = 0
105-
coprocessorKindToU8 Vector = 1
106-
coprocessorKindToU8 Tensor = 2
107-
coprocessorKindToU8 Crypto = 3
108-
coprocessorKindToU8 Physics = 4
111+
coprocessorKindToU8 Math = 0
112+
coprocessorKindToU8 Vector = 1
113+
coprocessorKindToU8 Tensor = 2
114+
coprocessorKindToU8 Crypto = 3
115+
coprocessorKindToU8 Physics = 4
116+
coprocessorKindToU8 FlintMath = 5
117+
coprocessorKindToU8 Dsp = 6
118+
coprocessorKindToU8 Io = 7
119+
coprocessorKindToU8 Graphics = 8
120+
coprocessorKindToU8 Audio = 9
121+
coprocessorKindToU8 Fpga = 10
109122

110123
public export
111124
coprocessorKindFromU8 : Bits8 -> Maybe CoprocessorKind
112-
coprocessorKindFromU8 0 = Just Math
113-
coprocessorKindFromU8 1 = Just Vector
114-
coprocessorKindFromU8 2 = Just Tensor
115-
coprocessorKindFromU8 3 = Just Crypto
116-
coprocessorKindFromU8 4 = Just Physics
117-
coprocessorKindFromU8 _ = Nothing
125+
coprocessorKindFromU8 0 = Just Math
126+
coprocessorKindFromU8 1 = Just Vector
127+
coprocessorKindFromU8 2 = Just Tensor
128+
coprocessorKindFromU8 3 = Just Crypto
129+
coprocessorKindFromU8 4 = Just Physics
130+
coprocessorKindFromU8 5 = Just FlintMath
131+
coprocessorKindFromU8 6 = Just Dsp
132+
coprocessorKindFromU8 7 = Just Io
133+
coprocessorKindFromU8 8 = Just Graphics
134+
coprocessorKindFromU8 9 = Just Audio
135+
coprocessorKindFromU8 10 = Just Fpga
136+
coprocessorKindFromU8 _ = Nothing
118137

119138
||| Round-trip on the kind discriminant. Constructive — case-analysis
120-
||| discharges every variant. Together with `coprocessorKindFromU8` this
121-
||| guarantees the kind ABI is well-formed end-to-end.
139+
||| discharges every variant. Zero believe_me.
122140
public export
123141
kindEncodeDecodeId :
124142
(k : CoprocessorKind) ->
125143
coprocessorKindFromU8 (coprocessorKindToU8 k) = Just k
126-
kindEncodeDecodeId Math = Refl
127-
kindEncodeDecodeId Vector = Refl
128-
kindEncodeDecodeId Tensor = Refl
129-
kindEncodeDecodeId Crypto = Refl
130-
kindEncodeDecodeId Physics = Refl
144+
kindEncodeDecodeId Math = Refl
145+
kindEncodeDecodeId Vector = Refl
146+
kindEncodeDecodeId Tensor = Refl
147+
kindEncodeDecodeId Crypto = Refl
148+
kindEncodeDecodeId Physics = Refl
149+
kindEncodeDecodeId FlintMath = Refl
150+
kindEncodeDecodeId Dsp = Refl
151+
kindEncodeDecodeId Io = Refl
152+
kindEncodeDecodeId Graphics = Refl
153+
kindEncodeDecodeId Audio = Refl
154+
kindEncodeDecodeId Fpga = Refl
131155

132156
--------------------------------------------------------------------------------
133157
-- Health
@@ -172,8 +196,14 @@ healthFromU8 _ = Unhealthy
172196
||| Unhealthy. Currently a placeholder until libechidna_coprocessor lands.
173197
public export
174198
coprocessorHealthOf : CoprocessorKind -> CoprocessorHealth
175-
coprocessorHealthOf Math = Healthy
176-
coprocessorHealthOf Vector = Healthy
177-
coprocessorHealthOf Tensor = Healthy
178-
coprocessorHealthOf Crypto = Healthy
179-
coprocessorHealthOf Physics = Healthy
199+
coprocessorHealthOf Math = Healthy
200+
coprocessorHealthOf Vector = Healthy
201+
coprocessorHealthOf Tensor = Healthy
202+
coprocessorHealthOf Crypto = Healthy
203+
coprocessorHealthOf Physics = Healthy
204+
coprocessorHealthOf FlintMath = Healthy
205+
coprocessorHealthOf Dsp = Healthy
206+
coprocessorHealthOf Io = Healthy
207+
coprocessorHealthOf Graphics = Healthy
208+
coprocessorHealthOf Audio = Healthy
209+
coprocessorHealthOf Fpga = Unhealthy -- subprocess; runtime probe required

0 commit comments

Comments
 (0)