Skip to content

docs(skill): API naming contract + dependency refresh, built-in cron scheduler, CI fixes - #145

Merged
owjs3901 merged 36 commits into
mainfrom
devfive/3099154426bffbeef8b62999b80bb038/skill-api-naming-contract
Oct 31, 2026
Merged

owjs3901 merged 36 commits into
mainfrom
devfive/3099154426bffbeef8b62999b80bb038/skill-api-naming-contract

Conversation

@devfive-relay-c70423

@devfive-relay-c70423 devfive-relay-c70423 Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Purpose

Started as a docs-only change (the API naming contract section of SKILL.md, upstreamed from devup-mcp 880787e) and grew into a CI-fix and dependency-maintenance pass. Rust 1.99 Clippy broke the existing tests and the coverage gate, so those are fixed here too. The published-crate impact is recorded in .changepacks/changepack_log_dependency-refresh.json (vespera, vespera_core, vespera_macro, vespera-bridge: Minor; vespera_inprocess, vespera-bridge-gradle-plugin: Patch).

Changes

  • Docs: SKILL.md API naming contract (camelCase wire names, snake_case ERD columns, #[serde(rename_all = "camelCase")] including schema_type! and multipart form_data names).
  • Dependency refresh: Rust crates, Bun/npm (landing app adapted to current Devup UI), GitHub Actions, and the Java side (Spring Boot 3.2.5 -> 4.1.2, Spring 7, JUnit 6.1.3, Gradle wrapper 9.8.2 everywhere). Lockfiles regenerated so transitive deps resolve to the latest compatible release.
  • Lint fixes (Rust 1.99): clippy::assert_is_empty fixed by comparing against Vec::<T>::new(); no #[allow].
  • Coverage fix: the metadata-version fast path in write_response_header compared const &str by ptr::eq, whose result depended on codegen-unit partitioning (tarpaulin dropped to 99.96%). It now compares by content; wire bytes are the same.
  • Bench gate: scripts/bench-interleaved.sh builds the merge base and the PR head separately and runs 5 alternating rounds in one job, so runner drift hits both sides. Same thresholds (median paired change > +30% and min paired round > +20%).
  • Cron scheduler: tokio-cron-scheduler replaced by a small built-in tokio scheduler (vespera::cron) driven by croner 4. #[cron] validation and the runtime now share one parser (vespera_core::cron). A differential run found 28 expressions the macro accepted and the old scheduler rejected at startup (for example /10 and LW).
  • axum default features dropped in vespera and vespera_inprocess (vespera_inprocess normal graph 67 -> 40 crates). vespera_inprocess now declares the tokio sync feature it already used.
  • chrono default features dropped in vespera (keeps serde + now); iana-time-zone and the windows-core proc-macro stack no longer compile.
  • 422 hoist borrows &str from the response body: alloc_budget case F 26 -> 20 allocs/op (budget lowered 26 -> 22). End to end through dispatch_from_bytes: 100 errors 9.46 us -> 8.40 us (-11.8%), 900 errors 77.0 us -> 64.0 us (-16.6%). Escaped strings fall back to the existing lenient owned walk; wire bytes unchanged.
  • Macro codegen trim: export_app! namespacing round-trips through JSON text (vespera_macro LLVM IR 553,831 -> 483,742 lines, -70k); schema! borrows its &str maps (a further -4,967). Own-crate rebuild 3.35 s -> 2.98 s, peak rustc 538 -> ~505 MB (same-session A/B).
  • axum-test -> examples/testkit: a tower-oneshot client with the surface the tests use (~200 lines). 82 integration tests unchanged apart from the import line. Also sea-orm runtime-tokio instead of runtime-tokio-rustls in the sqlite example, and unused dev-deps removed.
  • criterion trimmed to default-features = false + cargo_bench_support (the gate only reads estimates.json).
  • Dependency counts (unique external name+version, all targets, all features, incl. dev): workspace 340 -> 283. Remaining duplicate crate names: 5 (see below).
  • Scale tooling (opt-in, not part of the PR bench gate): scripts/gen-stress-app.ps1, scripts/measure-stress.ps1, crates/vespera_inprocess/benches/extreme.rs, plus scripts/bisect-dep.{sh,ps1}. Finding: no superlinear hot path. macro_expand_crate slope ~1.0 up to 2000 routes, dispatch cost flat from 1k to 50k routes and 1 to 10k registered apps, streaming peak heap constant from 16 MiB to 1000 MiB.

Remaining duplicate crates (5, all upstream-forced)

Crate Versions Path
syn 2 / 3 third-party proc-macros on syn 2 (garde_derive, rstest_macros, sea-orm-macros, ...) vs vespera_macro, serde_derive, thiserror-impl on syn 3
hashbrown 0.16 / 0.17 sea-orm -> sqlx-core -> hashlink 0.11 -> hashbrown 0.16 vs -> indexmap 2.14 -> hashbrown 0.17
heck 0.4 / 0.5 0.4 from sea-orm -> ouroboros_macro, sea-orm-macros -> sea-bae, sea-query -> sea-query-derive; 0.5 from sea-orm-macros and croner -> strum_macros 0.27
strum 0.27 / 0.28 vespera_core -> croner 4.0.2 -> strum 0.27 vs sea-orm -> strum 0.28
itertools 0.13 / 0.14 criterion 0.8.2 (dev) -> itertools 0.13 vs sea-orm -> itertools 0.14

Shipped crates are unaffected: vespera/vespera_core/vespera_macro/vespera_jni have only syn 2/3, vespera_inprocess none. The others exist only in examples/axum-example (sea-orm) and dev-dependencies.

BREAKING / behaviour changes

  • BREAKING: vespera::tokio_cron_scheduler re-export removed; use vespera::cron.
  • BREAKING: vespera-bridge requires Spring Boot 4.1 / Spring Framework 7 / JUnit 6 / Gradle 9.8; Spring Boot 3 is no longer supported.
  • vespera::chrono::Local needs chrono's clock feature, which vespera no longer enables; add it in your own manifest.
  • axum's tracing / tower-log features are no longer forced on by vespera / vespera_inprocess; enable them in your own axum dependency if you relied on that.
  • Wire format is unchanged (wire_contract.rs); examples/axum-example/openapi.json is not committed.

Test plan

Local: cargo clippy --all-targets --all-features -- -D warnings, cargo clippy --workspace --no-default-features -- -D warnings, cargo fmt --check, cargo test --workspace, cargo test --workspace --doc, bun run lint, bun test.

CI (head 04aa5c1, all green): Test (includes the tarpaulin 100% line-coverage gate), Criterion regression gate (interleaved), JNI E2E on ubuntu / windows / macos (vespera-bridge unit suite + demo-app E2E), Rust branch coverage (observational), changepacks, build; deploy is skipped on PRs.

@owjs3901
owjs3901 marked this pull request as ready for review October 30, 2026 11:58
The pre-baked metadata fast path in write_response_header gated on ptr::eq between two const &str uses. A const has no stable address, so whether the fast path fired depended on codegen-unit partitioning: any test-only edit flipped it and the tarpaulin build lost 3 lines (99.96% < 100%). Compare by content (len + 5-byte memcmp): same bytes on the wire, always hits for the engine version.
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Changepacks

vespera@0.4.0 - Cargo.toml

Maybe you forgot to write the following files to the latest version

vespera@0.4.0 → 0.5.0 - crates/vespera/Cargo.toml

Minor

  • Refresh Rust and Java dependencies and support Rust 1.99 Clippy diagnostics. Replace tokio-cron-scheduler (and its second croner/chrono-tz/uuid/tracing tree) with a built-in tokio scheduler driven by croner 4; the compile-time #[cron] validator and the runtime scheduler now share one parser (vespera_core::cron), removing the croner 3/4 mismatch (compile-time-accepted expressions could be rejected at runtime). vespera-bridge now targets Spring Boot 4.1 / Spring Framework 7 / JUnit 6 / Gradle 9.8. axum is now depended on with default-features off (its tracing/tower-log features are no longer forced on; vespera_inprocess drops 27 transitive crates) and vespera_inprocess declares the tokio sync feature it uses. BREAKING: vespera::tokio_cron_scheduler re-export removed (use vespera::cron); vespera-bridge requires Spring Boot 4. vespera now depends on chrono without default features (serde + now): iana-time-zone and the windows-core proc-macro stack are no longer compiled, and chrono's Local clock (the clock feature) is no longer enabled by vespera itself; re-enable it in your own manifest if you use vespera::chrono::Local. vespera_macro no longer compiles a serde Value (de)serializer copy of the OpenAPI types (export_app! namespacing round-trips through JSON text) and schema! borrows its schema maps.

vespera_core@0.4.0 → 0.5.0 - crates/vespera_core/Cargo.toml

Minor

  • Refresh Rust and Java dependencies and support Rust 1.99 Clippy diagnostics. Replace tokio-cron-scheduler (and its second croner/chrono-tz/uuid/tracing tree) with a built-in tokio scheduler driven by croner 4; the compile-time #[cron] validator and the runtime scheduler now share one parser (vespera_core::cron), removing the croner 3/4 mismatch (compile-time-accepted expressions could be rejected at runtime). vespera-bridge now targets Spring Boot 4.1 / Spring Framework 7 / JUnit 6 / Gradle 9.8. axum is now depended on with default-features off (its tracing/tower-log features are no longer forced on; vespera_inprocess drops 27 transitive crates) and vespera_inprocess declares the tokio sync feature it uses. BREAKING: vespera::tokio_cron_scheduler re-export removed (use vespera::cron); vespera-bridge requires Spring Boot 4. vespera now depends on chrono without default features (serde + now): iana-time-zone and the windows-core proc-macro stack are no longer compiled, and chrono's Local clock (the clock feature) is no longer enabled by vespera itself; re-enable it in your own manifest if you use vespera::chrono::Local. vespera_macro no longer compiles a serde Value (de)serializer copy of the OpenAPI types (export_app! namespacing round-trips through JSON text) and schema! borrows its schema maps.

vespera_inprocess@0.4.0 → 0.4.1 - crates/vespera_inprocess/Cargo.toml

Patch

  • Refresh Rust and Java dependencies and support Rust 1.99 Clippy diagnostics. Replace tokio-cron-scheduler (and its second croner/chrono-tz/uuid/tracing tree) with a built-in tokio scheduler driven by croner 4; the compile-time #[cron] validator and the runtime scheduler now share one parser (vespera_core::cron), removing the croner 3/4 mismatch (compile-time-accepted expressions could be rejected at runtime). vespera-bridge now targets Spring Boot 4.1 / Spring Framework 7 / JUnit 6 / Gradle 9.8. axum is now depended on with default-features off (its tracing/tower-log features are no longer forced on; vespera_inprocess drops 27 transitive crates) and vespera_inprocess declares the tokio sync feature it uses. BREAKING: vespera::tokio_cron_scheduler re-export removed (use vespera::cron); vespera-bridge requires Spring Boot 4. vespera now depends on chrono without default features (serde + now): iana-time-zone and the windows-core proc-macro stack are no longer compiled, and chrono's Local clock (the clock feature) is no longer enabled by vespera itself; re-enable it in your own manifest if you use vespera::chrono::Local. vespera_macro no longer compiles a serde Value (de)serializer copy of the OpenAPI types (export_app! namespacing round-trips through JSON text) and schema! borrows its schema maps.

vespera_jni@0.4.0 → 0.4.1 - crates/vespera_jni/Cargo.toml

Patch

  • Auto-update: depends on 'vespera_inprocess' via a local workspace dependency

vespera_macro@0.4.0 → 0.5.0 - crates/vespera_macro/Cargo.toml

Minor

  • Refresh Rust and Java dependencies and support Rust 1.99 Clippy diagnostics. Replace tokio-cron-scheduler (and its second croner/chrono-tz/uuid/tracing tree) with a built-in tokio scheduler driven by croner 4; the compile-time #[cron] validator and the runtime scheduler now share one parser (vespera_core::cron), removing the croner 3/4 mismatch (compile-time-accepted expressions could be rejected at runtime). vespera-bridge now targets Spring Boot 4.1 / Spring Framework 7 / JUnit 6 / Gradle 9.8. axum is now depended on with default-features off (its tracing/tower-log features are no longer forced on; vespera_inprocess drops 27 transitive crates) and vespera_inprocess declares the tokio sync feature it uses. BREAKING: vespera::tokio_cron_scheduler re-export removed (use vespera::cron); vespera-bridge requires Spring Boot 4. vespera now depends on chrono without default features (serde + now): iana-time-zone and the windows-core proc-macro stack are no longer compiled, and chrono's Local clock (the clock feature) is no longer enabled by vespera itself; re-enable it in your own manifest if you use vespera::chrono::Local. vespera_macro no longer compiles a serde Value (de)serializer copy of the OpenAPI types (export_app! namespacing round-trips through JSON text) and schema! borrows its schema maps.

vespera-bridge@0.4.0 → 0.5.0 - libs/vespera-bridge/build.gradle.kts

Minor

  • Refresh Rust and Java dependencies and support Rust 1.99 Clippy diagnostics. Replace tokio-cron-scheduler (and its second croner/chrono-tz/uuid/tracing tree) with a built-in tokio scheduler driven by croner 4; the compile-time #[cron] validator and the runtime scheduler now share one parser (vespera_core::cron), removing the croner 3/4 mismatch (compile-time-accepted expressions could be rejected at runtime). vespera-bridge now targets Spring Boot 4.1 / Spring Framework 7 / JUnit 6 / Gradle 9.8. axum is now depended on with default-features off (its tracing/tower-log features are no longer forced on; vespera_inprocess drops 27 transitive crates) and vespera_inprocess declares the tokio sync feature it uses. BREAKING: vespera::tokio_cron_scheduler re-export removed (use vespera::cron); vespera-bridge requires Spring Boot 4. vespera now depends on chrono without default features (serde + now): iana-time-zone and the windows-core proc-macro stack are no longer compiled, and chrono's Local clock (the clock feature) is no longer enabled by vespera itself; re-enable it in your own manifest if you use vespera::chrono::Local. vespera_macro no longer compiles a serde Value (de)serializer copy of the OpenAPI types (export_app! namespacing round-trips through JSON text) and schema! borrows its schema maps.

vespera-bridge-gradle-plugin@0.4.0 → 0.4.1 - libs/vespera-bridge-gradle-plugin/build.gradle.kts

Patch

  • Refresh Rust and Java dependencies and support Rust 1.99 Clippy diagnostics. Replace tokio-cron-scheduler (and its second croner/chrono-tz/uuid/tracing tree) with a built-in tokio scheduler driven by croner 4; the compile-time #[cron] validator and the runtime scheduler now share one parser (vespera_core::cron), removing the croner 3/4 mismatch (compile-time-accepted expressions could be rejected at runtime). vespera-bridge now targets Spring Boot 4.1 / Spring Framework 7 / JUnit 6 / Gradle 9.8. axum is now depended on with default-features off (its tracing/tower-log features are no longer forced on; vespera_inprocess drops 27 transitive crates) and vespera_inprocess declares the tokio sync feature it uses. BREAKING: vespera::tokio_cron_scheduler re-export removed (use vespera::cron); vespera-bridge requires Spring Boot 4. vespera now depends on chrono without default features (serde + now): iana-time-zone and the windows-core proc-macro stack are no longer compiled, and chrono's Local clock (the clock feature) is no longer enabled by vespera itself; re-enable it in your own manifest if you use vespera::chrono::Local. vespera_macro no longer compiles a serde Value (de)serializer copy of the OpenAPI types (export_app! namespacing round-trips through JSON text) and schema! borrows its schema maps.

The metadata fast path in write_response_header compares the version by content, so cover an owned copy of the engine version alongside the borrowed one and drop the stale pointer-eq wording. Audit of ptr::eq/as_ptr/Arc::ptr_eq in crates/ found no other branch selection that depends on const/static addresses: slice_from_owner is a bounds-checked range test on real allocations that falls back to the copying path, the JNI overlap check compares live direct-buffer ranges, and the remaining Arc::ptr_eq/ptr::eq uses are test assertions on real allocations.
clippy::assert_is_empty rejects assert!(x.is_empty()) and its suggested fix was assert_eq!(x, [] as [T; 0]). Compare against Vec::<T>::new() instead: same failure output (the value is printed), no cast-to-zero-length-array noise, no lint suppression. The inline attrs assertion becomes an exact length check.
scripts/bisect-dep.sh and .ps1 binary-search the published releases of one
crate with cargo update -p X --precise V, using a git-bisect-run style
exit-code probe, and always restore Cargo.lock. Verified in both shells
against a synthetic probe (either 1.13.0..1.19.0 finds first bad 1.17.0).
The Criterion gate measured the merge base in one block and the PR head in a
later block, so runner drift showed up as fake regressions (PR #144's two
byte-identical sides swung -12%..+15% and tripped a different bench each run).

scripts/bench-interleaved.sh now builds both sides (separate fresh target
dirs: a shared one makes cargo judge the second build "fresh" by mtime and
silently benchmark one binary against itself), then runs 5 alternating
base/head rounds with per-side CRITERION_HOME. A bench fails iff the median
paired change (head/base - 1 inside a round) exceeds +30% AND the min of the
paired rounds (the sign-test lower confidence limit of the median) exceeds
+20%: same thresholds, but one noisy round cannot trip the gate any more.

Local evidence (Git Bash, 16 gated benches, 5 rounds):
- A/A: all medians within +-4%, worst single round -13%; no failures.
- Injected ~2us spin in write_status_code (uncommitted, reverted): exit 1,
  8 benches flagged with every paired round > +58% (e.g. resolve_path
  +157% median / +149% min); unaffected wire_path/1024 stayed at -0.3%.
The #[cron] macro validated with croner 4 (sloppy ranges) while the runtime
tokio-cron-scheduler parsed with croner 3. A differential run against
Job::new_async found 28 divergent expressions where the macro accepted what
the scheduler rejected at startup (a step without a start such as "/10",
and the "LW" day-of-month token).

Rather than patch the validator, both sides now share one parser
(vespera_core::cron, croner 4) and a small scheduler (vespera::cron)
replaces tokio-cron-scheduler. The second croner, chrono-tz, uuid, tracing
and num-* crates leave the cron feature's graph (320 -> 313 resolved
name+version pairs workspace-wide; the croner duplicate is gone). Unused
example dependencies and dead [build-dependencies] are removed as well.

