-
Notifications
You must be signed in to change notification settings - Fork 1
275 lines (227 loc) · 12.7 KB
/
Copy pathci.yml
File metadata and controls
275 lines (227 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: clippy, rustfmt
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Format check
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Test
run: cargo test --workspace
- name: Audit
run: cargo install cargo-audit --locked && cargo audit
stack-graphs-corpus:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Run Stack Graphs Regression Corpus
run: cargo test --test parity_test test_formal_edges -- --nocapture
embeddings:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: clippy
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
# The `embeddings` feature (model2vec-rs). The default model's weights
# are fetched from HuggingFace Hub and checksum-verified by
# crates/calm-core/build.rs::ensure_embedding_weights at compile time
# (2026-07-12 — used to be vendored via Git LFS, which exhausted the
# GitHub account's LFS bandwidth budget; see
# docs/superskills/specs/2026-07-12-edge-release-binary-distribution.md).
# No special checkout step needed here any more — build.rs handles it,
# and degrades to a placeholder (never fails the build) if the fetch
# doesn't succeed, same as before.
- name: Clippy (embeddings)
run: cargo clippy -p calm-core --all-targets --features embeddings -- -D warnings
- name: Test (embeddings)
run: cargo test -p calm-core --features embeddings
no-stack-graphs-formal:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: clippy
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
# D1 (2026-07-30 stack-graphs-demotion-lever): the ONLY dependency
# chain in the whole workspace that pins core `tree-sitter` to "^0.24"
# (verified via `cargo tree -i -p tree-sitter@0.24.7` -- real precedent
# for why this matters: Perl was dropped from the 25-language list
# (2026-07-10) for exactly this reason, see
# docs/superskills/plans/2026-07-10-25-language-expansion.md §1.4).
# `resolver::formal` compiles to a same-API stub without this feature
# (crates/calm-core/src/resolver/mod.rs) -- this job is the only CI
# coverage of that stub actually compiling and behaving correctly
# (`cargo check` alone can silently bit-rot a cfg branch nothing else
# ever builds). Keeps every OTHER default feature on
# (embeddings/tier0-5/scip-overlay) so this isolates JUST the
# stack-graphs-formal absence, not a combination of several features
# being off at once.
- name: Clippy (no stack-graphs-formal)
run: cargo clippy -p calm-core --all-targets --no-default-features --features embeddings,tier0-5,scip-overlay -- -D warnings
- name: Test (no stack-graphs-formal)
run: cargo test -p calm-core --no-default-features --features embeddings,tier0-5,scip-overlay
- name: Verify tree-sitter core is actually unpinned (not just a feature flag on paper)
run: |
set -e
LEAKED=$(cargo tree -p calm-core --no-default-features --features embeddings,tier0-5,scip-overlay 2>&1 | grep -ic "stack-graph" || true)
if [ "$LEAKED" -ne 0 ]; then
echo "::error::stack-graphs family still present in the dependency tree without stack-graphs-formal -- the feature gate is not actually cutting the dependency"
exit 1
fi
all-languages:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: clippy
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
# The 11 Phase B/C languages (kotlin/swift/scala/dart/lua/elixir/
# haskell/ocaml/zig/powershell/groovy) are deliberately NOT in the
# `tier0-5` default bundle (opt-in only until proven stable — see
# calm-core/Cargo.toml's own comment on `lang-kotlin`), which means
# `verify`'s plain `cargo test --workspace` above NEVER compiles or
# tests a single line of their code — `lang_feature_flags_match_*`
# (crates/calm-core/tests/lang_feature_parity.rs) only checks that the
# Cargo.toml *declarations* line up across the 3 crates, not that the
# actual grammar-gated code builds/passes. This job is the real
# coverage: same "all 11 new lang-* features enabled together"
# combination first run by hand at the end of the 2026-07-10/11
# 25-language-expansion session (786 passed then) — promoted to a
# permanent CI job instead of staying a one-off manual check. Bundled
# with `lsp-overlay` too: the D.0-D.4 LspProvider generalization
# (2026-07-11) is also gated behind a non-default feature with no
# other CI coverage.
- name: Clippy (all languages + lsp-overlay)
run: cargo clippy --workspace --all-targets --features tier0-5,lang-kotlin,lang-swift,lang-scala,lang-dart,lang-lua,lang-elixir,lang-haskell,lang-ocaml,lang-zig,lang-powershell,lang-groovy,scip-overlay,lsp-overlay -- -D warnings
- name: Test (all languages + lsp-overlay)
run: cargo test --workspace --features tier0-5,lang-kotlin,lang-swift,lang-scala,lang-dart,lang-lua,lang-elixir,lang-haskell,lang-ocaml,lang-zig,lang-powershell,lang-groovy,scip-overlay,lsp-overlay
# Real cross-SDK MCP interop check (2026-07-14 upgrade item, ported from
# modelcontextprotocol/rust-sdk's own crates/rmcp/tests/test_with_js.rs —
# verified against that real source before porting). Every OTHER test in
# this repo (the `verify`/`all-languages` jobs above, the bash hook
# suite) drives `calm serve` with rmcp's own client code — same SDK,
# same author, on both sides of the wire, so a protocol-shape bug rmcp's
# own client happens to tolerate would never surface. This job is the
# other half: the official TypeScript MCP SDK (@modelcontextprotocol/sdk,
# a genuinely independent implementation) drives a real `calm serve`
# child process over real stdio and validates `tools/list` +
# `tools/call` end-to-end, including strict structuredContent-vs-
# outputSchema validation the TS SDK enforces that rmcp's own test
# client does not — this is exactly what caught a real schema/impl
# mismatch bug (`weak_cross_reference_languages` and 13 sibling fields
# missing `#[serde(default)]`) the very first time this check ran.
js-client-interop:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Build calm binary
run: cargo build --bin calm
# ubuntu-latest already ships a recent Node.js + npm (same assumption
# release.yml's npm-publish job already makes) — no actions/setup-node
# needed.
- name: Install JS interop test dependencies
working-directory: tests/js_client_interop
run: npm ci
- name: Run cross-SDK MCP interop check
working-directory: tests/js_client_interop
run: node client.mjs "$GITHUB_WORKSPACE/target/debug/calm" "$GITHUB_WORKSPACE/crates/calm-core/tests/fixtures/rust_workspace"
# Feature-matrix coverage for the 2026-07-28 OTel/HTTP upgrade
# (docs/superskills/plans/2026-07-28-otel-http-dynamic-toolsets.md) --
# `verify`'s plain `cargo build/test --workspace` above never compiles a
# single line of otel.rs/http.rs, same gap `all-languages` closes for the
# opt-in language features.
#
# The single-otel-version guard below locks in the audit's A2 finding
# (opentelemetry Rust crates version-skew: a bare `cargo add` to latest
# resolves opentelemetry to two coexisting core versions, silently
# broken) so a future dependency bump can't reintroduce it unnoticed.
# Uses `cargo metadata | jq` on the exact package name, NOT a `cargo
# tree | grep` substring match: a bare `grep -c 'opentelemetry v0.3[^1]'`
# (no tree-connector anchor) false-positive-matches the *substring*
# inside `tracing-opentelemetry v0.32.1` -- verified live 2026-07-28,
# that naive pattern reports count=1 even in the correctly-pinned,
# healthy state, which would make this job permanently red. `jq`
# filtering on `.name == "opentelemetry"` operates on cargo's own
# structured package list, so it can't confuse a real second core with
# an unrelated crate whose name happens to contain the same substring.
otel-http-features:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: clippy
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Clippy (otel)
run: cargo clippy -p calm-cli --features otel -- -D warnings
- name: Test (otel)
run: cargo test -p calm-cli --features otel
- name: Guard against opentelemetry core version skew (locks in audit A2 finding)
run: |
VERSIONS=$(cargo metadata --format-version 1 --features otel \
| jq -r '.packages[] | select(.name == "opentelemetry") | .version' | sort -u)
COUNT=$(printf '%s\n' "$VERSIONS" | grep -c .)
echo "Resolved opentelemetry core version(s): $VERSIONS"
if [ "$COUNT" -ne 1 ]; then
echo "::error::Expected exactly ONE resolved 'opentelemetry' core version, found $COUNT: $VERSIONS"
exit 1
fi
if ! printf '%s\n' "$VERSIONS" | grep -q '^0\.32\.'; then
echo "::error::Resolved opentelemetry core is $VERSIONS, expected the pinned 0.32.x line -- update crates/calm-cli/src/otel.rs's version-note comment and Cargo.toml's pin comment together if this is an intentional bump"
exit 1
fi
- name: Clippy (http)
run: cargo clippy -p calm-server -p calm-cli --features http -- -D warnings
- name: Test (http)
run: cargo test -p calm-server -p calm-cli --features http
# Wires `calm fitness-check` (README: "CI gate, exits 1 on failure") into
# actual CI — previously documented as a CI gate but never invoked by any
# workflow, so a declared `[[boundaries]]`/threshold violation could sit
# "over gate" indefinitely without ever failing a build. Runs `calm index`
# first since fitness-check reads `import_edges`/`symbols` from this repo's
# own `.calm/index.db`, which a fresh checkout doesn't have yet.
fitness-check:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
- name: Build calm binary
run: cargo build --bin calm
- name: Index this repo
run: ./target/debug/calm index --project-root .
- name: Fitness check
# --config is NOT optional despite the CLI's "uses defaults if not
# provided" framing: the numeric thresholds do have real defaults,
# but [[boundaries]]/[config_drift] have no conceptual default
# (an empty rule set) — omitting --config silently skips checking
# this repo's own declared boundary rules entirely rather than
# erroring, verified locally (`no [[boundaries]] rules declared`).
run: ./target/debug/calm fitness-check --project-root . --config thresholds.toml