<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin Riedl</title>
    <description>The latest articles on DEV Community by Kevin Riedl (@wavect).</description>
    <link>https://dev.to/wavect</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4090821%2Fcb617a4f-1c5d-4420-8dde-eb574e32de34.png</url>
      <title>DEV Community: Kevin Riedl</title>
      <link>https://dev.to/wavect</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wavect"/>
    <language>en</language>
    <item>
      <title>What a semantic patch can honestly prove about WebAssembly output</title>
      <dc:creator>Kevin Riedl</dc:creator>
      <pubDate>Mon, 24 Aug 2026 21:19:22 +0000</pubDate>
      <link>https://dev.to/wavect/what-a-semantic-patch-can-honestly-prove-about-webassembly-output-pbi</link>
      <guid>https://dev.to/wavect/what-a-semantic-patch-can-honestly-prove-about-webassembly-output-pbi</guid>
      <description>&lt;p&gt;When a coding agent changes a systems program, a source diff is only the beginning of the question.&lt;/p&gt;

&lt;p&gt;The more useful question is: &lt;strong&gt;what exact machine-facing artifacts would this semantic change produce, and can another process independently verify that relationship?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is one of the research problems we are exploring in &lt;a href="https://wavect.io/semaprax/" rel="noopener noreferrer"&gt;SEMAPRAX&lt;/a&gt;, an Apache-2.0 agent-native systems programming language built at Wavect GmbH.&lt;/p&gt;

&lt;p&gt;SEMAPRAX is currently &lt;strong&gt;v0.2 pre-alpha experimental research software&lt;/strong&gt;. It is not production-ready. The narrow mechanism described here is useful precisely because its claims are bounded.&lt;/p&gt;

&lt;h2&gt;
  
  
  From a patch to target projections
&lt;/h2&gt;

&lt;p&gt;SEMAPRAX has a read-only command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;semaprax target-evidence &amp;lt;file&amp;gt; &amp;lt;patch.spatch&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command takes a verified source snapshot and a semantic patch. It independently rebuilds both the base program and the patched candidate, then derives several deterministic compiler-owned projections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;semantic Graph JSON&lt;/li&gt;
&lt;li&gt;an explicit capability manifest&lt;/li&gt;
&lt;li&gt;Native C11 source&lt;/li&gt;
&lt;li&gt;a structurally validated WebAssembly Core module&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For every projection, the report records a domain-separated digest and byte length. It also classifies the projection as changed or unchanged.&lt;/p&gt;

&lt;p&gt;That sounds simple, but the distinction matters. A source edit can leave one projection unchanged while altering another. A documentation-level identity change, a capability change, and a runtime-behavior change should not all be flattened into the same “some bytes changed” signal.&lt;/p&gt;

&lt;p&gt;The target report therefore binds the proposed semantic change to the compiler artifacts it actually affects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why deterministic output is the prerequisite
&lt;/h2&gt;

&lt;p&gt;Evidence over compiler output is only useful when the output is reproducible.&lt;/p&gt;

&lt;p&gt;SEMAPRAX treats source formatting, semantic graph data, diagnostics, semantic patches, and target artifacts as deterministic projections. The same admitted input must produce the same bytes. Otherwise a digest says little: a second verifier could not distinguish a meaningful change from nondeterministic code generation.&lt;/p&gt;

&lt;p&gt;This is also why the report uses domain separation. A digest of a semantic graph should not be confused with a digest of a Wasm module, even if a contrived byte sequence happened to match. Each artifact is hashed in its own named domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The WebAssembly boundary
&lt;/h2&gt;

&lt;p&gt;The current WebAssembly lane uses the profile &lt;code&gt;semaprax.wasm-core.v1&lt;/code&gt;. The emitted module is structurally checked using &lt;code&gt;wasmparser&lt;/code&gt; 0.256.0 with its full feature set.&lt;/p&gt;

&lt;p&gt;Structural validation answers a real but limited question: &lt;strong&gt;is this byte sequence a structurally valid WebAssembly Core module under that validator configuration?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It does not answer whether the program was executed correctly. It does not establish host compatibility, ABI correctness, safety, performance, provenance, policy approval, or conformance across runtimes.&lt;/p&gt;

&lt;p&gt;SEMAPRAX’s public Wasm support is deliberately partial today. It covers bounded scalar exports and generated JavaScript/TypeScript bindings. It is not general WASI support, and it is not a broad WebAssembly Component Model implementation.&lt;/p&gt;