BREAKING: vespera::tokio_cron_scheduler re-export is removed.
Micro benches hide per-op costs that compound in large applications, so add
opt-in scale tooling (not part of the PR bench gate, not a workspace member):

- scripts/gen-stress-app.ps1 + scripts/measure-stress.ps1: emit a standalone
  N-route vespera app (schemas, enums, wide/circular/deep types, schema_type!)
  and report clean/incremental build time, macro_expand_crate, peak rustc
  working set and the log-log scaling slope. -Control/-Keep attribute cost to
  serde, vespera attributes, vespera! or a hand-written axum router.
- crates/vespera_inprocess/benches/extreme.rs: size ladders for route tables
  (1k-50k), headers (10-10k), header values (ASCII/Unicode/escape-heavy),
  422 envelopes (10-100k, crossing the 64 KiB hoist cap), long paths/queries,
  buffered bodies to 100 MiB, streaming to 1000 MiB with a counting allocator
  (peak heap), 1k-100k concurrent dispatches, 100-10k registered apps, thread
  scaling. Every case asserts the status it claims to measure.

Findings (see PR notes): dispatch cost is flat from 1k to 50k routes and from
1 to 10k registered apps; per-header and per-error costs are flat; streaming
peak heap is constant from 16 MiB to 1000 MiB. No superlinear hot path in
vespera_macro (macro_expand_crate slope ~1.0 up to 2000 routes).

