Skip to content

Commit 6e65f03

Browse files
UnbreakableMJAntigravity (Gemini 3.5 Flash)
andcommitted
feat(skills): update spacecraft-gleam-guidelines with memory safety and concurrency
Add detailed sections to the skill metadata and reference document covering compiler-level and runtime-level memory safety, concurrency tradeoffs (when actors serialize/bottleneck vs. when processes isolate failure domains), and target-specific JS vs. Erlang FFI boundary safety. Co-Authored-By: Antigravity (Gemini 3.5 Flash) <noreply@google.com>
1 parent ad47816 commit 6e65f03

4 files changed

Lines changed: 53 additions & 2 deletions

File tree

spacecraft-gleam-guidelines.skill

2.09 KB
Binary file not shown.

spacecraft-gleam-guidelines.zip

2.09 KB
Binary file not shown.

spacecraft-gleam-guidelines/SKILL.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
name: spacecraft-gleam-guidelines
33
description: Use for writing type-safe fault-tolerant highly-concurrent Gleam code on the BEAM following Spacecraft Software standards. Triggers on any request involving Gleam, .gleam files, gleam.toml, the gleam CLI (build, check, test, format, add, publish, export), gleam_stdlib, typed OTP — gleam_otp actors, static_supervisor, factory_supervisor, supervision child specs — gleam_erlang processes, Subjects, selectors, named processes, Result/Option error handling, use expressions, exhaustive case, opaque types, @external FFI, the JavaScript target, or gleeunit/qcheck/birdie testing. Trigger even when implicit, e.g. "write a typed actor", "port this GenServer to Gleam", "supervise this Gleam process", or "make this Gleam code faster". Do NOT trigger for Erlang (spacecraft-erlang-guidelines) or Elixir (spacecraft-elixir-guidelines) — Gleam's typed actor and supervision APIs differ sharply from raw OTP, and generic BEAM advice gets them wrong. By Mohamed Hammad and Spacecraft Software.
4+
license: GPL-3.0-or-later
5+
maintainer: Mohamed Hammad <Mohamed.Hammad@SpacecraftSoftware.org>
6+
website: https://Construct.SpacecraftSoftware.org/
47
---
58

69
# Spacecraft Gleam Guidelines
@@ -13,12 +16,28 @@ description: Use for writing type-safe fault-tolerant highly-concurrent Gleam co
1316

1417
## Core Philosophy
1518
- **Stability first (Standard §3 Priority 1).** Gleam layers a sound static type system on the BEAM's fault tolerance — two complementary safety nets. Model *expected* failures as `Result` values the compiler forces callers to handle; let *unexpected* faults crash the process and let its supervisor restart it. Never blur the two lanes.
16-
- **Then Performance (Priority 2).** Concurrency is the default lever — cheap isolated BEAM processes, one scheduler per core, share-nothing message passing through typed `Subject`s. No locks, because nothing is shared.
19+
- **Then Performance (Priority 2).** Concurrency is the default lever — cheap isolated BEAM processes, one scheduler per core, share-nothing message passing through typed `Subject`s. Avoid process bottlenecks; keep stateless operations synchronous.
1720
- **Types are the design tool.** No nulls, no exceptions, exhaustive `case`. Make invalid states unrepresentable with custom types and `opaque` constructors instead of validating at every call site.
1821
- **Immutable, functional core.** All data is immutable; transform with pure functions, pattern matching, and pipelines. Keep side effects at the process boundary.
1922
- **Target discipline.** The Erlang target is the Spacecraft default for services — OTP, supervision, and `gleam_otp` exist only there. The JavaScript target has **no supervision**: a panic kills the whole runtime, so "let it crash" is Erlang-target advice only.
2023
- **Current APIs only.** `gleam_otp` and `gleam_erlang` had breaking 1.0 redesigns (2025-06-12). Verify against hexdocs for the pinned version — most older tutorials (and model memory) show APIs that no longer exist.
2124

25+
## Memory Safety & Type Guarantees
26+
- **Compile-Time Soundness:** Gleam's compiler enforces type-safe boundaries. It contains no `null` or `nil` values (use `Option` or `Result`), requires exhaustive matching on `case` patterns (no unhandled paths), and prevents mutable state bugs.
27+
- **Process Heap Isolation:** On the BEAM, every process has its own private heap. Garbage collection runs per-process and does not block the entire VM ("stop-the-world"). A crash or memory leak in one process is isolated and does not affect the rest of the application.
28+
- **FFI Protection:** FFI allows unsafe operations to escape compiler checks. Always wrap foreign calls in thin, safe wrappers, decode untyped data immediately using `gleam/dynamic/decode`, and convert Erlang/JS exceptions/throws into Gleam `Result`s.
29+
30+
## Concurrency vs. Performance Tradeoffs
31+
- **When Concurrency Helps (Do Spawn):**
32+
- Stateful services that require serialized updates (e.g. database connections, user sessions).
33+
- Highly concurrent independent I/O tasks (e.g. parallel HTTP requests or parallel file operations).
34+
- Isolating failure domains so a crash in one connection does not take down others.
35+
- **When Concurrency Hurts (Do NOT Spawn):**
36+
- Stateless calculations: Wrapping stateless logic in an actor serializes requests, introducing a CPU bottleneck and overhead from message passing.
37+
- Trivial tasks: The overhead of spawning a process and copying data exceeds execution time for small computations.
38+
- Large data transfer: BEAM copies message payloads between process heaps (except ref-counted binaries >64 bytes). For large terms, keep data process-local or use read-optimized ETS only if benchmarked.
39+
40+
2241
## Mandatory Abstraction Choice
2342
Always match the abstraction to the workload — and **prefer a plain module of pure functions when no state or isolation is needed** (do not wrap pure logic in a process):
2443