&lt;p&gt;Those nonclaims are part of the design. Evidence becomes dangerous when a convenient static fact is presented as a stronger runtime guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replay before authority
&lt;/h2&gt;

&lt;p&gt;A target report is still only evidence. By itself, it has no permission to modify source.&lt;/p&gt;

&lt;p&gt;SEMAPRAX can wrap the report in an additive Evidence v2 capsule tied to the semantic patch. The evidence-gated apply route acquires the ordinary single-file authority, independently replays the exact bounded change, reconstructs the target report, and checks the binding before committing.&lt;/p&gt;

&lt;p&gt;Conceptually, the route is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;verified source snapshot
        +
semantic patch bytes
        |
        v
independent replay
        |
        +--&amp;gt; candidate semantic graph
        +--&amp;gt; candidate capability manifest
        +--&amp;gt; candidate Native C11 source
        +--&amp;gt; candidate Wasm Core module
        |
        v
exact evidence comparison
        |
        v
commit or fail closed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the source snapshot drifted, the patch bytes differ, replay fails, or any bound artifact differs, the evidence-gated route must not commit the change.&lt;/p&gt;

&lt;p&gt;This keeps three ideas separate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Meaning&lt;/strong&gt; — the verified semantic change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evidence&lt;/strong&gt; — deterministic facts about its projections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authority&lt;/strong&gt; — the narrow operation allowed to publish it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why this may matter for agent-written systems code
&lt;/h2&gt;

&lt;p&gt;Text diffs are optimized for human review. Agents can consume them too, but they do not directly expose persistent semantic identity, resolved relationships, capability changes, or target consequences.&lt;/p&gt;

&lt;p&gt;An agent-oriented toolchain can make those facts first-class without pretending that agents are infallible. The goal is not to replace review with a digest. The goal is to give reviewers and automated policies a replayable statement that is narrower, more precise, and easier to falsify.&lt;/p&gt;

&lt;p&gt;For WebAssembly toolchains, this raises practical questions we would value feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which compiler facts are useful to bind alongside Wasm bytes?&lt;/li&gt;
&lt;li&gt;Which runtime observations belong in a separate evidence layer?&lt;/li&gt;
&lt;li&gt;How should toolchains describe validator configuration so reports remain replayable years later?&lt;/li&gt;
&lt;li&gt;Where should the boundary sit between a compiler-owned artifact and host-owned execution evidence?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can inspect the research project at &lt;a href="https://wavect.io/semaprax/" rel="noopener noreferrer"&gt;wavect.io/semaprax&lt;/a&gt; and the &lt;a href="https://github.com/wavect/semaprax" rel="noopener noreferrer"&gt;SEMAPRAX source repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; coding agents have been used extensively as development assistants on SEMAPRAX. Wavect GmbH retains human responsibility for the project and uses executable quality gates. The implementation remains experimental and not production-ready.``&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>ai</category>
      <category>rust</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why Agent Edits Need Semantic Identity: Building SEMAPRAX in Rust</title>
      <dc:creator>Kevin Riedl</dc:creator>
      <pubDate>Sun, 23 Aug 2026 12:56:48 +0000</pubDate>
      <link>https://dev.to/wavect/why-agent-edits-need-semantic-identity-building-semaprax-in-rust-1l2b</link>
      <guid>https://dev.to/wavect/why-agent-edits-need-semantic-identity-building-semaprax-in-rust-1l2b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://wavect.io/blog/semantic-identity-rust-agent-edits/" rel="noopener noreferrer"&gt;Wavect&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Text positions are fragile edit targets because formatting and nearby changes move them. SEMAPRAX instead gives declarations persistent identities, resolves source into checked HIR, projects deterministic graph views and binds patches to a revision. Rust newtypes keep declaration and expression identities distinct, while ordered collections and independent evidence replay make the boundary reproducible. This is a pre-alpha research design, not a claim of production readiness or complete language safety.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;A coding agent should edit a declaration by identity and expected meaning, not by a line number that may already be stale.&lt;/strong&gt; In &lt;a href="https://wavect.io/semaprax/" rel="noopener noreferrer"&gt;SEMAPRAX&lt;/a&gt;, persistent declaration IDs survive ordinary source movement, checked HIR centralizes resolved meaning, and revision-bound patches fail closed when their source snapshot changes. Rust makes these distinctions explicit in the compiler's types.&lt;/p&gt;