Cargo.lock and bun.lock are regenerated from scratch so every transitive
dependency resolves to its latest compatible release.
Bumps (via dependency-check-updates): Spring Boot 3.2.5 -> 4.1.2 (bridge,
demo-app), spring-test 6.1.6 -> 7.0.10, JUnit 5.10.2 -> 6.1.3, AssertJ 3.27.7,
Jackson 2.22.4, vanniktech maven-publish 0.37.0, plugin-publish 2.2.1,
Gradle wrapper 9.8.2 everywhere (the demo was still on 8.11.1).

Code changes needed for the major migration:
- HttpStatus.PAYLOAD_TOO_LARGE -> CONTENT_TOO_LARGE (Spring 7 deprecation).
- Tests: HttpHeaders is no longer a Map (containsKey -> containsHeader);
  the renamed 413/422 constants must match what getStatusCode() returns.
- demo-app tests: TestRestTemplate moved to spring-boot-resttestclient
  (+ @AutoConfigureTestRestTemplate, spring-boot-restclient); Jackson 3 is
  now Boot's default so the test builds its own Jackson 2 ObjectMapper.

Verified on JDK 17: vespera-bridge 297 tests / 0 failures, demo-app E2E
43 tests / 0 failures (6 bench-gated skips, unchanged). JNI latency on the
real cdylib (median of 3 interleaved runs, ns/op): sync 1611 -> 1556,
direct 1569 -> 1527, response-streaming 2052 -> 1982, bidirectional
2232 -> 2165, async 14123 -> 14278; allocated bytes/op within +-3%.
vespera-bridge moves to Spring Boot 4 (breaking for Boot 3 consumers, so a
minor bump while 0.x); the Gradle plugin only changes build tooling (patch).
vespera_inprocess only needs axum's Router, yet pulled axum's default
feature set (hyper, hyper-util, serde_urlencoded, tracing, ...). Turning
default features off takes its normal dependency graph from 67 to 40
crates; vespera goes from 151 to 147 (it still enables form/json/query/
multipart/http1/tokio explicitly). Behaviour change: axum's rejection
logging through tracing is no longer forced on; applications that want it
keep it through their own axum dependency (Cargo unifies features).