spacecraft-gleam-guidelines/references/Spacecraft_Gleam_Guidelines.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Spacecraft Gleam Guidelines — Full Reference
22

3-
**Version:** 1.0
3+
**Version:** 1.1
4+
**Date:** 2026-07-12
45
**Author:** Mohamed Hammad & Spacecraft Software
56
**Compatibility:** Claude 3.5+, Claude 4, Grok, and all advanced reasoning models
67

@@ -12,6 +13,37 @@ verified 2026-07-04 against Gleam 1.17.0, gleam_otp 1.2.0, gleam_erlang 1.3.0,
1213
and gleam_stdlib 1.0.3. `gleam_otp`/`gleam_erlang` broke compatibility at 1.0
1314
(2025-06-12) — reject any pattern from pre-1.0 tutorials.
1415

16+
## Concurrency vs. Performance: When it Helps vs. When it Hurts
17+
18+
BEAM processes are extremely cheap, but they are not free. Concurrency is an architectural decision that must be guided by the workload shape:
19+
20+
1. **When Concurrency Helps (Spawn Processes):**
21+
- **State Isolation:** When you need a serialized service managing state that changes over time (e.g., an actor maintaining a pool connection or session state).
22+
- **I/O Parallelism:** Offloading concurrent I/O operations (HTTP queries, file system access).
23+
- **Failure Isolation:** Running independent tasks (like client connection handlers) in isolated processes so that a crash in one task does not crash other sessions.
24+
2. **When Concurrency Hurts (Keep it Serial / Synchronous):**
25+
- **Stateless Calculations:** Wrapping pure algorithms (e.g., parsing, string transformations, math) in processes serializes requests. This forces caller processes to block on a single actor's mailbox, turning the actor into a serialized bottleneck.
26+
- **Trivial/Small Tasks:** The overhead of spawning a process and scheduling it is larger than executing simple synchronous code.
27+
- **Data Copying Overhead:** BEAM processes share nothing; sending a message copies the payload from the sender's heap to the receiver's heap. While ref-counted binaries >64 bytes are shared via a global heap, large nested terms (large dicts, custom records) suffer significant copying overhead. Keep large data structures in the process that processes them, or use a read-optimized ETS table (via thin FFI modules) only if benchmarking proves a performance gain.
28+
29+
## Memory Safety & Runtime Isolation
30+
31+
Gleam delivers memory safety at two levels: the compile-time type system and the BEAM runtime's process model.
32+
33+
1. **Compile-Time Safety:**
34+
- **No Nulls/Exceptions:** Gleam eliminates null pointer exceptions by using `Option(Type)` and `Result(Type, Error)` types.
35+
- **Exhaustive Matching:** The compiler guarantees that all pattern matches (`case` expressions) are total. You cannot compile a program with unhandled variants or missing cases.
36+
- **Immutability:** All data structures are immutable. This eliminates class-level bugs like data races on shared memory, pointer aliasing, or accidental mutation.
37+
2. **Runtime Isolation (BEAM Heap Model):**
38+
- **Per-Process Heaps:** Unlike traditional VMs (JVM, V8) that use a single shared heap with a global garbage collector, the BEAM allocates a small private heap for each process.
39+
- **Non-Blocking GC:** Garbage collection runs per-process. A process only collects its own heap when idle or when its heap is full. This prevents "stop-the-world" pauses from impacting other processes.
40+
- **Crash Containment:** A process crash terminates only the offending process and its linked children. Memory is reclaimed instantly when the process dies, avoiding VM-wide leaks.
41+
3. **Safe FFI Boundaries:**
42+
- Since FFI targets (Erlang/JavaScript) bypass Gleam's compiler safety checks, foreign functions must be isolated behind a thin wrapper module.
43+
- Always catch exceptions thrown in foreign code (using the `exception` package on Erlang or standard try-catch on JavaScript) and map them to Gleam `Result` types.
44+
- External raw terms must be validated at the boundary using decoders (`gleam/dynamic/decode`) before passing them to the rest of the application.
45+
46+
1547
## 1. Program shape: `main` + root supervisor (the backbone)
1648

1749
Create process names up front, start one root supervisor, park the main

0 commit comments

Comments
 (0)