&lt;p&gt;This article explains that design as implemented in the pre-alpha research compiler. It is useful even if you never adopt the language: the same boundaries apply to refactoring engines, compiler services and agent tools that must turn an intention into a reviewable change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are line and byte offsets poor agent edit targets?
&lt;/h2&gt;

&lt;p&gt;A text edit usually says “replace bytes 418 to 463.” That address describes one file snapshot, not the program entity the agent meant. A formatter, comment or concurrent edit can move it. A name is better, but overloads, scopes and renames make names contextual too.&lt;/p&gt;

&lt;p&gt;The SEMAPRAX language contract therefore makes human-readable &lt;code&gt;.spx&lt;/code&gt; source the canonical Git projection while exposing a versioned semantic graph as the preferred agent interface. Public declarations carry persistent &lt;code&gt;@id&lt;/code&gt; identities. Expression identities remain revision-scoped because preserving every transient syntax node across arbitrary rewrites would imply a stronger identity guarantee than the compiler can honestly provide. The distinction is part of the &lt;a href="https://github.com/wavect/semaprax/blob/ca339feffcadf77a679abe2f159376287cf2e22c/docs/RFC-0001.md" rel="noopener noreferrer"&gt;SEMAPRAX language and compiler contract&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Rust encode the identity boundary?
&lt;/h2&gt;

&lt;p&gt;The HIR does not pass raw strings everywhere. It defines separate newtypes for declarations and expressions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;DeclarationId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;ExpressionId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ResolvedFunction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DeclarationId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// checked signature, body and effects&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shortened example reflects the types in &lt;a href="https://github.com/wavect/semaprax/blob/ca339feffcadf77a679abe2f159376287cf2e22c/src/hir.rs" rel="noopener noreferrer"&gt;&lt;code&gt;src/hir.rs&lt;/code&gt; at the audited revision&lt;/a&gt;. The benefit is mundane and important: a function that expects a persistent declaration target cannot accidentally receive an expression address. The compiler must perform an explicit conversion or reject the operation.&lt;/p&gt;

&lt;p&gt;The same module stores declaration indexes in &lt;code&gt;BTreeMap&lt;/code&gt; and relation sets in &lt;code&gt;BTreeSet&lt;/code&gt;. Ordered collections are not sufficient for determinism, but they remove one common source of output drift: randomized hash iteration. Semantic order still has to be preserved where order affects execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why resolve once into checked HIR?
&lt;/h2&gt;

&lt;p&gt;If a graph exporter, native backend and Wasm backend each reconstruct meaning from syntax, they can disagree about types, ownership or call targets. SEMAPRAX resolves and verifies first, then downstream projections consume the checked representation. The published &lt;a href="https://github.com/wavect/semaprax/blob/ca339feffcadf77a679abe2f159376287cf2e22c/docs/ARCHITECTURE.md" rel="noopener noreferrer"&gt;architecture and trust-boundary document&lt;/a&gt; describes this pipeline and separates implemented lanes from future authority.&lt;/p&gt;

&lt;p&gt;That gives an agent a useful chain of custody:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse human-readable source.&lt;/li&gt;
&lt;li&gt;Resolve names and persistent identities into HIR.&lt;/li&gt;
&lt;li&gt;Verify types, effects, ownership rules and contracts admitted by the current language subset.&lt;/li&gt;
&lt;li&gt;Project deterministic graph JSON or target artifacts from checked semantics.&lt;/li&gt;
&lt;li&gt;Bind proposed changes to the source revision and expected semantic target.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The graph is therefore a compiler projection, not a second source of truth. Git still reviews source. The agent gains structured context without asking humans to review an opaque database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes a semantic graph deterministic?
&lt;/h2&gt;

&lt;p&gt;Determinism is a whole-pipeline property. Stable node identifiers do not help if edge order changes between runs or diagnostics depend on hash iteration. SEMAPRAX uses ordered indexes, explicit serialization, bounded traversal and canonical output rules in its &lt;a href="https://github.com/wavect/semaprax/blob/ca339feffcadf77a679abe2f159376287cf2e22c/src/graph.rs" rel="noopener noreferrer"&gt;Rust graph projection&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is also a subtle prohibition: never “fix” execution vectors by sorting them for prettier JSON. Evaluation and cleanup order are semantic. Canonical sorting belongs only on mathematically unordered sets. Sequence-bearing data must retain the compiler-defined order.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can evidence constrain an agent patch?
&lt;/h2&gt;