Dropping the implicit features exposed that vespera_inprocess used
tokio::sync::mpsc without declaring tokio's "sync" feature (it only built
because axum enabled it); declare it, and give the tests/benches the axum
and tokio features they use as dev-dependencies.
The 422 hoist deserialized path/code/message into owned Strings (two to
three allocations per error). They now borrow from the body as Cow<str>
through a small BorrowedStr deserializer (serde's own Cow<str> impl always
allocates) and are owned only when the JSON string held an escape.
ValidationErrorItem gains a lifetime; the wire bytes are unchanged
(wire_contract and the hand-vs-serde round-trip tests pass).

Same-run criterion A/B vs the saved baseline (hoist_422_ab, typed_new):
  errors_1   103.1 ns -> 95.0 ns  (-5.2%,  p < 0.05)
  errors_5   370.7 ns -> 321.6 ns (-14.7%, p < 0.05)
End to end through dispatch_from_bytes (extreme bench, errors_422):
  100 errors 9.46 us -> 8.58 us (-10.0%, p < 0.05)
  900 errors 77.0 us -> 68.5 us (-11.1%, p < 0.05)
  10 errors: -2.3%, not significant.
alloc_budget case F: 26 -> 19-21 allocations per 422 dispatch; the budget is
tightened from 26 to 22 (down only).
The generic PhantomData visitor left one line (the generic Visitor impl
header) reported uncovered by tarpaulin's llvm engine under the CI rustfmt
layout, failing the 100% line-coverage gate. The visitor now yields a plain
Cow<'de, str> and the wrapper is applied with .map(BorrowedStr): no
lifetime-parameterised helper type, same behaviour, fewer lines.
cargo llvm-cov shows every line of hoist.rs executed.
tarpaulin (llvm engine, CI rustfmt layout) still reported the BorrowedStr
Deserialize impl header uncovered, failing the 100% line-coverage gate.
Remove the custom deserializer: the strict typed pass now deserializes
path/code/message as Option<&str> borrowed from the body. A string holding
an escape cannot be borrowed, so that pass fails and the existing lenient
serde_json::Value walk hoists the same errors with owned values (it already
handles wrong-typed fields). Less code, one fewer type, and the common
escape-free envelope allocates nothing per error.

