@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.
- package/CONTRIBUTING.md +193 -0
- package/README.md +154 -41
- package/dist/cli/index.js +66474 -29775
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +43671 -0
- package/dist/index.js +53581 -21797
- package/dist/index.js.map +1 -1
- package/dist/templates/architect.yaml +15 -13
- package/dist/templates/domain-owner.yaml +5 -4
- package/dist/templates/skills/sdd-architect.md +44 -26
- package/dist/templates/skills/sdd-auditor.md +5 -4
- package/dist/templates/skills/sdd-delegate.md +43 -4
- package/dist/templates/skills/sdd-implement.md +83 -13
- package/dist/templates/skills/sdd-narrative.md +7 -4
- package/dist/templates/variants/logic-shapes.yaml +59 -0
- package/dist/templates/variants/portal-shapes.yaml +13 -0
- package/dist/webapp.html +771 -0
- package/docs/architecture.md +83 -0
- package/docs/cli.md +1208 -0
- package/docs/design/approval-baseline.md +257 -0
- package/docs/design/connecting-agent-entrypoint.md +167 -0
- package/docs/design/execution-budgets.md +199 -0
- package/docs/design/pack-scoping.md +581 -0
- package/docs/design/supervisor-doctrine.md +110 -0
- package/docs/design-export.md +313 -0
- package/docs/extending-wairon.md +616 -0
- package/docs/network.md +109 -0
- package/docs/requirements.md +65 -0
- package/docs/roadmap.md +133 -0
- package/docs/standards/INDEX.md +23 -0
- package/docs/standards/architecture.md +1042 -0
- package/docs/standards/language-bindings.md +120 -0
- package/docs/templates.md +61 -0
- package/docs/vision.md +59 -0
- package/docs/wairon-feature-requests-hosted-mcp.md +74 -0
- package/package.json +18 -5
- package/schemas/design-export-2.json +1186 -0
package/docs/network.md
ADDED
|
@@ -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)).
|
package/docs/roadmap.md
ADDED
|
@@ -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.
|