Neon Law
  • Fractional CTO
  • Litigation
  • Fractional GC
  • Legal Services
  • Sign in
← Rust in Peace

Rust in Peace

0 / 59 viewed

Open any slide to read it. View them all to unlock your certificate.

1

Chapter 1

Intro

May my soul rust in peace

Ferris the Rust crab in goggles holds a glowing vial, Megadeth Rust in Peace parody

1. May my soul rust in peace

5 Years at the Fruit

A hand holds a kiwi in front of a colorful rainbow sculpture

2. 5 Years at the Fruit

4 years finance data & platform engineering

Ten colleagues standing together in an Apple office

3. 4 years finance data & platform engineering

1 year teaching programming

Colleagues share dinner together at a restaurant

4. 1 year teaching programming

What I realized is

Groovy card: asterisk everyone loves vibing; nearly

5. What I realized is

Decided to be a lawyer in New York

New York City seen beyond a hillside cemetery

6. Decided to be a lawyer in New York

What our firm does

Fractional CTO

Litigation

Fractional GC

One-time services

7. What our firm does

NeonLawNavigator

github.com/neon-law-foundation/navigator
8. NeonLawNavigator

Agenda

An agenda, not a lecture outline — you are here to argue back. By the end of the half hour you will be able to:

  • Recount how a two-person team crossed from software to law without dropping the toolchain. Trace our process from the law, to a Cucumber feature, to a reusable template, to the signed notation it produces for one client. Dissect one workflow, forming a Nevada LLC, into attorney-gated steps with the shipped code. Map the Rust ecosystem we rely on and the seams that let us change it. Defend the claim that a reviewed, repeatable workflow beats a prompt. See how a grounded issue becomes a reviewable change, with automation carrying evidence forward and a person retaining the decision.
9. Agenda

Las Vegas, 2011 — where I learned to program

The Las Vegas Ruby Group logo: a ruby beside the wordmark, lvrug.org, @LVRUG

10. Las Vegas, 2011 — where I learned to program
2

Chapter 2

The Rails Lesson

Convention over configuration

Rails' core idea was radical to a beginner: stop configuring, start agreeing. If everyone follows the same convention, the framework fills in the rest — and a stranger can read your code.

11. Convention over configuration

The database was a shared design

The first convention I learned was the schema. Migrations turned the database into something a team designed together — versioned in the repository, applied the same way on every machine.

12. The database was a shared design

Controllers — where a request becomes a decision

The next thing we agreed on was the controller: the one place a request turns into an action. Same file, same shape, in every app — so anyone could find the logic.

13. Controllers — where a request becomes a decision

Parameter handling — the shape of what comes in

Then we learned to distrust the input. Parameter handling was the convention for taking what a user sent and making it safe before it touched anything that mattered.

14. Parameter handling — the shape of what comes in

Middleware — the layer I didn't know I needed

The last convention floored me: middleware. A stack of small, composable layers every request passes through — logging, auth, sessions — each one modular, each one reusable.

15. Middleware — the layer I didn't know I needed

"It works on my machine"

And then there was the phrase every one of us said, half-joking, in that Rails room: "It works on my machine." It was a promise and a curse — the first bug we could never reproduce.

16. "It works on my machine"

How new all of this still was

What stunned me most was how young it all was. These were not settled laws handed down — they were conventions a small community was inventing, out loud, in real time. And I got to be in the room.

17. How new all of this still was

From Rails conventions to Navigator

Fifteen years later I am a lawyer, and I kept every one of those lessons. Schema, controllers, parameters, middleware, convention over configuration — Navigator is those Rails ideas, applied to the practice of law in Rust.

18. From Rails conventions to Navigator

A eulogy for my programming career

I thought becoming a full-time lawyer meant leaving production software behind. Rust changed the obituary: I can let the old career rest because its best habits now run the law practice.

19. A eulogy for my programming career
3

Chapter 3

Shared craft compounds

Keep domain seams in Rust, where interest compounds

The bet is not "write a service in Rust." Rust owns reusable domain systems: libraries, command-line tools, workers, editor integrations, tests, and — through Dioxus — the browser pages. The payoff is that each good decision reinforces the next one.