Same-run criterion A/B vs the saved baseline (p < 0.05 for all):
  hoist_422_ab typed_new errors_1   103.1 ns -> 99.4 ns  (-3.7%)
  hoist_422_ab typed_new errors_5   370.7 ns -> 326.4 ns (-13.3%)
  dispatch errors_422/10            -7.7%
  dispatch errors_422/100           9.46 us -> 8.40 us (-11.8%)
  dispatch errors_422/900           77.0 us -> 64.0 us (-16.6%)
alloc_budget case F: 26 -> 20 allocations per 422 dispatch (budget 22).
Test: plain strings are Cow::Borrowed, escaped strings still hoist unescaped.
vespera_macro: namespace_export_schemas round-trips the spec through JSON text
instead of serde_json::to_value/from_value, so the Value (de)serializer copy of
every OpenAPI type's serde impl is no longer compiled into the proc-macro
(LLVM IR lines 553,831 -> 483,742; own-crate rebuild 3.35s -> 2.98s, peak rustc
538 -> ~505 MB in a same-session A/B). schema! borrows the known-schema maps
from schema storage as &str instead of cloning into String maps, which also
drops the duplicate String monomorphization of the schema parser (-4,967 IR
lines).

axum-example: sea-orm runtime-tokio instead of runtime-tokio-rustls. The example
only uses sqlite, so rustls/ring/webpki/untrusted and the second getrandom and
windows-sys versions leave the lockfile (workspace unique crates 340 -> 321).
…graph

