@wairon/cli 5.1.1-dev.11 → 5.1.1-dev.110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CONTRIBUTING.md +193 -0
  2. package/README.md +154 -41
  3. package/dist/cli/index.js +66474 -29775
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/index.d.ts +43671 -0
  6. package/dist/index.js +53581 -21797
  7. package/dist/index.js.map +1 -1
  8. package/dist/templates/architect.yaml +15 -13
  9. package/dist/templates/domain-owner.yaml +5 -4
  10. package/dist/templates/skills/sdd-architect.md +44 -26
  11. package/dist/templates/skills/sdd-auditor.md +5 -4
  12. package/dist/templates/skills/sdd-delegate.md +43 -4
  13. package/dist/templates/skills/sdd-implement.md +83 -13
  14. package/dist/templates/skills/sdd-narrative.md +7 -4
  15. package/dist/templates/variants/logic-shapes.yaml +59 -0
  16. package/dist/templates/variants/portal-shapes.yaml +13 -0
  17. package/dist/webapp.html +771 -0
  18. package/docs/architecture.md +83 -0
  19. package/docs/cli.md +1208 -0
  20. package/docs/design/approval-baseline.md +257 -0
  21. package/docs/design/connecting-agent-entrypoint.md +167 -0
  22. package/docs/design/execution-budgets.md +199 -0
  23. package/docs/design/pack-scoping.md +581 -0
  24. package/docs/design/supervisor-doctrine.md +110 -0
  25. package/docs/design-export.md +313 -0
  26. package/docs/extending-wairon.md +616 -0
  27. package/docs/network.md +109 -0
  28. package/docs/requirements.md +65 -0
  29. package/docs/roadmap.md +133 -0
  30. package/docs/standards/INDEX.md +23 -0
  31. package/docs/standards/architecture.md +1042 -0
  32. package/docs/standards/language-bindings.md +120 -0
  33. package/docs/templates.md +61 -0
  34. package/docs/vision.md +59 -0
  35. package/docs/wairon-feature-requests-hosted-mcp.md +74 -0
  36. package/package.json +18 -5
  37. package/schemas/design-export-2.json +1186 -0
@@ -0,0 +1,109 @@
1
+ # Derived networking: `wairon network`
2
+
3
+ wairon derives a system's network from its design. The inputs are the calls you model, the entries you declare on Portals (`invokedBy: {kind: entry, scope: outside | network}`), the networks your projects declare (`network` in `.wai/project.yaml`, written by `wairon network declare [--description <text>]` — `undeclare` removes it — or by the assistant's `sdd_set_network` tool) and the gateways on them (`variant: gateway`). From these it answers who may talk to whom, and on what grounds.
4
+
5
+ **The gate comes first.** Every network command reads the design as the validator judges it. A flow an error sits on (`GATEWAY_BYPASSED`, ...) is **refused**: the matrix marks its row `REFUSED` with the findings, a policy never admits it (and `policy` exits 1, naming it at the head of the file), `why` answers that the gate refuses it, and `check` files an observed flow that only a refused flow would allow as disallowed. A warning (`ENTRY_UNPROVEN`, ...) only marks its row. Each command prints the findings it was judged against.
6
+
7
+ Specs never hold an address, a port, a namespace or a label. Those deployment facts come from a **bindings file** that the team keeps outside `.wai/` and passes when generating policy. The design stays logical, and the deployment stays yours.
8
+
9
+ Every command runs at the project you are in. At a project that declares members, the commands cover its whole family; `--no-recursive` limits them to that project alone. Inside a member, they answer from the enclosing family — the parent's network declaration and the callers the parent models, the same answer the family root gives — and `--no-recursive` judges the member alone. Only the family run can narrow a `network` entry to the callers it really has.
10
+
11
+ ## The outputs, and what each is for
12
+
13
+ | Command | Output | What a team does with it |
14
+ |---|---|---|
15
+ | `wairon network flows [--format json\|csv\|markdown] [--out <file>]` | The **allowed-flows matrix**: one row per flow (from, to, transport, binding, networks crossed, gateway, evidence) | Review it in pull requests as the authoritative "who talks to whom". A design change that adds a dependency shows up as a new row before any code or firewall change exists. The CSV suits spreadsheets and audits, and the Markdown suits review comments. A design that fails the gate exits 1. |
16
+ | `wairon network policy --bindings <file> [--out <file>]` | **Kubernetes `NetworkPolicy`** YAML: one ingress policy per called workload | Commit it to the deployment repository and diff it in CI. A design change becomes a policy diff that the security reviewer reads in the same PR. A design that fails the gate exits 1: the refused flows are left out and named at the head of the file. A design name the bindings leave unbound also exits 1. |
17
+ | `wairon network diagram [--out <file>]` | A **Mermaid** flowchart: declared networks as nested boundaries, gateways on them, an `outside` node, and flows aggregated per workload pair | Use it as the data-flow diagram with trust boundaries that threat modelling starts from: each boundary an edge crosses is a place to ask the STRIDE questions. It also works for onboarding and on architecture pages. The hosted canvas draws the same picture in its **Network** view (`/canvas/<project>/network`; the system spec's `diagram.defaultView: network` opens the canvas there). |
18
+ | `wairon network check --observed <file> [--bindings <file>]` | **Unexpected** flows (seen, but nothing allows the pair), **disallowed** flows (a verb the destination declares, but not allowed from that source, or only by a flow the gate refuses), **unknown verbs** (an allowed pair, but a method and path no contract of the destination declares) and **unexercised** flows (allowed, never seen) | Audit a live system against its design. Exits 1 on anything unexpected, disallowed or unknown, so it can gate a pipeline. Unexercised flows are review items, such as dead dependencies or rules to tighten, and never fail the command. |
19
+ | `wairon network why <from> <to>` | The modelled chain behind a flow: the entry or call step, each network entered, the gateway, and the verb with its binding | Answer a firewall change request or an incident question ("why does checkout talk to payments?") from the design, in one command. Exits 1 when nothing allows the flow, and names what does reach the target instead; says so when the gate refuses the flow, when a name is unknown (a typo, not a refusal), and — exiting 0 — when the callee is reached in-process, which is never a network flow. |
20
+ | `wairon network declare [--description <text>]` / `undeclare` | Writes (or removes) `network` in `.wai/project.yaml` | Declare the boundary without a hand edit. It changes which rules fire, so validate, then re-lock. |
21
+
22
+ The MCP server offers the same reads to an assistant while it designs: `sdd_get_network_flows` (optionally `to: <project | portal | portal.verb>`) and `sdd_explain_flow` (`from`, `to`), and the declaration as `sdd_set_network` (`declared`, `description`). The hosted server serves the view model at `GET /web/projects/network?projectId=…`.
23
+
24
+ ### What becomes a flow
25
+
26
+ - Only **network transports** produce flows: HTTP, gRPC, GraphQL, MessageBus and Custom. In-process libraries, CLI commands, IPC and JSON-RPC over stdio never do.
27
+ - A **modelled call** into a network verb from another subsystem or project is a flow from the calling component. It names the networks it enters and the gateway it passes.
28
+ - A verb's **binding** is the path a cluster sees: an HTTP endpoint is joined under its Portal's `basePath` (`basePath: /v1` and `POST /orders` bind `POST /v1/orders`), so L7 checks match real paths.
29
+ - An **Adapter's transport** is its target Portal's: the Adapter calls the Portal's verbs over it. An Adapter may state one (`sdd_add_component` fills it in from the Portal its `dependsOn` names); a stated transport that disagrees with the target's is `ADAPTER_TRANSPORT_MISMATCH`, so changing a Portal's transport shows its impact on every Adapter that calls it.
30
+ - An **`outside` entry** is a flow from outside the verb's innermost network. For an outermost network that is the world (`outside`); for a nested network it is the next network out (`network:<parent>`). Scopes are relative.
31
+ - A **`network` entry** is a flow from anywhere inside the network. At the family root, when modelled callers prove the entry, the blanket row is replaced by those callers. The matrix is therefore least-privilege by construction: "the network may reach this" becomes "these two Adapters reach this".
32
+
33
+ ### Naming parties
34
+
35
+ `from`, `to`, the observed-flow names and the binding keys all use design names:
36
+
37
+ - `outside`.
38
+ - `network` or `network:<id>`, meaning anywhere inside a declared network. A network's id is the key of the project that declares it; plain `network` is the family root's.
39
+ - A project key such as `orders`.
40
+ - A subsystem, as `project::subsystem` or bare for the root's own.
41
+ - A component, as `project::component` or bare for the root's own.
42
+ - On the receiving end, also `project::portal.verb`.
43
+
44
+ Each party has a **default workload name**: a member's project key, or for the root project's own components their subsystem — also when the root's component reaches into another project: the caller is named by its workload (its subsystem, the pod it runs in), with the component kept for the evidence, so a bindings file written per service keeps covering it after a callee is promoted.
45
+
46
+ ## The bindings file
47
+
48
+ YAML, kept wherever your deployment config lives (never in `.wai/`):
49
+
50
+ ```yaml
51
+ workloads:
52
+ orders: # a project
53
+ selector: { app.kubernetes.io/name: orders }
54
+ namespace: shop
55
+ port: 8080 # the port its Portals listen on (optional)
56
+ platform::api_gateway: # a Portal: more specific than its project
57
+ selector: { app.kubernetes.io/name: edge }
58
+ namespace: edge
59
+ port: 8443
60
+ edge: # a subsystem of the root project
61
+ selector: { app.kubernetes.io/name: edge }
62
+ network: # "anywhere in the root network": a label every member pod carries
63
+ selector: { platform.example/member: "true" }
64
+ outside: # what "outside" means for a policy
65
+ - 0.0.0.0/0
66
+ ```
67
+
68
+ - `workloads` maps a design name to a `selector` (labels, required and non-empty), a `namespace` (optional) and a `port` (optional, 1–65535). The most specific key a party has wins, in the order component, subsystem, project, default workload name.
69
+ - `outside` lists the CIDR blocks admitted for callers from outside, for example the internet, a load balancer range or an intranet. Without it, nothing from outside is admitted.
70
+ - A source in another namespace gets a `namespaceSelector` on `kubernetes.io/metadata.name`. A network-wide source bound without a namespace matches in any namespace (`namespaceSelector: {}`).
71
+
72
+ **Nothing is guessed.** A design name the bindings do not map is selected by the placeholder label `wairon.dev/workload: <name>`, which matches no pod until you bind it or label one. It is listed in the document and on stderr, and at the top of the output under `# UNBOUND:`, and `policy` exits 1 so a pipeline notices. MessageBus flows travel through the broker rather than pod to pod, so they are listed as `# NOT EXPRESSED` instead of opening ingress. Default deny is implied: each policy selects its workload and admits only what the design allows.
73
+
74
+ **Renamed projects.** A bindings key, or a name in an observed-flow file, that is a project's former id (its rename trace, `previousIds`) still resolves to the renamed project, and the output carries a `# NOTE` naming the rename, so you can update the key at your pace instead of finding a policy that selects nothing or a legitimate flow filed as unexpected. `wairon project rename` lists the binding and telemetry keys to rename in its plan.
75
+
76
+ **Mixed reach.** A NetworkPolicy cannot split traffic by path. When one workload serves verbs of different reach on one port — a verb entered from `outside` and a verb only the network may call — its policy has to admit the union, and `policy` says so in a `# NOTE` naming the verbs. To keep the narrower verb narrow at L4, bind the Portal on its own (a `<project>::<portal>` key with its own selector or port): it then gets a policy of its own.
77
+
78
+ ## The observed-flow format
79
+
80
+ Export observed flows from whatever sees them: a service-mesh telemetry export, an eBPF flow log (Cilium/Hubble, Retina), or VPC flow logs once your tooling has mapped addresses to workloads. wairon never sees an IP address. Name each end by a design name, or by a label value that one of your bindings' selectors carries (pass `--bindings` so it can be mapped back).
81
+
82
+ CSV with a header row; `source` and `destination` are required, the rest optional:
83
+
84
+ ```csv
85
+ source,destination,transport,method,path,count
86
+ outside,edge,HTTP,GET,/api/orders,120
87
+ edge,orders,HTTP,POST,/orders,40
88
+ orders,billing,HTTP,POST,/charges,38
89
+ ```
90
+
91
+ Or JSON with the same fields, as a list or as `{ "flows": [...] }`:
92
+
93
+ ```json
94
+ [{ "source": "orders", "destination": "billing", "method": "POST", "path": "/charges", "count": 38 }]
95
+ ```
96
+
97
+ - A row without `method` and `path` is an L4 observation: it exercises every allowed flow between the pair.
98
+ - A row with both is checked at L7 against the verbs' bindings. `{id}` and `:id` path segments match any value, and gRPC paths (`/pkg.Service/Method`) match the `service/method` binding.
99
+ - A malformed row (no source or destination, or a non-integer count) is refused with its row number, and nothing is half-read.
100
+ - A name that is a project's former id is mapped to the renamed project, with a `# NOTE` (see **Renamed projects** above).
101
+
102
+ ## A typical loop
103
+
104
+ ```sh
105
+ wairon network flows --format markdown --out docs/flows.md # review in the PR
106
+ wairon network policy --bindings ../deploy/bindings.yaml --out ../deploy/netpol.yaml
107
+ wairon network check --observed hubble-export.csv --bindings ../deploy/bindings.yaml
108
+ wairon network why shop::checkout_adapter payments::payments_api.charge
109
+ ```
@@ -0,0 +1,65 @@
1
+ # wairon — Requirements
2
+
3
+ > Last updated: 2026-10-05 (for v6.0.0)
4
+
5
+ ---
6
+
7
+ ## Goals
8
+
9
+ 1. **Spec as the source of truth.** A project's architecture lives in a typed
10
+ spec tree under `.wai/specs/`. Agent files and conformance checks are derived
11
+ from it; generated files are outputs, never inputs.
12
+
13
+ 2. **Architecture conformance.** `wairon validate` is a gate that enforces
14
+ reference integrity, contract↔implementation symmetry, component-stereotype
15
+ dependency rules, and dependency-cycle freedom — so two implementers generate
16
+ the same structure and boundaries are not violated.
17
+
18
+ 3. **Equip the AI session, don't orchestrate it.** wairon serves live agent
19
+ briefs, installs SDD skills, and exposes `sdd_*` MCP tools. The host AI tool
20
+ spawns its own subagents and runs the workflow.
21
+
22
+ 4. **Multi-tool support.** Install skills, guides and the MCP registration (and,
23
+ when a project opts in, agent files) for Claude Code, Gemini CLI /
24
+ Antigravity, and other targets from the same spec tree.
25
+
26
+ 5. **Human approval, checkable in CI.** A human approves a design with
27
+ `wairon lock`; the approval is a committed file, and `wairon lock-check`
28
+ tells CI whether what merges is the approved design.
29
+
30
+ 6. **Optional and additive.** If a project has no `.wai/specs/`, wairon is
31
+ inert. When enabled, the workflow is strict.
32
+
33
+ 7. **Observable, file-based state.** Everything lives under `.wai/` as
34
+ human-readable YAML/JSON — no database, works offline, and no daemon for the
35
+ core workflow (`wairon serve` is an opt-in hosting daemon over the same files).
36
+
37
+ ---
38
+
39
+ ## Non-Goals
40
+
41
+ - **Not a session orchestrator.** wairon does not spawn or drive AI sessions,
42
+ run multi-model pipelines, or manage git worktrees. It relies on the host
43
+ tool's own native subagent mechanism. (`wairon serve` *hosts* the `sdd_*` tools
44
+ over HTTP for remote MCP clients, but still does not run or drive the AI
45
+ session.)
46
+ - **Not a hand-maintained agent registry.** Agents are derived from specs, not
47
+ authored in an `agents.json`.
48
+ - **Not a runtime for application code.** wairon manages specs, conformance, and
49
+ agent topology — not execution.
50
+ - **Not a plugin marketplace.** Templates are file-based; there is no registry
51
+ service.
52
+
53
+ ---
54
+
55
+ ## Scope
56
+
57
+ In scope: the SDD spec tree, conformance validation (spec and code↔spec),
58
+ approval and the CI merge gate, members and cross-project references, the
59
+ design export, spec-derived topology and live briefs, domains
60
+ (subsystem-derived + free-standing), SDD skills, extension packs, the MCP
61
+ server, shared context, multi-target generation, and the opt-in hosted server.
62
+
63
+ Still out of scope: deriving specs from existing code, conformance diffs
64
+ between revisions, and org-scale shared standards (see the
65
+ [roadmap](roadmap.md)).
@@ -0,0 +1,133 @@
1
+ # wairon — Roadmap
2
+
3
+ > Last updated: 2026-10-05 (for v6.0.0)
4
+
5
+ wairon is an AIDD support tool built around Spec-Driven Development. This roadmap
6
+ reflects what is actually shipped in `src/` and what is planned. The
7
+ [CHANGELOG](https://github.com/SYW-Apps/Waffle-AIron/blob/main/CHANGELOG.md) has the per-release detail.
8
+
9
+ ---
10
+
11
+ ## Shipped
12
+
13
+ - **SDD spec tree** — L0 System → L1 Subsystem → L2 Component → L3 Interface →
14
+ L4 Implementation → L5 Narrative, stored under `.wai/specs/`.
15
+ - **Architecture-conformance validation** (`wairon validate`) — a documented
16
+ rule registry (`wairon rules list`): reference integrity,
17
+ contract↔implementation method symmetry, narrative-call resolution and
18
+ control-flow soundness, component-stereotype dependency rules (including the
19
+ Supervisor/Actor doctrine and the Repository pattern), technology-leakage
20
+ fencing, dependency-cycle detection, draft-aware severity, per-project
21
+ severity overrides and per-spec `lint.allow`. `--ci` for pipelines.
22
+ - **Code↔spec conformance** — a spec's `sourcePath` is checked against the code:
23
+ declared exports, methods, params and the import graph, recorded beside the
24
+ approval and enforced by `validate --ci`.
25
+ - **One type grammar** — language-neutral type spellings (`list<T>`, `T?`,
26
+ `async T`, `int`/`float`, enums, named value-objects, signature types), with
27
+ `wairon doctor --fix` rewriting older spellings.
28
+ - **Approval and the merge gate** — `wairon lock` records a human's approval of
29
+ the design as one digest per spec in the committed `.wai/lock.json` (it never
30
+ rewrites the spec tree); `wairon lock-check` answers in CI whether the design
31
+ being merged is the approved one, also as a reusable GitHub workflow.
32
+ - **Members, parts and projects** — a project grows from subsystems, to
33
+ **parts** (some of its subsystems stored in another folder or repository), to
34
+ member **projects** with their own id, exports and lock, reached as
35
+ `alias::name`. Declared `externals` are pinned (`wairon externals pin`) and
36
+ compared with their live producers. `validate` at a parent is the family run.
37
+ - **Family migrations and renames** — attach, detach, adopt, promote, demote,
38
+ internalize, externalize, project and alias renames, each planned first
39
+ (`--report` / `dryRun`) and applied all or nothing; in-tree renames of
40
+ components, methods and types, and method moves, rewrite every reference.
41
+ - **Design export** (`wairon export`) — the whole resolved design as one JSON
42
+ document with a published schema, stamped with the approval verdict, for
43
+ generators and translators.
44
+ - **Spec-derived agent topology** — agents are derived from the spec tree
45
+ (`system-architect`, `<subsystem>-owner`, optionally a
46
+ `<component>-implementer` per component) and served as **live briefs**
47
+ (`sdd_get_agent_brief`, `wairon agent brief`), composed from the current tree
48
+ on every call. Agent files on disk are an opt-in materialized view
49
+ (`rules.materializeAgentFiles`). Execution budgets derive a model tier and
50
+ allowance per agent. There is no hand-maintained agent registry.
51
+ - **Domains** (`wairon domains`) — subsystem-derived domains plus free-standing
52
+ domains declared in `.wai/topology.yaml`, each with a derived owner agent.
53
+ - **SDD skills** (`wairon skills`) — installed into each active target tool to
54
+ drive the spec-driven workflow in-session.
55
+ - **MCP server** (`wairon mcp`) — topology tools + `sdd_*` tools for authoring
56
+ and validating specs, and MCP `instructions` returned on `initialize` so a
57
+ connecting agent is taught the SDD model (tree shape, authoring order, the
58
+ bound project's profile and packs, read-the-skill-first) instead of depending
59
+ on a human having briefed it. Packs append their platform delta to that text
60
+ via `instructions` in `pack.yaml`.
61
+ - **Shared context** (`.wai/context/`) — project description + auto-generated
62
+ domain map and AI guide.
63
+ - **Diagrams** (`wairon diagram`) — Mermaid component and L5-derived sequence
64
+ diagrams, an interactive canvas (Cytoscape.js, embedded, works offline) with
65
+ scoped navigation, narrative flowcharts and relation health, and editable
66
+ draw.io / Excalidraw exports.
67
+ - **Extension packs** (`wairon pack`) — profiles, language tables, rules,
68
+ patterns, variants and skills injected from outside; a machine pack store
69
+ with per-project selection, pinning, bundling and `pack sync` for CI, and
70
+ `pack impact` before every pack write.
71
+ - **Tooling** — `init`, `status`, `doctor` (health checks and upgrade
72
+ repairs), `wairon dev` (the web UI over a local project), self-update with
73
+ release channels, command aliases, multi-target exporters (Claude, Gemini /
74
+ Antigravity, custom), npm packages and standalone binaries.
75
+ - **Hosted server** (`wairon serve` / `wairon host`) — the `sdd_host` subsystem
76
+ serves the `sdd_*` tools over streamable HTTP for many fully-isolated projects,
77
+ each scoped per request to its authenticated project. Split data plane / admin
78
+ control plane; organization units and a permission grid; owner-bound API keys
79
+ and SSO; a state-scoped `lock` with approval requests; hosted members as
80
+ records of their own; git-backed projects; Notion / Miro producers; a web UI
81
+ (canvas, specs, admin). Self-host via Docker. See the
82
+ [hosted server guide](https://github.com/SYW-Apps/Waffle-AIron/blob/main/docs/design/hosted-mcp-server.md).
83
+
84
+ ---
85
+
86
+ ## Planned
87
+
88
+ - **Conformance engine depth** — call-graph↔narrative conformance beyond the
89
+ current checks, event-topology completeness, and clearer remediation
90
+ messages. This is wairon's core differentiator.
91
+ - **Upgrade automation** — more of the mechanical rewrites `wairon doctor
92
+ --fix` leaves to an author today (for example language-flavoured result
93
+ types), and per-member repairs run from a family's top.
94
+ - **Derive specs from existing code** — bootstrap a draft spec tree from a repo
95
+ so teams can adopt conformance without greenfield modeling.
96
+ - **CI reporting** — conformance diffs between two revisions in PR checks (the
97
+ pass/fail gates, `validate --ci` and `lock-check`, ship today).
98
+ - **Org scale** — shared template libraries and cross-project standards.
99
+ - **Multi-Domain Architectural Profiles** — Support non-backend domains cleanly to prevent context waste. The engine integration is shipped (profiles resolve per subsystem, family fencing applies, extension packs register custom profiles with their own doctrine/severities/designDepth), but the depth of **builtin** doctrine varies by profile — labeled honestly below. Platform-specific doctrine is expected to arrive as extension packs (profile + rules + language table), not as core code.
100
+ - **Frontend Profiles** (`frontend-reactive` and `frontend-controller`) — *doctrine enforced today*:
101
+ - *Concept*: Enforces a strict separation of presentation views from reactive logic custom hooks or class controllers.
102
+ - *Stereotypes*: Introduces `View` blocks representing pure presenter elements (like React JSX, Vue templates, or Flutter StatelessWidgets).
103
+ - *Validation*: Views are strictly passive; they cannot depend on database Stores, Registries, or Adapters. They only receive properties and forward callbacks. `Actor`/`Supervisor` in a frontend subsystem draw a sanity warning. (The two frontend profiles currently share one doctrine; reactive-dataflow-specific checks are future work.)
104
+ - **PLC Cyclic Profile** (`plc-cyclic`) — *core doctrine enforced today*:
105
+ - *Concept*: Structures industrial control programs executing inside strict scan cycles (e.g., Structured Text, CODESYS, Beckhoff TwinCAT, Siemens S7).
106
+ - *Stereotypes*: `Portal` maps to external HMI/network interfaces, `Orchestrator` maps to cyclic sequence programs, and Function Blocks map to an Orchestrator with `dependencyClass: pure` or `read` over `Store` instance memory. `cyclic` lifecycle entrypoints root the scan loop.
107
+ - *Validation*: Strict single-threaded execution model — **forbids concurrent runtime blocks** (`Actor` and `Supervisor` stereotypes) because execution must complete deterministically inside a single scan cycle. (Narrative-level checks — e.g. flagging blocking loops without watchdogs — are *not* yet implemented.)
108
+ - **OS / Game ECS / Embedded Profiles** (`lowlevel-os`, `game-ecs`, `realtime-embedded`) — *blueprints: today these enforce only the backend-family fencing (frontend stereotypes are refused). The stereotype mappings below are modeling guidance for humans; the platform-specific validations described are NOT implemented in core.*
109
+ - **OS Profile** (`lowlevel-os`): Models OS kernel scheduling loops, thread tasks, virtual filesystem blocks, and hardware interfaces. `Supervisor` maps to the kernel scheduler, `Actor` represents thread contexts/tasks, `Adapter` represents device drivers/VFS layers, and `Store` represents process tables. Envisioned zero-cost target: spec boundaries as compile-time virtual boundaries in systems languages (C, Rust `no_std`).
110
+ - **Game Profile** (`game-ecs`): Structures Entity-Component-System simulation loops. `Store` represents the component array registries, `Orchestrator` represents systems (e.g. Physics, Collision), and `Observer` manages game event buses. Envisioned zero-cost target: boundaries compiling down to direct storage queries. (Note: the standard dependency matrix is profile-blind today and does not yet license the ECS system→Store idiom specially.)
111
+ - **Embedded Profile** (`realtime-embedded`): Structures real-time microcontroller firmware, hardware pin control, sensor loops, and actuator drivers. `Adapter` wraps physical pin/device register I/O, `Orchestrator` implements control loops (e.g., PID controls), and `Observer` captures hardware interrupt routines (`interrupt` lifecycle entrypoints root ISR flows). Envisioned validation: pin access strictly behind Adapters, static-memory narrative checks (banning dynamic heap allocation) — both unimplemented; ISR/memory/WCET annotations would ride the `ext:` data channel.
112
+
113
+ ---
114
+
115
+ ## Architectural invariants
116
+
117
+ | Invariant | Why |
118
+ |-----------|-----|
119
+ | **`.wai/` boundary** | All wairon state lives under `.wai/`; nothing is written elsewhere without explicit opt-in. |
120
+ | **No hidden server (by default)** | The core workflow runs on-demand; the stdio MCP server is a subprocess, not a daemon. `wairon serve` is an explicit, opt-in hosting daemon. |
121
+ | **No database** | All state is human-readable YAML/JSON. |
122
+ | **Works offline (core)** | The core workflow has no network requirement; `wairon serve` and update checks are opt-in. |
123
+ | **Specs are the source of truth** | Agents and conformance are derived from `.wai/specs/`; generated files are outputs. |
124
+ | **wairon equips, not orchestrates** | wairon does not run AI sessions — it produces subagents, skills, and MCP tools the host tool consumes. |
125
+
126
+ ---
127
+
128
+ ## History note
129
+
130
+ Earlier drafts explored a local AI orchestration hub (session spawning,
131
+ delegation, multi-model pipelines, git worktrees). That direction was retired in
132
+ favour of equipping the host AI tool's own native subagent mechanism. The
133
+ orchestration code has been removed; this roadmap supersedes those plans.
@@ -0,0 +1,23 @@
1
+ # Architecture Standards
2
+
3
+ The canonical, language-neutral definition of wairon's architecture model — the
4
+ building blocks, patterns, entity/behavior rules, spec-tree layout, and the rules a
5
+ conformant design must obey. The schema, validator, MCP tools, and SDD skills all
6
+ reconcile to this.
7
+
8
+ - [Architecture Standard](architecture.md) — the single source of truth:
9
+ - the two axes (containment vs refinement; folders vs files)
10
+ - the ten building blocks + dependency rules + default interfaces
11
+ - logic as Orchestrators, bounded by a dependency class (`pure`, `read`, or a workflow)
12
+ - the process layer (Supervisor trees, Actors, entity Actors, timers) and external I/O / emission (Adapter)
13
+ - object modeling: where behavior lives; composition over inheritance
14
+ - entities & types: defined once, scoped by ownership
15
+ - the Repository pattern (one aggregate: Store, Registry, Indexes, Queries), the built-in variants (the `gateway` Portal variant among them), and the retired Specialist and Gateway stereotypes
16
+ - `owns` vs `dependsOn`, the visibility rule, ownership-leaf vs dependency-sink
17
+ - composition & layering (no nesting; promote to L1)
18
+ - implementation/concurrency strategy and transactions (language-neutral)
19
+ - spec-driven diagram generation
20
+ - a worked example: a live auction
21
+ - [Language Bindings](language-bindings.md) — how the neutral strategies map to
22
+ concrete primitives (Rust, Go, Java, C#, TypeScript, Python), and an Orchestrator
23
+ as a class or a module of functions.