20. Keep domain seams in Rust, where interest compounds

Widely available — governed in the open

Rust is stewarded by the Rust Foundation, an independent non-profit whose members include AWS, Google, Microsoft, and Meta — none of whom own the language. Wide availability is the access-to-justice argument: the toolchain costs a clinic exactly what it costs us — nothing.

21. Widely available — governed in the open

A cautionary tale — Java, Oracle, and the price of a single owner

Java was created at Sun; Oracle acquired Sun in 2010 and sued Google that same year over Android's reuse of 37 Java SE API packages. Google v. Oracle ran more than a decade, until the Supreme Court ruled in 2021 it was fair use.

22. A cautionary tale — Java, Oracle, and the price of a single owner

Say it with your whole chest

And when someone asks why it is written in Rust: because we are doing it in motherfucking Rust.

23. Say it with your whole chest
4

Chapter 4

Six ways to know a change holds

One giant change deserves more than one glance

When two numbers are too large to hold side by side, you can compare several well-chosen positions instead of trusting one glance. AI-assisted code is similar: no one review sees the whole change, so we ask the same question six different ways.

24. One giant change deserves more than one glance

The compiler asks whether the program can be true

Rust compiler: do the types, ownership, lifetimes, and exhaustive cases still compose into a program the machine can run?

25. The compiler asks whether the program can be true

Clippy and rustfmt ask whether the code speaks our dialect

Clippy finds suspicious choices. rustfmt removes accidental visual difference. Together they make the code easier for the next reader — and the next agent — to recognize.

26. Clippy and rustfmt ask whether the code speaks our dialect

Tests ask whether the promise still holds at the boundary

Tests are the behavioral measurement: given this input, state, or failure, does the system still keep the promise it made before the refactor?

27. Tests ask whether the promise still holds at the boundary

Bloom turns verification into a learning loop

The Bloom taxonomy gives the same work six human verbs: remember, understand, apply, analyze, evaluate, create.

28. Bloom turns verification into a learning loop

Marketing copy must explain the way, not only the claim

“AI helps us move faster” is not an explanation. The useful promise is: we move faster because every change meets several explicit checks before it earns trust.

29. Marketing copy must explain the way, not only the claim

Three workshops, three people, one method

The same explanation changes with the person doing the work:

  • Using the Navigator — the licensed lawyer checks a matter and signs the result.
  • Operating Navigator — the admin operator checks the environment before it goes live.
  • Contributing to Navigator — the contributor checks that an improvement protects the shared corpus.
30. Three workshops, three people, one method

Fast generation, slow enough verification

Vibe code quickly. Then keep it DRY, refactorable, covered, formatted, and explainable — six perspectives make the feedback loop faster, not heavier.

31. Fast generation, slow enough verification
5

Chapter 5

From Law to Workflow

The goal — deterministic workflows from law

The whole method on one slide: a prompt is a wish; a workflow is a contract. Read the law → a Cucumber feature → a template (the reusable blueprint) → a notation (one client's reviewed, signed result).

32. The goal — deterministic workflows from law

Step 1 — read the law

A Nevada LLC is a creature of statute: NRS Chapter 86 says what the Articles of Organization must contain. We do not paraphrase from memory — we read the chapter at its official source and cite it.

33. Step 1 — read the law

Step 2 — write the behavior before the code

The first artifact is not Rust — it is a Cucumber feature describing the whole arc in plain language, runnable as a test: a founder intakes, an attorney reviews, signatures land, and the state stamps a filing.

From features/tests/features/nest_formation.feature:


  Scenario: From intake to a stamped Secretary-of-State filing
    When the firm opens the "nv__llc_formation" matter for the client
    And the founder answers the formation questionnaire:
      | value                  |
      | Libra                  |
      | Bright Star Ventures   |
      | Neon Law Registered Agent |
      | members                |
      | Libra; 1 Main St; Las Vegas; NV; 89101; USA |
      | 2026-07-01             |
    And the attorney approves and sends the document
    Then the formation reaches the signature wait
    And the persisted packet is the official SoS form carrying the founder's answers
    And the generated packet is filed as a document in the matter
    When the attorney files the Articles with the Nevada Secretary of State
    Then the formation workflow reaches END
    And a filing was recorded with the "Nevada Secretary of State"
    And the founder's six onboarding answers are on file
34. Step 2 — write the behavior before the code

"It works on my machine" — so we stopped trusting my machine

Callback. The fix for that old curse is not a better machine — it is to stop trusting any machine. The scenario above runs against a real, throwaway store, so the environment is pinned in code, not remembered on a box.

35. "It works on my machine" — so we stopped trusting my machine

Step 3 — the template: a questionnaire and a workflow

The template is one markdown file with two machine-readable graphs: a questionnaire graph (what we ask) and a workflow graph (what we do). The Nest questionnaire is six answers, in order.

From templates/forms/united_states/nevada/state/nv__llc_formation.md:


questionnaire:
  BEGIN:
    _: person__client
  person__client:
    _: entity__company
  entity__company:
    _: person__registered_agent
  person__registered_agent:
    _: custom_single_choice__management_structure
  custom_single_choice__management_structure:
    _: people__managing_members
  people__managing_members:
    _: custom_datetime__formation_date
  custom_datetime__formation_date:
    _: END
  END: {}

And here is the workflow — the LLC formation dissected into small, named, modular steps. Each state is a noun in our glossary; each transition is a signal some handler fires. This graph is the product.

From templates/forms/united_states/nevada/state/nv__llc_formation.md:


workflow:
  BEGIN:
    intake_submitted: intake_persisted__organizer
  intake_persisted__organizer:
    articles_rendered: lawyer_review
  lawyer_review:
    approved: generate_pdf__articles_pdf
    rejected: END
  generate_pdf__articles_pdf:
    pdf_persisted: sent_for_signature__pending
  sent_for_signature__pending:
    signature_received: filing__nv_sos
    signature_declined: END
  filing__nv_sos:
    filed: END
  END: {}
36. Step 3 — the template: a questionnaire and a workflow

Step 4 — the attorney gate is a graph invariant

Every workflow must pass through lawyer_review before anything is signed or filed — not as a policy memo, but as a property checked over the state-machine graph itself with a breadth-first search from BEGIN.

From workflows/src/guardrail.rs:


pub fn lawyer_review_precedes_signature(spec: &WorkflowSpec) -> Result<(), GateViolation> {
    let begin = StateName::begin();
    if let Some(signature) = reaches_target_without_review(spec, &begin, is_signature_state) {
        return Err(GateViolation {
            fill_state: begin.as_str().to_string(),
            submission_state: signature,
        });
    }
    Ok(())
}
37. Step 4 — the attorney gate is a graph invariant

Step 5 — signature is a modular step

sent_for_signature__pending is one state in the graph, and the thing that fires it is a small trait — not a vendor. DocuSign is the shipped implementation; dev and tests run a recording stub, so the step stays testable without an account.

From portal/src/signature.rs:


pub trait SignatureProvider: Send + Sync {
    /// Submit the rendered retainer PDF for the given notation, placing
    /// the fields described by `manifest`. Returns a provider-issued id
    /// correlating future events.
    async fn send_for_signature(
        &self,
        notation_id: Uuid,
        pdf: &[u8],
        manifest: &SignatureManifest,
    ) -> Result<SignatureRequestId, SignatureError>;

Because the step is modular it can also be careful. Dispatch is idempotent — a notation that already has an envelope out reuses it, fires nothing, and sends nothing — so a retry can never double-send a client's contract.

From portal/src/retainer_walk.rs:


    // Idempotency: this notation already has an envelope out. Reuse the
    // recorded id, fire nothing, send nothing — the post-state is
    // whatever the notation already records.
    if let Some(existing) =
        store::signatures::request_id_for_notation(deps.surreal, notation_id).await?
    {
        return Ok((
            StateName::from(notation_row.state.as_str()),
            crate::signature::SignatureRequestId(existing),
        ));
    }
38. Step 5 — signature is a modular step

Step 6 — the filing, run durably

The last state, filing__nv_sos, records the filing with the Nevada Secretary of State — and like every long-running step it executes as a journaled, resumable Restate workflow through the restate-sdk crate.

39. Step 6 — the filing, run durably

"It works on my machine" — even when my machine dies

Restate takes the phrase somewhere new. The durable filing does not live on the machine at all — it is journaled, so it survives the pod that ran it and replays exactly where it left off.

40. "It works on my machine" — even when my machine dies

Why a workflow beats a prompt

You could ask a frontier model to "form me a Nevada LLC" and get something plausible. We built the harness instead, because plausible is not the bar — repeatable is. A prompt's steps are neither repeatable nor modular.

41. Why a workflow beats a prompt

Privacy-preserving operations are part of the product

Legal tech cannot treat observability as a copy of production. Navigator emits OpenTelemetry traces, metrics, and logs through one Rust crate, and the rule is structural: identifiers and counts, never client content.

42. Privacy-preserving operations are part of the product
6

Chapter 6

Rust All the Way Down

We did not start all Rust

Navigator did not begin as a pure-Rust stack. We have moved the boundary a seam at a time: server-rendered Maud with HTMX/Alpine/Bootstrap gave way to Dioxus; React and TipTap were evaluated and declined; the browser now shares the Cargo workspace with the rules and the server.

43. We did not start all Rust

From Postgres to Rust — over a bridge, since dismantled

SurrealDB holds the record: document, graph, and key-value work meet in one Rust engine. Every port slice proved its reads and writes before the old path went away, and the last of them took Postgres with it.

44. From Postgres to Rust — over a bridge, since dismantled

The runtime story: keep the seam, change the engine

The same move repeats at the runtime boundary. Durable workflows landed on Restate, local identity on Rauthy, the private edge on Pingora, local S3 on Garage, and observability on OpenObserve — each behind an application-owned protocol, trait, or environment contract.

45. The runtime story: keep the seam, change the engine

One deployment bucket; many matter repositories

Storage and Git deliberately have different cardinality. The target is one private object-storage bucket per deployment; documents, assets, exports, logs, and every Project's files use application-owned logical keys and metadata inside it. Git is the inverse: one deployment-specific GitHub organization holds many private repositories, such as neon-law-stg-projects/PROJECT_CODE_1 and neon-law-stg-projects/PROJECT_CODE_2.

46. One deployment bucket; many matter repositories

Rust where we can own the path; partners at the edge

The destination is not an ideological ban on vendors. Surreal Cloud, Restate Cloud, OpenObserve Cloud, Stalwart Managed Email, and Miuda PBX are the Rust-operated lanes under recorded cutover gates. Xero, DocuSign, and the SIP carrier stay at the business edge, where they provide the service we do not claim to reimplement.

47. Rust where we can own the path; partners at the edge

Rust reaches the places lawyers work

Navigator is not only a web app. The same rules meet lawyers in the editor they already work in, and the same AIDA catalog is available to assistants through MCP and A2A.

48. Rust reaches the places lawyers work

I want a commercial relationship with everything I depend on

A small legal team cannot maintain the world's infrastructure — so I want to pay for it, in the open. A vendor like Restate, or GitHub Sponsors for the libraries. A healthy dependency is one someone is paid to keep healthy.

49. I want a commercial relationship with everything I depend on

Always the latest, always Rust

Two rules keep the interest compounding: take the newest version of every dependency, and use exactly one language. No pinned-and-forgotten crates, no second runtime, no polyglot seams to babysit.

50. Always the latest, always Rust

Swap the seam — it still works

Every heavy dependency sits behind a trait, so changing one does not make the application a rewrite. Signatures, storage, identity, durable execution, policy, telemetry, and the project repository surface have all had an explicit seam. Sometimes the right change is a new provider; sometimes it is retiring a surface entirely.

51. Swap the seam — it still works

The crates we actually run on

The bill of materials for a real legal-tech product — every line a crate you can pull today:

  • HTTP and views — axum, dioxus, tower / tower-http.
  • Async runtime — tokio, multi-threaded, with graceful shutdown.
  • Store — surrealdb, one engine for document, graph, and key-value.
  • Durable execution — restate-sdk.
  • Telemetry — opentelemetry, tracing, OTLP.
  • Archive — arrow and parquet; a real Iceberg table lane is separately tracked.
  • Content — pulldown-cmark.
  • Cloud — google-cloud-storage + reqwest.
  • Identity — jsonwebtoken + oauth2.
  • Tests — fantoccini and cucumber, exercised through the workspace harness.
52. The crates we actually run on

Ethics is part of the stack

Lawyers who code still carry the rules of professional conduct, and the engineering answer is the same as it is for memory safety: make the invariant structural, not aspirational.

  • Scope is a field, not a vibe. Every engagement is scoped in writing before work starts. The conflict check runs first. Before any matter opens, we query every current and former matter. Referral, without a referral fee. When conflicted out, we refer — with no referral fee.
53. Ethics is part of the stack

The simplest developer environment I can get away with

The local loop is production-shaped on purpose: the Rust CLI provisions an isolated KIND dependency tier and the host application process shares that exact environment.

54. The simplest developer environment I can get away with

The online developer environment

So we built the environment in the cloud too. The same Rust processes, the same swappable seams, spun up online — so the loop follows me anywhere, and I barely write the code by hand at all. Agents do the typing; I review.

55. The online developer environment

"It works on my machine in the cloud — and on yours, and on my client's"

The phrase, finally earned. It works on my machine in the cloud. It works on your machine. It works on my client's machine — because the environment is swappable seams, pinned services, and durable runs, not a special box.

56. "It works on my machine in the cloud — and on yours, and on my client's"

Where we are today — live by August 20

Every seam now has its Rust answer, decided and recorded: SurrealDB (Surreal Cloud) for the store, Restate Cloud for durable execution, OpenObserve Cloud for telemetry, Stalwart Managed Email for every matter address, Miuda PBX on RustPBX for voice, Pingora at the private edge, Garage and Rauthy in the local loop, Regorus for policy, Dioxus for every view, Typst for every document. Running by August 20, 2026.

57. Where we are today — live by August 20

Betting on ourselves — Rust in peace

Choosing these vendors is betting on ourselves. If we write successful Rust, our vendors write successful Rust — a healthy ecosystem that stays usable for many years. That lets the firm focus on winning cases, and lets me Rust in peace: no longer a full-time developer, standing on the shoulders of giants.

58. Betting on ourselves — Rust in peace
7

Chapter 7

Wrap Up

Take the method home

The ask is not a star on a repository — it is the method, and every piece of it is a crate you can pull tonight. Read the law. Write the behavior first. Keep the domain seam in Rust. Put a human at the gate.

Read what we built and why for the longer version — then come find me afterward and let us get crabby together.

59. Take the method home

You finished — claim your certificate

Enter your name and email and the Neon Law Foundation will send a PDF certificate of completion.

We use your email only to send this certificate.

Neon Law
BlogContactFoundationNavigatorPresentationsWorkshops
Contact us — contact@neonlaw.com+1 510 800 2080
  • Nevada
    5150 Mae Anne AveSte 405-9002Reno, NV 89523
  • New York
    12 E 49th St18th FloorNew York, NY 10017
  • Washington
    720 Seneca StSte 107-715Seattle, WA 98101

© 2026 Shook Law PLLC and Neon Law Foundation

This is attorney advertisement. Nothing on this site is legal advice. Neon Law is the trade name of Shook Law PLLC, and an attorney-client relationship begins only with a signed retainer between you and Shook Law PLLC. Published flat fees cover the scope each one names and do not include third-party filing fees. Every legal matter is different, and past results do not guarantee a similar result.

Shook Law PLLC is a proud supporter of the Neon Law Foundation , a 501(c)(3) nonprofit.

Neon Law Foundation is a Nevada nonprofit corporation and a 501(c)(3) tax-exempt organization. It does not practice law and cannot represent you.

Nothing on this site is legal advice, and nothing here creates an attorney-client relationship.

5150 Mae Anne Ave Ste 405-9999, Reno, NV 89523
support@neonlaw.orgTransparency & public disclosures

Powered by Neon Law Navigator #26.8.20-hotfix.4

Open source — neon-law-foundation/navigator GitHub stars 2