vespera: chrono without default features (serde + now). The crate only needs
the DateTime types, serde support and Utc::now() for the cron scheduler, so
iana-time-zone and the windows-core/-implement/-interface proc-macro stack no
longer compile for every user. `vespera::chrono::Local` (chrono's `clock`
feature) is no longer enabled by vespera itself.

criterion (vespera, vespera_inprocess dev-deps): default-features = false with
cargo_bench_support only. The regression gate reads estimates.json, so rayon,
plotters and the html_reports/gnuplot plumbing were unused.

examples/third: drop the axum-test and insta dev-dependencies it never used
(cargo machete clean).

Lockfiles: log 0.4.35 (cargo update); bun.lock transitive refresh. Every direct
Cargo, npm, Gradle and workflow dependency is at its latest release.

Unique external crates: `vespera` default features 178 -> 154, workspace
(all targets and features) 340 -> 313.
The examples' integration tests used axum-test for TestServer + multipart
forms. It brought 30 crates (hyper, reserve-port, expect-json, typetag,
rand 0.10 -> chacha20 -> a second cpufeatures, ...) into the dev graph for a
handful of calls. examples/testkit drives the router with tower's oneshot and
implements exactly the surface the tests use (get/post/put/patch, json,
multipart, bytes/content_type/add_header, status/text/json assertions); the
82 integration tests are unchanged apart from the import line.

Workspace unique external crates (all targets/features, incl. dev) 313 -> 283;
duplicate crate names 6 -> 5 (cpufeatures gone). Changepack note updated for
the chrono and proc-macro changes.
@owjs3901 owjs3901 changed the title docs(skill): add the API naming contract docs(skill): API naming contract + dependency refresh, built-in cron scheduler, CI fixes Oct 31, 2026
@owjs3901
owjs3901 merged commit fc32f59 into main Oct 31, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant