Provides coding and architectural support for Mach language projects.

Install

mkdir -p .claude/skills/mach && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17824" && unzip -o skill.zip -d .claude/skills/mach && rm skill.zip

Installs to .claude/skills/mach

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Use when writing, editing, or reviewing Mach (.mach) source files. Covers the full language: project/module structure, use/fwd imports and re-exports, the shadow-module pattern, all declaration forms (def, rec, uni, fun, ext fun, val/var, test), the type grammar with the ^ secret qualifier, literals, operators and casts, statements, docstring conventions, stdlib idioms (Result/Option, std.print), the comptime channel ($mach.*/$project.*/$bin.* reads, $if/$or, $each, intrinsics, comptime parameters, variadic packs), #[...] decorators, and inline assembly (asm x86_64/aarch64/riscv64).
589 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Write Mach (.mach) source files.
  • Edit Mach source files according to language rules.
  • Review Mach source files for correctness and style.
  • Understand Mach project and module structure.
  • Implement comptime features and inline assembly.

How it works

This skill provides guidance on Mach language rules, covering syntax, module structure, declarations, and advanced features like comptime and inline assembly. It emphasizes explicit typing and adherence to specific idioms.

Inputs & outputs

You give it
A task requiring Mach code creation, modification, or review.
You get back
Correct, compliant Mach (.mach) source code.

When to use mach

  • Writing Mach code
  • Reviewing Mach language syntax
  • Structuring Mach modules

About this skill

Mach

Mach is a low-level, explicitly-typed language: no type inference, no garbage collection, no hidden control flow. Files use .mach. This skill is the fast path for authoring correct Mach; doc/language/ in the Mach repository is the authoritative reference and wins on any disagreement.

Hard rules - get these right

  • No type inference. Every binding declares its type. val x = 42; is an error; write val x: i64 = 42;.
  • No compiler-known type aliases. bool, usize, str, char are stdlib defs, not built-ins. Import them before use (use std.types.bool.bool;). true/false are stdlib vals (1/0); comparisons and logical operators produce u8.
  • Decorators are #[...] attributes on the line(s) above a declaration: #[symbol("main")], #[inline], #[align(64)]. The backtick form was removed in v2.4.0 and is a migration error - never emit backticks.
  • Variadics are comptime packs. A trailing va: ... parameter, consumed by $each a in va. There is no va_list/va_start/va_arg and the C-style bare ... parameter is a removed-syntax error.
  • Strings are *u8, single-line. "hello" is a pointer to null-terminated bytes. No fat-pointer string type (str is def str: *char;); no multi-line string literal - use \n escapes.
  • No tagged unions, no match. A discriminated value is a rec carrying a discriminator plus a payload uni; consumers branch with if/or. This is exactly how stdlib Result[T, E] is built.
  • No compound assignment. += etc. do not exist; write x = x + 1;.
  • fwd is bare and always public (no pub fwd). ext fun is the only body-less function form.

Project and module structure

A project has a mach.toml at its root; [project] id roots every module path. A file at src/foo/bar.mach in project id = "myproj" is the module myproj.foo.bar. There is no this. self-prefix - always use the full project-rooted path, including for sibling modules. A one-segment use <id>; resolves only when that project declares a [project] module surface file (e.g. a library glfw imported as use glfw;); std does not - always import full std.* paths.

A file reads top-down: module docstring, use/fwd lines, declarations.

use - private import

use std.types.size;             # binds module `size`; use as size.usize
use sz: std.types.size;         # module under alias; use as sz.usize
use std.types.size.usize;       # binds the symbol; use bare as usize

The resolver binds whatever the path ends at: a module (members reached qualified) or a symbol (used bare). Importing a module does not pull its members in unqualified. No splat, no use foo.{a,b} - one name per line. A module uses every dependency it directly names, even ones reachable through a re-export: the dependency graph is visible at the top of every file.

fwd - public re-export

fwd impl.Point;                 # re-export as Point
fwd Pt: impl.Point;             # re-export as Pt
fwd impl.helpers;               # a module path re-exports the whole module

Mirrors use grammar; always publishes.

Shadow-module pattern

A surface file foo.mach co-exists with directory foo/ holding split implementations. The surface uses each split and fwds its public symbols; consumers use myproj.foo; and never name the splits. Topical splits forward everything unconditionally; multiplatform splits pick one impl per target:

$if ($mach.build.os == $mach.os.linux) {
    use impl: myproj.os.linux;
}
$or ($mach.build.os == $mach.os.windows) {
    use impl: myproj.os.windows;
}
$or {
    $error("myproj.os: unsupported target");
}

fwd impl.page_size;

Entrypoint and output

The stdlib provides the platform _start, which calls whatever function exports the linker symbol main. use std.runtime; is required to link it in even though nothing references it by name:

use std.runtime;
use std.print;

#[symbol("main")]
fun main(argc: i64, argv: **u8) i64 {
    print.println("hello, mach");
    ret 0;
}

use std.print; binds the leaf module print (std itself is not in scope). It exposes print/println (stdout), eprint/eprintln (stderr), and the format family printf/printlnf/eprintf/eprintlnf - pack-variadic, with {} holes filled in argument order plus {:x}-style specs ({:X}, {:c}, {:5}, {:<5}, {:08x}; {{/}} for literal braces). All return Result[usize, str].

print.printlnf("built {} in {}ms", name, elapsed);

Declarations

Modifiers: pub (public surface; without it a declaration is file-private) applies to fun, rec, uni, def, val, var; ext (C-ABI external) applies to functions only.

def - type alias

pub def Age:   i64;
pub def BinOp: fun(i64, i64) i64;

Aliases name any type; alias and underlying type are interchangeable.

rec / uni

pub rec Point { x: i64; y: i64; }
pub rec Pair[T, U] { left: T; right: U; }      # generic

pub uni Number { i: i64; f: f64; }              # fields overlap; size of largest

The compiler does not track which uni field is live. The sum-type idiom (stdlib Result[T, E] verbatim):

pub rec Result[T, E] {
    tag:   bool;
    value: uni { ok: T; err: E; };
}

Packed layout is not available; #[align(N)] raises a type's or global's alignment.

fun

pub fun add(a: i64, b: i64) i64 { ret a + b; }
pub fun identity[T](value: T) T { ret value; }  # generic; call: identity[i64](42)
pub fun load($order: u8, p: *i64) i64 { ... }   # comptime value param (see Comptime)
pub fun sum(va: ...) i64 {                      # variadic pack (see Comptime)
    var t: i64 = 0;
    $each a in va { t = t + a; }
    ret t;
}

Generic params [T] take types only, no constraints; monomorphized per instantiation; call sites always supply the types explicitly.

ext fun

#[symbol("write")]
pub ext fun libc_write(fd: i64, buf: *u8, n: i64) i64;

Body-less, ends in ;, C ABI is the contract. Provide the definition at link time (mach build . -l c, manifest libs, or an explicit .o/.a/.so). On PE targets pin imports to their DLL with #[library("ws2_32.dll")].

val / var

val pi: f64 = 3.14159;          # immutable; initializer required
var counter: i64 = 0;
var buf: [256]u8;               # default-initialized to zero

Work at module top level (pub exports) and in function bodies.

test

Tests are declarations, inline next to the code they cover, in any module:

test "point: add is commutative" {
    if (add(1, 2) != add(2, 1)) { ret 1; }
    ret 0;
}

The label is a required string literal. Its internal format is a convention, not an enforced standard: choose whatever names the test clearly and stays consistent within a project. The compiler uses a fully-qualified module.path.symbol:behavior form (e.g. "mach.cli.cmd.doc.write_doc:summary_only") that pins each test to the exact unit it exercises and groups cleanly under --filter; the libraries favor a shorter "topic: behavior" (e.g. "abs: i64 min saturates"). Either reads well. The body checks like an i32 function: ret 0 (or falling off the end) passes, any non-zero return fails. There are no assertion builtins; return early on a failed check. mach test collects every test in the project (dependencies excluded unless --include-deps), builds one executable per test, and reports per-module; --filter <pattern> narrows, --list enumerates.

Types

