Skip to content

Commit 6a75c7f

Browse files
ZhiXiao-LinRoy Lin
andauthored
feat(cloud): lock reproducible integration stack (#29)
Co-authored-by: Roy Lin <roylin@a3s.dev>
1 parent 954f33e commit 6a75c7f

15 files changed

Lines changed: 1009 additions & 13 deletions

File tree

.github/workflows/cloud-stack.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Cloud Stack
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- ".github/workflows/cloud-stack.yml"
7+
- ".gitmodules"
8+
- "apps/cloud"
9+
- "compat/**"
10+
- "crates/acl"
11+
- "crates/boot"
12+
- "crates/event"
13+
- "crates/flow"
14+
- "crates/gateway"
15+
- "crates/orm"
16+
- "crates/runtime"
17+
- "crates/sentry"
18+
- "crates/updater/**"
19+
- "justfile"
20+
- "scripts/verify-cloud-stack.mjs"
21+
- "scripts/verify-cloud-stack.test.mjs"
22+
push:
23+
branches:
24+
- main
25+
paths:
26+
- ".github/workflows/cloud-stack.yml"
27+
- ".gitmodules"
28+
- "apps/cloud"
29+
- "compat/**"
30+
- "crates/acl"
31+
- "crates/boot"
32+
- "crates/event"
33+
- "crates/flow"
34+
- "crates/gateway"
35+
- "crates/orm"
36+
- "crates/runtime"
37+
- "crates/sentry"
38+
- "crates/updater/**"
39+
- "justfile"
40+
- "scripts/verify-cloud-stack.mjs"
41+
- "scripts/verify-cloud-stack.test.mjs"
42+
43+
permissions:
44+
contents: read
45+
46+
concurrency:
47+
group: cloud-stack-${{ github.event.pull_request.number || github.ref }}
48+
cancel-in-progress: true
49+
50+
jobs:
51+
verify:
52+
name: Locked stack and contracts
53+
runs-on: ubuntu-24.04
54+
steps:
55+
- name: Checkout orchestrator
56+
uses: actions/checkout@v4
57+
58+
- name: Initialize locked integration inputs
59+
run: |
60+
git config --global url."https://github.com/".insteadOf "git@github.com:"
61+
git submodule update --init -- \
62+
apps/cloud \
63+
crates/acl \
64+
crates/boot \
65+
crates/event \
66+
crates/flow \
67+
crates/gateway \
68+
crates/orm \
69+
crates/runtime \
70+
crates/sentry
71+
72+
- name: Install Node.js 20
73+
uses: actions/setup-node@v4
74+
with:
75+
node-version: 20
76+
77+
- name: Install Rust 1.88.0
78+
uses: actions-rust-lang/setup-rust-toolchain@v1
79+
with:
80+
toolchain: "1.88.0"
81+
82+
- name: Test compatibility-lock policy
83+
run: node --test scripts/verify-cloud-stack.test.mjs
84+
85+
- name: Print and verify exact integration inputs
86+
run: node scripts/verify-cloud-stack.mjs
87+
88+
- name: Resolve locked Cloud metadata
89+
run: cargo metadata --manifest-path apps/cloud/Cargo.toml --locked --format-version 1
90+
91+
- name: Build the locked Cloud workspace
92+
run: cargo check --manifest-path apps/cloud/Cargo.toml --workspace --all-targets --locked
93+
94+
- name: Run Cloud contract fixtures
95+
run: cargo test --manifest-path apps/cloud/Cargo.toml --locked -p a3s-cloud-contracts
96+
97+
- name: Check the locked Gateway dependency surface
98+
run: cargo check --manifest-path crates/gateway/Cargo.toml --locked --all-targets --features wire

.gitmodules

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,21 @@
5555
[submodule "apps/desktop"]
5656
path = apps/desktop
5757
url = git@github.com:A3S-Lab/Desktop.git
58+
[submodule "apps/cloud"]
59+
path = apps/cloud
60+
url = git@github.com:A3S-Lab/Cloud.git
5861
[submodule "crates/flow"]
5962
path = crates/flow
6063
url = git@github.com:A3S-Lab/Flow.git
6164
[submodule "crates/boot"]
6265
path = crates/boot
6366
url = git@github.com:A3S-Lab/Boot.git
67+
[submodule "crates/runtime"]
68+
path = crates/runtime
69+
url = git@github.com:A3S-Lab/Runtime.git
70+
[submodule "crates/orm"]
71+
path = crates/orm
72+
url = git@github.com:A3S-Lab/ORM.git
6473
[submodule "crates/use"]
6574
path = crates/use
6675
url = git@github.com:A3S-Lab/Use.git

AGENTS.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ This file provides repository guidance for Codex and other coding agents working
99
```text
1010
a3s/
1111
├── apps/
12+
│ ├── cloud/ # Cloud control plane and node agent (submodule)
1213
│ └── docs/ # Documentation site
1314
├── crates/ # Rust crates as submodules
14-
│ ├── acl/ ahp/ box/ code/ event/ gateway/
15-
│ ├── lane/ memory/ power/ search/ updater/ use/
15+
│ ├── acl/ ahp/ box/ code/ event/ flow/ gateway/
16+
│ ├── lane/ memory/ orm/ power/ runtime/ search/ use/
17+
│ ├── updater/ # Root-owned shared crate
1618
│ └── common/ # Shared types (local crate)
1719
└── homebrew-tap/ # Homebrew tap
1820
```
@@ -87,6 +89,19 @@ Conventions:
8789
- ACL means the A3S Agent Configuration Language. Parse and generate it with
8890
`a3s-acl`; do not treat ACL as HCL or use an HCL parser for ACL files.
8991

92+
## Cloud Compatibility Lock
93+
94+
- `compat/cloud-stack.acl` is the source of truth for Cloud integration
95+
revisions, package versions, ownership, and protocol levels.
96+
- Keep component and protocol blocks sorted and keep the file in the canonical
97+
form generated by the checked-in `a3s-acl` Node SDK.
98+
- Update a component's gitlink, exact Cargo dependency, and lock entry together.
99+
- Run `just cloud-stack-check` from a clean checkout with the locked Cloud,
100+
ACL, Boot, Event, Flow, Gateway, ORM, Runtime, and Sentry submodules
101+
initialized.
102+
- Do not publish a compatibility update until the lock verifier and Cloud
103+
contract fixtures pass.
104+
90105
## NestJS And DDD Rules
91106

92107
Every business module must follow the four-layer DDD structure:
@@ -254,4 +269,5 @@ Rules:
254269
- Removed dead wrappers, orphaned exports, and redundant modules.
255270
- Used typed extension options where applicable.
256271
- Updated documentation for completed features.
272+
- Updated and verified `compat/cloud-stack.acl` for Cloud integration changes.
257273
- Ran formatting and relevant checks/tests from the correct workspace or app.

README.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ is Rust.
3434

3535
| Area | Paths | Purpose |
3636
| --- | --- | --- |
37-
| Product surfaces | `crates/cli`, `crates/bench`, `apps/web`, `apps/box`, `apps/docs` | CLI, browser workspace, benchmark control component, native app, and documentation site. |
37+
| Product surfaces | `crates/cli`, `crates/bench`, `apps/web`, `apps/box`, `apps/cloud`, `apps/docs` | CLI, browser workspace, benchmark control component, native app, Cloud control plane, and documentation site. |
3838
| Agent runtime | `crates/code`, `crates/ahp`, `crates/acl`, `crates/common` | Sessions, tools, policy, protocol, config, and shared types. |
3939
| UI systems | `crates/tui`, `crates/gui`, `crates/webview` | Terminal UI, native RSX UI, and trusted WebView helpers. |
4040
| Use and retrieval | `crates/use`, `crates/search` | Browser, native Office, and OCR capability surfaces, external Use extensions, and search through the shared Browser runtime. |
41-
| State and coordination | `crates/memory`, `crates/event`, `crates/flow`, `crates/lane` | Memory, events, workflows, and queues. |
41+
| State and coordination | `crates/memory`, `crates/event`, `crates/flow`, `crates/lane`, `crates/orm` | Memory, events, workflows, queues, and typed persistence. |
4242
| Runtime safety and operations | `crates/runtime`, `crates/box`, `crates/observer`, `crates/sentry` | Provider-neutral execution, isolation, observability, and runtime control. |
4343
| Services | `crates/boot`, `crates/gateway`, `crates/power` | Service framework, ingress, and model serving. |
4444
| Distribution | `crates/updater`, `homebrew-tap` | CLI self-update support and Homebrew formulae. |
@@ -49,26 +49,28 @@ is Rust.
4949
| --- | --- | --- |
5050
| [A3S Web](apps/web/) | 0.1.0 | Browser workspace for the A3S Code product, served by the local CLI. |
5151
| [A3S Box Desktop](apps/box/) | 0.1.0 | Native A3S Box management client. |
52+
| [A3S Cloud](apps/cloud/) | 0.1.0 | Multi-tenant control plane, node agent, and versioned Cloud contracts. |
5253
| [a3s](crates/cli/) | 0.9.1 | End-user CLI and typed component-management entrypoint. |
5354
| [a3s-code](crates/code/) | core and SDKs 5.3.1 | Rust agent runtime plus Node and Python SDK bindings. |
5455
| [a3s-gui](crates/gui/) | 0.1.0 | Native GUI runtime with hooks, RSX templates, semantic UI, and platform hosts. |
5556
| [a3s-tui](crates/tui/) | 0.1.10 | Terminal UI framework used by `a3s code`. |
5657
| [a3s-flow](crates/flow/) | 0.4.1 | Durable workflow engine with event-sourced runs and replay. |
58+
| [a3s-orm](crates/orm/) | 0.1.0 | Typed SQL, migrations, and PostgreSQL/SQLite persistence. |
5759
| [a3s-memory](crates/memory/) | 0.1.2 | Pluggable long-term memory storage for agents. |
5860
| [a3s-event](crates/event/) | 0.3.0 | Event subscription, dispatch, and persistence. |
5961
| [a3s-lane](crates/lane/) | 0.5.0 | Rust-only priority and job queue with Redis, flows, repeat jobs, worker leases, retry, and DLQ. |
6062
| [a3s-use](crates/use/) | 0.1.1 | Typed Browser, native Office, and OCR capability layer plus native CLI, standard MCP, and Skill extension surfaces. |
6163
| [a3s-search](crates/search/) | 1.4.3 | Embeddable meta-search engine using `a3s-use-browser` for headless browsing. |
6264
| [a3s-bench](crates/bench/) | 0.1.0 | Reproducible evaluation of coding agents, automated systems, and deterministic tools. |
63-
| [a3s-runtime](crates/runtime/) | 0.1.0 | Provider-neutral execution contract and Runtime client. |
65+
| [a3s-runtime](crates/runtime/) | 0.2.0 | Provider-neutral execution contract and Runtime client. |
6466
| [a3s-box](crates/box/) | 3.0.5 | Docker-like MicroVM runtime for Linux OCI workloads. |
6567
| [a3s-observer](crates/observer/) | 0.11.0 | eBPF observability for LLM calls, tools, files, and egress. |
66-
| [a3s-sentry](crates/sentry/) | 0.6.0 | Tiered runtime security control. |
67-
| [a3s-boot](crates/boot/) | 0.1.0 | Nest-inspired modular service framework for Rust APIs. |
68-
| [a3s-gateway](crates/gateway/) | 1.0.11 | Reverse proxy, routing, middleware, streaming, and scale-to-zero. |
68+
| [a3s-sentry](crates/sentry/) | 0.7.0 | Tiered runtime security control. |
69+
| [a3s-boot](crates/boot/) | 0.1.1 | Nest-inspired modular service framework for Rust APIs. |
70+
| [a3s-gateway](crates/gateway/) | 1.0.12 | Reverse proxy, routing, middleware, streaming, and scale-to-zero. |
6971
| [a3s-power](crates/power/) | 0.4.2 | Privacy-preserving LLM inference for TEE environments. |
7072
| [a3s-ahp](crates/ahp/) | 2.4.0 | Agent Harness Protocol supervision primitives. |
71-
| [a3s-acl](crates/acl/) | 0.2.1 | Agent Configuration Language parser. |
73+
| [a3s-acl](crates/acl/) | 0.2.2 | Agent Configuration Language parser. |
7274
| [a3s-webview](crates/webview/) | 0.1.1 | Native trusted WebView popup helper. |
7375
| [a3s-common](crates/common/) | 0.1.1 | Shared primitives and transport types. |
7476
| [a3s-updater](crates/updater/) | 0.3.0 | Verified component transactions and self-update support for CLI binaries. |
@@ -154,6 +156,9 @@ Local development:
154156
```bash
155157
git submodule update --init --recursive
156158

159+
# Verify the exact Cloud integration stack and contract fixtures.
160+
just cloud-stack-check
161+
157162
# Run A3S Code from source.
158163
just code
159164

@@ -205,7 +210,12 @@ git commit -m "Update <component> snapshot"
205210

206211
Applications under `apps/` use app-local workflows. The root `justfile` only
207212
orchestrates common entry points such as `just code`, `just dev`, `just web`,
208-
`just use-hotplug-e2e`, and `just box-check`.
213+
`just use-hotplug-e2e`, and `just cloud-stack-check`.
214+
215+
Cloud integration revisions and protocol levels are recorded in
216+
`compat/cloud-stack.acl`. Update that ACL lock and the corresponding gitlinks
217+
together; its verifier rejects missing, dirty, or mismatched inputs before the
218+
cross-repository contract gate runs.
209219

210220
## Documentation
211221

apps/cloud

Submodule cloud added at 85f5d13

compat/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Cloud Stack Compatibility Lock
2+
3+
`cloud-stack.acl` is the machine-readable compatibility boundary for the A3S
4+
Cloud integration gate. It pins every participating submodule to a full commit,
5+
records exact Cargo package versions, and names the protocol levels exercised
6+
by the gate. The root-owned Updater crate is pinned by its exact package version
7+
and by the root commit that contains it.
8+
9+
The lock is parsed and regenerated with the checked-in `a3s-acl` Node SDK.
10+
`node scripts/verify-cloud-stack.mjs` rejects non-canonical ACL, unknown fields,
11+
unsafe or duplicate paths, missing gitlinks, unexpected submodule URLs,
12+
revision drift, dirty component worktrees, Cargo manifest or lockfile drift,
13+
and mismatched Cloud or Gateway dependencies. It also parses and generates all
14+
tracked Cloud product-configuration fixtures and rejects HCL/Terraform product
15+
configuration in the Cloud integration surface.
16+
17+
## Proposing An Update
18+
19+
1. Update the component in its own repository and obtain an immutable release
20+
or full commit revision.
21+
2. Update the root submodule gitlink and the corresponding `component` block.
22+
Keep component and protocol blocks sorted by label, and keep attributes in
23+
the order produced by `a3s-acl`.
24+
3. Update exact dependency declarations and Cargo lockfiles in the owning
25+
component repository before moving its root gitlink.
26+
4. Run `just cloud-stack-check` from a clean recursive checkout.
27+
5. Include the printed compatibility-lock digest and component revisions in
28+
the pull request evidence. Do not publish the compatibility update until the
29+
Cloud contract gate passes.
30+
31+
The compatibility lock does not replace component release processes. A lock
32+
change is integration evidence: each component still owns its implementation,
33+
tests, release notes, and publication.

compat/cloud-stack.acl

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
stack "cloud" {
2+
format = 1
3+
owner = "A3S-Lab/Cloud"
4+
rust_version = "1.88.0"
5+
schema = "a3s.cloud.compatibility-lock.v1"
6+
}
7+
component "acl" {
8+
owner = "A3S-Lab/ACL"
9+
package = "a3s-acl"
10+
path = "crates/acl"
11+
repository = "git@github.com:A3S-Lab/ACL.git"
12+
revision = "ef6fde1614313c14a13a543d37be014eb362776d"
13+
source = "git"
14+
version = "0.2.2"
15+
}
16+
component "boot" {
17+
owner = "A3S-Lab/Boot"
18+
package = "a3s-boot"
19+
path = "crates/boot"
20+
repository = "git@github.com:A3S-Lab/Boot.git"
21+
revision = "aed8a8b213b1675f4c0b6d5a59599fb9fe9a0249"
22+
source = "git"
23+
version = "0.1.1"
24+
}
25+
component "cloud" {
26+
owner = "A3S-Lab/Cloud"
27+
path = "apps/cloud"
28+
repository = "git@github.com:A3S-Lab/Cloud.git"
29+
revision = "85f5d13104e5129a3b9be3f46456b5cb0099ba77"
30+
source = "git"
31+
version = "0.1.0"
32+
}
33+
component "event" {
34+
owner = "A3S-Lab/Event"
35+
package = "a3s-event"
36+
path = "crates/event"
37+
repository = "git@github.com:A3S-Lab/Event.git"
38+
revision = "6df3d6551a2a3ab68b2f8271d33a87b078fc8151"
39+
source = "git"
40+
version = "0.3.0"
41+
}
42+
component "flow" {
43+
owner = "A3S-Lab/Flow"
44+
package = "a3s-flow"
45+
path = "crates/flow"
46+
repository = "git@github.com:A3S-Lab/Flow.git"
47+
revision = "d11cc9ab1e859b23c5108882158ade8d296d93ab"
48+
source = "git"
49+
version = "0.4.1"
50+
}
51+
component "gateway" {
52+
owner = "A3S-Lab/Gateway"
53+
package = "a3s-gateway"
54+
path = "crates/gateway"
55+
repository = "git@github.com:A3S-Lab/Gateway.git"
56+
revision = "d20c6eb22628d80c21daa5de42b362a768d99946"
57+
source = "git"
58+
version = "1.0.12"
59+
}
60+
component "orm" {
61+
owner = "A3S-Lab/ORM"
62+
package = "a3s-orm"
63+
path = "crates/orm"
64+
repository = "git@github.com:A3S-Lab/ORM.git"
65+
revision = "6fdeae38032a5134e858cf3985f47d60cb5180ac"
66+
source = "git"
67+
version = "0.1.0"
68+
}
69+
component "runtime" {
70+
owner = "A3S-Lab/Runtime"
71+
package = "a3s-runtime"
72+
path = "crates/runtime"
73+
repository = "git@github.com:A3S-Lab/Runtime.git"
74+
revision = "010588fc36c850b5ef86f1847c0a0e976f1eda82"
75+
source = "git"
76+
version = "0.2.0"
77+
}
78+
component "sentry" {
79+
owner = "A3S-Lab/Sentry"
80+
package = "a3s-sentry"
81+
path = "crates/sentry"
82+
repository = "git@github.com:A3S-Lab/Sentry.git"
83+
revision = "cf93cc28ffe49e6b97d0197da778db923cb4a72f"
84+
source = "git"
85+
version = "0.7.0"
86+
}
87+
component "updater" {
88+
owner = "A3S-Lab/a3s"
89+
package = "a3s-updater"
90+
path = "crates/updater"
91+
source = "workspace"
92+
version = "0.3.0"
93+
}
94+
protocol "cloud-gateway-snapshot" {
95+
level = 2
96+
owner = "A3S-Lab/Cloud"
97+
schema = "a3s.cloud.gateway-snapshot.v2"
98+
source = "apps/cloud/crates/contracts/src/node/gateway.rs"
99+
}
100+
protocol "cloud-node-command" {
101+
level = 1
102+
owner = "A3S-Lab/Cloud"
103+
schema = "a3s.cloud.node-command.v1"
104+
source = "apps/cloud/crates/contracts/src/node/command.rs"
105+
}
106+
protocol "flow-native-typescript" {
107+
level = 1
108+
owner = "A3S-Lab/Flow"
109+
schema = "a3s.flow.native_ts.v1"
110+
source = "crates/flow/src/protocol.rs"
111+
}
112+
protocol "runtime-capabilities" {
113+
level = 3
114+
owner = "A3S-Lab/Runtime"
115+
schema = "a3s.runtime.capabilities.v3"
116+
source = "crates/runtime/src/contract/capabilities.rs"
117+
}
118+
protocol "runtime-observation" {
119+
level = 2
120+
owner = "A3S-Lab/Runtime"
121+
schema = "a3s.runtime.observation.v2"
122+
source = "crates/runtime/src/contract/observation.rs"
123+
}
124+
protocol "runtime-unit-spec" {
125+
level = 2
126+
owner = "A3S-Lab/Runtime"
127+
schema = "a3s.runtime.unit-spec.v2"
128+
source = "crates/runtime/src/contract/unit.rs"
129+
}

0 commit comments

Comments
 (0)