Appendix D: Cheatsheet
For when you know what you want and need the syntax. Each line is a complete construct; chapters and other appendices are linked for full context.
Module
Section titled “Module”A plain module is the default building block; a specific type (service, …) is sugar you reach for when it earns its keep.
module Orders { rest_create createOrder } // plain module — the defaultservice Orders { // a typed module (sugar) aspect team: "Commerce" rest_create createOrder} // type + name + bodyservice #k7f2 Orders { ... } // with stable ID (random, meaningless)service AuthService in Platform { ... } // attach to a parent declared elsewhereservice Notifications // empty body, no bracesSee Ch 4.
Interface
Section titled “Interface”A plain interface is the default connection; a wire-level type (rest_create, kafka, …) is sugar. Name interfaces after the protocol verb/resource.
interface authorize // plain interface — the defaultrest_create authorize // typed leaf (sugar)rest_create authorize { // with body "Description" timeout: "5s"}kafka paymentEvents // async event interface (no subscribes:)// an event is an async interface reached by a normal `>` process edge — the edge IS the subscriptionSee Ch 5.
Surface
Section titled “Surface”surface ordersResource { // generic surface base: "/orders" rest_create createOrder}resource ordersResource { base: "/orders" } // user-defined surface typesurface outer { surface inner { ... } } // nested surfacesresource is a custom type teams define via type surface resource { ... }; the stdlib only ships generic surface. See Ch 6 and Ch 16.
Process
Section titled “Process”process Checkout { order = Customer > Orders.createOrder // step, with result binding Orders > Payments.authorize(order) // step with arg list | > Ledger.record // fan: owner = previous line's HEAD (Orders) \ > Audit.log // snake: owner = previous line's TAIL (Ledger) "wait for fraud review" // bare note step (no edge) Orders "ops team double-checks the total" // actor-anchored note
Payments if "stripe-customer" { // exclusive conditional (free-form head) Payments > Stripe.charge } else { Payments > PayPal.charge }
Orders select "payment method" { // multi-way, inclusive (every match runs) stripe: Payments > Ledger.record applepay: Payments > Ledger.record }
Shipping parallel race { // concurrent branches; race = first wins branch: Shipping > Notifications.sendEmail branch: Shipping > Notifications.sendSMS }
Orders try { // error path (guard, continue forward) Orders > Payments.authorize } catch "declined" { Orders > Notifications.sendEmail }
Orders each item in order.items: Orders > Inventory.reserve(item) // iteration (one-liner body)
Order reversible { // saga: completed steps roll back Order > Inventory.reserve unwind Order > Inventory.release // each step compensates itself Order > Payments.charge unwind Order > Payments.refund }
do NotifyCustomer(order) // splice subprocess (ownerless) finish "checkout complete" // terminate: success}
process Checkout in Orders { ... } // attach to a modulesubprocess NotifyCustomer(arg) { Orders > Ledger.record } // reusable helper (args intent-only)Anonymity — the draft floor (every anonymous piece is a TODO):
module Orders { > Payments // bare step: anon process, implicit caller = Orders > Cart.add // name the interface; caller still implicit}A > B. // trailing dot: B is a module, interface unspecified (TODO)A > B.x > C.y // chain (ordered): desugars to A > B.x ; B > C.yBare steps are unordered (order comes only from a process { } wrapper); a chain is one ordered anonymous process; a module callee synthesizes an anonymous interface. Refer to modules, interfaces, and subprocesses that don’t exist yet — the compiler synthesizes a dashed stub and tracks each gap as a TODO (process-first drafting), rather than erroring. archlang validate --complete gates a zero-TODO model. See Ch 7.
view PaymentsLandscape { "Description — first line is the header zone" show @@domain:"Payments" or @@security.zone:"PCI" // union selectors; @@ = aspect axis show in Payments or in Gateway // subtree membership hide database // subtract after the show-union group by @@team // cluster by an aspect getter (by VALUE) group by in Payments // by CONTAINMENT — one frame per container style * { color: colorize(@@security.zone) } // colour; explicit cast feeds the legend style violating PciIsolation { color: crimson } // policy findings drive visuals}// one representation clause replaces the board:// table { column @name; sort by @name }// matrix { axis @@team; order by cluster } — or `rows`/`cols` for a rectangular one// grid { rows @@team; cols @@security.zone; color @kind } — cross-tab, cells list modules// flow <Proc> [sequence | bpmn] — `bpmn` opens { lane by @@team | pool by @@team | … }// no layout clause — layout is the solver's; pin per node with `style X { pin <x>, <y> }`.See Ch 8.
A story is a guided walk over the view — not a representation, so it composes with any of them, and it is inert until the viewer is opened with ?present=1:
view PaymentsStory { show @@team:"payments" story { // at most FIVE chapters (hard grammar rule) chapter "Order comes in" { "Leading string is the chapter's note — optional, and it must come first." Web, Checkout, Orders // any node selector; written order IS the narration } chapter "Money moves" { Payments, Bank, Ledger } }}// beats, the relation each crosses, the sentence, the camera window and the// chapter handoff are all DERIVED. Doesn't compose with `focus`; one per view.See Ch 36.
Fields and aspects
Section titled “Fields and aspects”Fields = structured data. Aspects = cross-plane connections (a classification or a module membership). Descriptions = unstructured prose.
service Orders { region: euWest // identifier value (a plain field) repo.url: "https://..." // dotted key + string (structured property) version: 2 // number enabled: true // boolean "Description goes here as a bare string."
aspect { domain: "Orders" // string value = classification (a (key, value) tag) broker: KafkaBroker // bare module ref = membership (KafkaBroker becomes a place) }}See Ch 9.
Descriptions & markdown documents
Section titled “Descriptions & markdown documents”"Plain markdown plus archlang extensions.**bold**, *italic*, ~~strike~~, `code`, [link](https://...), tables, lists.
[[#stable_id]] / [[Name]] link to a declaration[[@@key]] / [[@@key:value]] link to an aspect plane / a specific classification[[Doc#section]] link to a heading inside an .md document@@aspectPath substitute an aspect value from THIS node (descriptions only)[[ref]]@@aspectPath read an aspect value on a REFERENCED node (works in .md too)"Every element also gets automatic backlinks (“mentioned in”). .md files render with the same flavored markdown and are a first-class archspace surface. See Ch 10 and Ch 10a.
Packages
Section titled “Packages”package: acme.shop // package root (opaque unit)version: "1.0.0"widgets: "./widgets.js"
repo: "https://github.com/acme/shop" // evidence pin — the repo `sources:` is checked againstcommit: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0" // required whenever `repo:` is set
dependencies { acme.shared: "../shared"}
use database, frontend from arch.backend // explicit, pick-and-choose (never use *)use relational_db as managed_db from acme.shared // local renameexport use payments_provider from acme.payments // re-exportA nested space manifest carries name: instead of package::
name: acme.shop.loans // a space within the packageSee Ch 12.
Evidence bindings — an ordinary field naming the code that attests a module, checked against the package’s repo:/commit: pin:
module Checkout { sources: "src/checkout/index.ts:12-88", "src/tax.ts:5-40", "src/whole-file.ts"}// entries are repo-root-relative; ranges are 1-based and INCLUSIVE.// verdicts: verified | broken | unverified — `unverified` is never a pass and draws no badge.See Ch 37.
Stable IDs
Section titled “Stable IDs”IDs are meaningless and permanent — random, never domain-encoded, never changed (let tooling mint them).
service #q8m3 Payments { ... } // module IDtype #b9k1 module service { ... } // type IDprocess #x4t7 Checkout { ... } // process IDview #h2w5 Landscape { ... } // view ID// Surfaces and interfaces do NOT carry IDs.See Ch 13.
Type declarations
Section titled “Type declarations”Plain modules/interfaces are the default — define a custom type only when you need to subtype, attach widgets, add custom fields/requirements, or assert a type.
type module service { required cascade version // mandatory cascading blank field required aspect domain // mandatory blank aspect component metrics { rest_create emit } // pre-filled sub-declaration required database PrimaryStore // mandatory blank sub-declaration cascade widget: arch-service // default cascading field append base // append-mode field (path/list/object compose)}
type service paymentsService { version: "2.1" } // subtypeexport type service internal_service { ... } // visible to importersRequired blanks
Section titled “Required blanks”// Two and only two ways to address an inherited `required` blank:field: value // fulfilldrop field // remove entirelySee Ch 17.
Propagation modes (set at the type)
Section titled “Propagation modes (set at the type)”| Modifier | Behavior |
|---|---|
| (none) — local | Stays where set, doesn’t flow |
cascade | Flows to descendants; override-on-walk |
cascade * | Declares a cascade-group root — sub-fields under the path participate in the same group; replacing the root drops the group; overriding a leaf keeps it |
append | Flows and composes (paths concat, lists append, objects merge) |
Cascade groups let you bundle related sub-fields (e.g. widget, widget.icon, widget.color) so that swapping the root tag automatically clears the inherited sub-fields, without per-leaf drop ceremony:
type module service { cascade * widget: arch-module { icon: service color: info }}type service custom { widget: my-element // drops icon, color}type service tweaked { widget.color: green // keeps icon}Aspects always cascade with override semantics; no modifier needed (or allowed) on aspects. See Ch 18.
Refinement / override / drop (uniform at type and instance level)
Section titled “Refinement / override / drop (uniform at type and instance level)”// Refine — same type or subtype, merges:component metrics { rest_create emitV2 }
// Override — switch to non-subtype type, requires keyword:override database metrics { db_read read }
// Drop — remove entirely:drop metricsdrop metrics.emit // remove a childMove-set against an inherited required blank:
| Goal | Syntax |
|---|---|
| Refine to subtype type, keep blank | required <subtype> Name |
| Refine to subtype type, fulfill | <subtype> Name { ... } |
| Switch to non-subtype type, keep blank | override required <new-type> Name |
| Switch to non-subtype type, fulfill | override <new-type> Name { ... } |
| Fulfill keeping inherited type | Name: value or Name { ... } |
| Remove entirely | drop Name |
See Ch 19.
Widgets
Section titled “Widgets”widget: arch-service // custom-element formwidget.icon: server // widget propwidget.accent: accent
widget: "<div class='card'>{{name}}</div>" // inline template formwidget: """<archui-card>{{name}}</archui-card>""" // triple-quoted, rawSee Ch 20.
archlang validate <path> # validate; exit non-zero on errorsarchlang validate --watch <path>archlang validate --complete <path> # fail (exit 3) if any TODO remainsarchlang info <path> # summarize a packagearchlang check <path> # validate + policy-check + format --check + evidencearchlang check <path> --against=main # + change-gate dry run vs a git refarchlang format <file.arch> # canonical formatting (whitespace, indent, ID minting)archlang format --check # exit non-zero if format would change anythingarchlang format --diff # print what would changearchlang set <path> <target> <field> <value> [--aspect] # headless field/aspect writearchlang set <path> <target> <text> --description # headless description writearchlang policy-check <path> # evaluate policies; error/warning/advisory findingsarchlang evidence <path> [--repo=<path>] # check `sources:` bindings; exit 1 only on BROKENarchlang export json <path> [-o <file>] # dump the resolved model as JSONarchlang export html <path> -o <file> # one self-contained HTML file, opens offlinearchlang render <path> --out=<f.svg|f.png> [--view=board|bpmn|flow|sequence] [--process=<name>] # headless diagram export (PNG via bundled resvg)archlang serve <path> [--port=<n>] [--web-root=<path>] # HTTP API + optional web UIarchlang lsp # language server on stdioarchlang conform <path> --source=jaeger|tempo --endpoint=<url> # check telemetry vs the modelSee Ch 21.
Embedding the viewer
Section titled “Embedding the viewer”<archlang-viewer src="./diagram.arch" style="width: 100%; height: 480px"></archlang-viewer>Sizing uses CSS (style, class); the element doesn’t accept width/height attributes. See Ch 23.
File layout reminder
Section titled “File layout reminder”my-project/├── package.archspace # manifest (required for non-anonymous package)├── widgets.js # custom-element registrations (optional)├── types.arch # type declarations├── orders.arch # instance declarations└── packages/shared/ # nested package (its own boundary) ├── package.archspace └── ...