Compiler-seeded primitives (the complete set): u8 u16 u32 u64, i8 i16 i32 i64, f32 f64, and the untyped pointer ptr. SIMD vector names (f32x4 …) are a planned design and do not resolve as types yet.

*T                  # pointer          ?x address-of, @p dereference
[N]T  [N][M]T       # array            val a: [4]i64 = [4]i64{1, 2, 3, 4};
fun(T1, T2) R       # function pointer val op: BinOp = add;  op(2, 3)
^T                  # secret-qualified (see below)

Pointers index like arrays: p[i] reads the i-th element (this is how str is walked). A fun(...) type may carry a trailing ... for FFI only.

^ - the secret qualifier

^T marks data as secret for the constant-time discipline. Secrets may move and be stored but may never reach an observable position: a branch or loop condition, the left operand of &&/||, a memory index, or a //% operand - each is a compile error. Public flows up to secret implicitly; the only downgrade is the explicit strip cast x:^ (or x:^T). Any operation with a secret operand yields a secret result; uni variants must agree on secrecy; a secret-welded pointer (*^T) cannot be erased to ptr. Also rejected: a secret float operand, a secret integer multiply or variable shift (target capability permitting), and a secret passed to a variadic pack. The weld checks are deep (a secret nested in an aggregate counts) and fail closed. Carry the obligation through codegen with #[oblivious].

Constant-time support is an experimental preview: the guarantee is incomplete and unaudited, with a proven secret-disclosure path still open. Read doc/language/secrecy.md before touching crypto code, and do not write production cryptography against it.

Literals

FormExampleNotes
Int (dec/hex/bin/oct)42 0xDEAD 0b1010 0o755 1_000_000untyped until context
Typed suffix7i64 255u8 2.5f64use when context doesn't constrain
Float1.5 1.5e10. must be followed by a digit
Char'M'u8; escapes \n \t \r \\ \' \0 \xHH
String"hi\n"*u8, null-terminated, single-line; adds \"
nilnilnull address; coerces to any pointer or function type

Untyped literals are checked against the declared type, never used to infer it. nil with no context types as *u8; `var cb: fun(


Content truncated.

When not to use it

  • When working with languages other than Mach.
  • When type inference or garbage collection is expected.

Limitations

  • No type inference is supported.
  • No compiler-known type aliases like `bool` or `usize`.
  • No tagged unions or `match` statements.

How it compares

This skill provides authoritative guidance on Mach's strict, low-level language features, including its explicit typing and lack of type inference, which differs from more permissive languages.

Compared to similar skills

mach side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
mach (this skill)024dReviewAdvanced
software-architecture3336moNo flagsIntermediate
codex322moReviewAdvanced
game-development706moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

software-architecture

davila7

Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development.

333868

codex

Lucklyric

Invoke Codex CLI for complex coding tasks requiring high reasoning capabilities. This skill should be invoked when users explicitly mention "Codex", request complex implementation challenges, advanced reasoning, or need high-reasoning model assistance. Automatically triggers on codex-related requests and supports session continuation for iterative development.

32238

game-development

davila7

Game development orchestrator. Routes to platform-specific skills based on project needs.

70195

senior-fullstack

davila7

Comprehensive fullstack development skill for building complete web applications with React, Next.js, Node.js, GraphQL, and PostgreSQL. Includes project scaffolding, code quality analysis, architecture patterns, and complete tech stack guidance. Use when building new projects, analyzing code quality, implementing design patterns, or setting up development workflows.

35110

command-name

anthropics

This skill should be used when the user asks to "create a plugin", "scaffold a plugin", "understand plugin structure", "organize plugin components", "set up plugin.json", "use ${CLAUDE_PLUGIN_ROOT}", "add commands/agents/skills/hooks", "configure auto-discovery", or needs guidance on plugin directory layout, manifest configuration, component organization, file naming conventions, or Claude Code plugin architecture best practices.

697

python-project-structure

wshobson

Python project organization, module architecture, and public API design. Use when setting up new projects, organizing modules, defining public interfaces with __all__, or planning directory layouts.

860

Search skills

Search the agent skills registry