&lt;p&gt;A serialized evidence capsule should describe why a patch is admissible, but possession of that capsule must not grant write authority. SEMAPRAX separates proof data from the component that owns the commit. Its patch route acquires the normal lock, independently replays the exact bounded evidence, checks the current source snapshot, and only then stages and commits the candidate. The &lt;a href="https://github.com/wavect/semaprax/blob/ca339feffcadf77a679abe2f159376287cf2e22c/src/patch_evidence.rs" rel="noopener noreferrer"&gt;patch-evidence implementation&lt;/a&gt; keeps replay and application visibly separate.&lt;/p&gt;

&lt;p&gt;This design addresses three distinct failures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stale intent:&lt;/strong&gt; the patch was valid for an older source revision.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wrong target:&lt;/strong&gt; the text still matches, but it now refers to a different declaration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forged confidence:&lt;/strong&gt; a caller presents a plausible report without reproducing the checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Independent replay does not prove that a requested feature is wise. It proves a narrower and testable statement: this bounded proposal still satisfies the compiler checks to which its evidence is bound.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should Rust compiler and agent-tool authors copy?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use domain newtypes.&lt;/strong&gt; Separate persistent entity IDs, revision-local node IDs, digests and capabilities at the type level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep one checked semantic core.&lt;/strong&gt; Make graph views and backends consume resolved meaning instead of reparsing names independently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design determinism deliberately.&lt;/strong&gt; Specify ordering, serialization, diagnostics and failure behavior, then test repeat runs byte for byte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bind edits to snapshots.&lt;/strong&gt; A semantic target without a source digest is still vulnerable to drift.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep evidence powerless.&lt;/strong&gt; Replay evidence inside the authority boundary before staging any change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish the limits.&lt;/strong&gt; A completion matrix is more useful than a broad “implemented” label when different compiler lanes have different evidence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SEMAPRAX follows the last rule with an evidence-gated &lt;a href="https://github.com/wavect/semaprax/blob/ca339feffcadf77a679abe2f159376287cf2e22c/docs/COMPLETION-MATRIX.md" rel="noopener noreferrer"&gt;completion matrix&lt;/a&gt;. It prevents a passing unit test for one projection from becoming a claim about every target or runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does SEMAPRAX not prove yet?
&lt;/h2&gt;

&lt;p&gt;SEMAPRAX v0.2 is experimental pre-alpha research. Its current repository documents bounded native C11/Clang and WebAssembly Core lanes, deterministic semantic tooling and a growing verified subset. It does not claim production readiness, complete memory safety, all operating systems, a complete ownership system, full ecosystem interoperability, a public Component Model runtime or live economic authority.&lt;/p&gt;

&lt;p&gt;The practical way to evaluate it is to inspect the source and dated evidence, not extrapolate from the project goal. Start with the &lt;a href="https://wavect.io/semaprax/architecture/" rel="noopener noreferrer"&gt;SEMAPRAX architecture overview&lt;/a&gt;, then compare the public claims with the pinned compiler revision below.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can you reproduce this walkthrough?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/wavect/semaprax.git
&lt;span class="nb"&gt;cd &lt;/span&gt;semaprax
git checkout ca339feffcadf77a679abe2f159376287cf2e22c
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; graph examples/hello.spx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command inspects the graph projection at the exact revision used for this article. Run the repository's documented quality gates before treating any local modification as evidence.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Editorial disclosure: OpenAI Codex assisted with drafting and translation. The technical claims and code references were checked against SEMAPRAX commit &lt;code&gt;ca339fe&lt;/code&gt; by Wavect. The article contains no performance or safety claim inferred from model output.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Reliable agent editing starts by naming the thing that should change, the revision in which it exists and the checks that must still hold. Rust can encode those distinctions directly: persistent declaration identity is not an expression address, checked HIR is not raw syntax, and evidence is not authority.&lt;/p&gt;

&lt;p&gt;SEMAPRAX is an experimental implementation of that boundary. Its useful lesson today is smaller than its long-term language goal: give agents semantic handles, make every projection deterministic, and fail closed when meaning or source state has moved.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>ai</category>
      <category>webassembly</category>
    </item>
  </channel>
</rss>
