Repository navigation
1.2.50
·
215 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
- Push alerts are sealed with post-quantum encryption wherever the daemon
can. Every alert is end-to-end encrypted, so the relay that forwards it
never sees plaintext, but thex25519sealing behind that is the kind a
future quantum computer could break, and traffic recorded today could be
decrypted then. A device paired under thexwingsuite closes that
window: its alerts are sealed with X-Wing (ML-KEM-768 + X25519), a
hybrid of post-quantum and classical key exchange, through HPKE in base
mode (HKDF-SHA256, AES-256-GCM). Thepushextra carries the
cryptographylibrary that seals it on every platform with a wheel, so
post-quantum sealing needs no further install step.GET /whoaminames
the suites a daemon can seal to assealableSuites; the app pairs under
xwingwhen it is listed, moves an existingx25519pairing up on its
own once a daemon starts advertisingxwing, and moves anxwing
pairing back down if its daemon stops sealing it. The post-quantum key
material costs 1136 bytes of the fixed notification budget, so an
xwingalert carries a shorter log tail. A daemon without the library
refusesxwingpairings and says so at startup,x25519pairings are
unchanged, and the wire construction is normative in
docs/relay-protocol.md. - Post-quantum sealing ships in every release binary and container image
whose platform can compile it. Where PyPI publishes nocryptography
wheel, CI builds the library from source against an OpenSSL 3.5 it
installs or builds: for the Linux builds without a wheel (including the
glibclinux-armv6for the Raspberry Pi 1 and Zero), for
windows-arm64, for the FreeBSD, OpenBSD, NetBSD, and illumos builds,
and for every image platform. A build that fails to compile the library
ships without the suite, and each one that succeeds proves itself with a
real X-Wing seal before it is frozen in. Intel
macOS and 32-bit Windows carrycryptography48.x, the last line with a
wheel for them. Thelinux-ppc64lebinary needs glibc 2.28 rather than
2.17, the floor of the only ppc64le wheel. Theillumos-amd64binary
also carries the push reporter itself, with libsodium from the OmniOS
extra publisher.linux-mips64leandlinux-armelsealx25519only,
because no Rust toolchain exists for their architectures. - A daemon event alert whose subject or message is empty leaves that field
out of the sealed plaintext instead of sending it asnull, which is what
the relay protocol's field contract specifies. - The reaper learns of a finished job through a done callback on that job's
wait task, and filing the completion is one list append however many jobs
are running. Draining 500 completions one at a time with 500 jobs running
measures 6 ms locally against 50 ms. - A bare
cronstable --versionprints the version before it builds the
argument parser and its subparsers. The command measures 54 ms locally
against 64 ms. - The SLA pass walks a memoized list of the jobs that carry an
slablock
and reads the latch map to find a latch left on a job whose block a
reload removed. One pass over 2,000 jobs with 20 SLA blocks measures
0.02 ms locally against 0.15 ms; over 10,000 jobs with 100 blocks,
0.09 ms against 0.79 ms. - The Prometheus scrape carries a rendered block on each shared per-job
label set, renders small integral values from a table filled on the
first scrape, builds each sample line as one string, and keeps its
sorted job order between scrapes. Two renders of a 500-job exposition
with run counters measure 8.7 ms locally against 13 ms. - The calendar feed folds each line once as it builds it, describes each
distinct schedule without anHitem once, and stops a capped entry
before converting the fire it drops. A 500-entry, seven-day feed
measures 25 ms locally against 43 ms. - The configuration parser forks a strictyaml position pointer with one
list copy, passes a value holding no$through the interpolation walk
without a call, and hands every job with a clean schedule the same empty
findings list. A 300-job parse measures 96 ms locally against 108 ms, an
interpolation walk over 2,000 references 41 ms against 49 ms, and a full
garbage collection with 100,000 jobs resident 34 ms against 99 ms. - The filesystem state store writes each atomic file through its raw
descriptor, opened in binary mode on every platform, lists a records or
documents root withscandirso the directory test reads each entry's
own type, sorts each stream listing once in the order the caller reads it,
and takes its try-lock through the one lock routine's non-blocking lane.
Twenty repeat listings of an unchanged 2,000-record stream measure 83 ms
locally against 103 ms, and a garbage-collection sweep over 2,000 unkept
streams 103 ms against 169 ms. - The dashboard's schedule engine jumps a restricted hour, minute, or
second field straight to its next listed value, keeps one collator for
every name sort, memoizes each schedule's prose, counts the running,
failing, ok, and paused jobs in one pass, and checks a fleet poll against
the response text it parsed. The log drawer keeps its search pattern
compiled across streamed lines, caches each line's stripped and lowercased
text, writes the match count only when it changes, and showsbad regex
in its place for a pattern that doesn't compile. Counting the matches in
a 5,000-line buffer measures 0.04 ms locally against 0.28 ms, and a cold
week walk over 500 schedules 1.75 ms against 4.2 ms. - The terminal dashboard caches short SGR sequences and their bounded
rewrites per theme. Discarded control sequences and oversized rewrites
stay out of the cache. The log drawer, the DAG log tab, and the tail view
bind their style helpers and stream markers once per frame. Restyling a
5,000-line drawer measures 17 ms locally against 25 ms, and a drawer
scroll walk with steady repaints 67 ms against 101 ms. - Config load rejects a job whose name matches a DAG's schedule job
(dag:<dag name>), including collisions across files and includes.
Otherdag:job names and classic crontabs nameddagare valid. - A failed cluster peer poll removes the peer from agreement, including
failures while parsing telemetry. Invalid telemetry fields are discarded
while the peer's membership observation is processed.
Performance vs 1.2.49
Gate: passed. Every metric stayed inside its regression limit.
Both versions ran interleaved on one runner. Time metrics compare the best round of each and memory metrics the median. A negative change means faster or smaller.
A regression gates only when it exceeds both its declared limit and 2 noise bands. The +- column is that band: the round-to-round scatter of the two sides, combined in quadrature.
All benchmark results (97 metrics)
| Benchmark | 1.2.49 | 1.2.50 | Change | Noise +- | Gate (eff.) |
|---|---|---|---|---|---|
| loop.stall_completions_500 | 110.26 ms | 14.92 ms | -86.5% | 1.0% | 25% |
| webui.log_count_5k | 660.0 us | 90.0 us | -86.4% | 4.4% | 303% (declared 25%) |
| webui.week_walk_500 | 7.65 ms | 3.50 ms | -54.2% | 1.2% | 25% |
| ical.render_500x7d | 93.49 ms | 51.46 ms | -45.0% | 2.5% | 15% |
| prometheus.render_500 | 30.04 ms | 17.74 ms | -40.9% | 2.1% | 33.29% (declared 15%) |
| tui.drawer_paint_5k | 223.63 ms | 137.50 ms | -38.5% | 0.4% | 15% |
| tui.log_restyle_5k | 53.01 ms | 32.64 ms | -38.4% | 1.3% | 18.87% (declared 15%) |
| mem.gc_pause_100k | 177.71 ms | 126.70 ms | -28.7% | 4.0% | 25% |
| startup.version | 68.91 ms | 54.48 ms | -28.0% | 0.2% | 25% |
| state.gc_sweep_2k_streams | 59.98 ms | 44.64 ms | -25.6% | 1.7% | 25% |
| config.parse_yaml_300 | 269.36 ms | 202.56 ms | -24.8% | 0.9% | 15% |
| config.parse_yaml_3k | 2.677 s | 2.026 s | -24.3% | 1.0% | 15% |
| config.reload_warm_50 | 61.15 ms | 47.44 ms | -22.4% | 0.8% | 25% |
| config.reload_warm_include_50 | 129.67 ms | 101.46 ms | -21.8% | 0.5% | 25% |
| cluster.parse_summaries_6k | 110.28 ms | 86.99 ms | -21.1% | 0.6% | 15% |
| schedule.reseed_local_20k | 118.99 ms | 94.86 ms | -20.3% | 1.1% | 15% |
| cronexpr.test_match_200k | 33.60 ms | 26.94 ms | -19.8% | 2.2% | 29.76% (declared 15%) |
| config.interp_2k | 97.18 ms | 78.35 ms | -19.4% | 0.4% | 15% |
| webui.radar_walk_500 | 470.0 us | 390.0 us | -17.0% | 0.0% | 425.5% (declared 25%) |
| schedule.due_pass_100k | 18.23 ms | 15.44 ms | -15.3% | 1.8% | 54.85% (declared 25%) |
| config.reload_gc_100k | 2.849 s | 2.417 s | -15.2% | 1.2% | 25% |
| startup.validate_config_100 | 256.12 ms | 223.60 ms | -13.6% | 0.2% | 25% |
| mem.jobconfig_2k | 1.70 MB | 1.49 MB | -12.6% | 0.1% | 29.42% (declared 15%) |
| startup.job_set_id_100 | 259.99 ms | 229.53 ms | -12.6% | 0.4% | 25% |
| cronexpr.occurrences_1k | 16.18 ms | 14.19 ms | -12.3% | 2.1% | 61.8% (declared 15%) |
| schedule.suggest_slot_5k | 4.90 ms | 4.31 ms | -12.2% | 6.2% | 203.9% (declared 15%) |
| state.list_records_warm | 144.04 ms | 126.70 ms | -12.0% | 0.5% | 15% |
| cronexpr.next_simple | 43.81 ms | 38.72 ms | -11.6% | 1.9% | 22.83% (declared 15%) |
| schedule.reseed_100k | 232.53 ms | 205.71 ms | -11.5% | 1.9% | 15% |
| json.roundtrip_3k | 658.32 ms | 588.55 ms | -10.6% | 0.9% | 15% |
| mem.rss_version | 16.22 MB | 14.62 MB | -9.9% | 0.5% | 25% |
| schedule.next_fires_2k | 29.82 ms | 27.00 ms | -9.5% | 1.2% | 33.53% (declared 15%) |
| json.roundtrip_orjson_3k | 235.90 ms | 213.96 ms | -9.3% | 0.5% | 15% |
| startup.import_config | 104.61 ms | 97.11 ms | -8.6% | 0.4% | 25% |
| state.fanout_gather_100 | 27.15 ms | 24.81 ms | -8.6% | 4.9% | 36.83% (declared 25%) |
| mcp.handle_200 | 144.32 ms | 132.40 ms | -8.3% | 0.5% | 15% |
| schedule.duplicates_20k | 19.32 ms | 17.74 ms | -8.2% | 5.2% | 51.75% (declared 15%) |
| cluster.job_owner_2k | 65.18 ms | 60.21 ms | -7.6% | 3.1% | 15% |
| schedule.pressure_20k_48h | 18.21 ms | 16.88 ms | -7.3% | 5.9% | 54.93% (declared 15%) |
| cronexpr.next_complex | 17.28 ms | 16.05 ms | -7.1% | 1.1% | 57.87% (declared 15%) |
| schedule.cold_build_100k | 543.51 ms | 505.88 ms | -6.9% | 0.8% | 15% |
| dag.plan_claim_10k | 17.92 ms | 16.70 ms | -6.8% | 3.6% | 55.81% (declared 15%) |
| loop.stall_metrics_2000 | 29.36 ms | 27.55 ms | -6.2% | 1.8% | info |
| state.mutate_document_1k | 227.91 ms | 215.20 ms | -5.6% | 0.5% | 25% |
| cronexpr.next_dst_2k | 36.70 ms | 34.71 ms | -5.4% | 1.9% | 27.24% (declared 15%) |
| state.artifact_list_churn | 1.70 ms | 1.61 ms | -5.3% | 4.6% | 293.7% (declared 25%) |
| schedule.lint_250_zoned | 7.94 ms | 7.54 ms | -5.0% | 1.0% | 126% (declared 15%) |
| push.seal_500 | 99.47 ms | 94.65 ms | -4.8% | 0.4% | 15% |
| webui.render_fleet_15x400 | 25.21 ms | 23.99 ms | -4.8% | 0.8% | 25% |
| state.artifact_get_newest | 24.34 ms | 23.26 ms | -4.5% | 1.0% | 25% |
| state.derive_max_warm | 285.97 ms | 273.33 ms | -4.4% | 0.4% | 15% |
| config.jobconfig_3k | 70.34 ms | 67.28 ms | -4.4% | 2.3% | 15% |
| dag.finish_fanin_1k | 4.25 ms | 4.07 ms | -4.2% | 1.2% | 117.6% (declared 25%) |
| webui.render_rows_500 | 17.63 ms | 16.93 ms | -4.0% | 0.5% | 25% |
| state.list_records_2k | 30.31 ms | 29.18 ms | -3.7% | 1.6% | 32.99% (declared 15%) |
| dag.mapped_drain_256 | 32.30 ms | 31.12 ms | -3.6% | 2.3% | 30.96% (declared 25%) |
| state.derive_max_cold | 27.58 ms | 26.71 ms | -3.1% | 2.1% | 36.26% (declared 15%) |
| redact.clean_20k | 21.16 ms | 20.53 ms | -3.0% | 1.8% | 47.25% (declared 15%) |
| startup.import_cronexpr | 28.42 ms | 28.77 ms | +2.8% | 0.5% | 25% |
| config.parse_crontab_1k | 12.21 ms | 11.89 ms | -2.6% | 1.4% | 81.9% (declared 15%) |
| state.list_documents_600 | 71.06 ms | 69.22 ms | -2.6% | 0.8% | 16.89% (declared 15%) |
| loop.idle_wake_rate | 21.90 ms | 21.35 ms | -2.5% | 1.5% | 25% |
| state.depends_on_past_gate | 3.60 ms | 3.51 ms | -2.5% | 2.9% | 55.59% (declared 25%) |
| state.boot_rehydrate_populated | 49.63 ms | 48.45 ms | -2.4% | 1.0% | 20.15% (declared 15%) |
| dag.adopt_scan_500 | 108.77 ms | 106.24 ms | -2.3% | 1.3% | 25% |
| dag.list_dags_warm | 1.09 ms | 1.11 ms | +2.3% | 2.3% | 183.7% (declared 25%) |
| loop.stall_jobs_500 | 21.54 ms | 21.11 ms | -2.0% | 0.6% | info |
| webui.render_term_5k | 130.35 ms | 127.80 ms | -2.0% | 1.1% | 25% |
| state.lease_renew_200 | 134.15 ms | 131.54 ms | -1.9% | 1.8% | 37.27% (declared 25%) |
| state.kv_roundtrip_200 | 184.99 ms | 181.63 ms | -1.8% | 1.5% | 15% |
| dag.build_chain_10k | 29.40 ms | 28.95 ms | -1.5% | 2.6% | 34.01% (declared 15%) |
| job.stream_capture_120k | 45.70 ms | 45.09 ms | -1.3% | 1.7% | 21.88% (declared 15%) |
| startup.import_daemon | 176.76 ms | 178.65 ms | +1.2% | 0.8% | 25% |
| dag.build_layered_10k | 49.79 ms | 50.35 ms | +1.1% | 3.1% | 20.09% (declared 15%) |
| cronexpr.parse_complex | 24.25 ms | 24.51 ms | +1.1% | 1.3% | 41.23% (declared 15%) |
| webapi.sse_burst_20k | 58.14 ms | 58.74 ms | +1.0% | 1.2% | 15% |
| redact.adversarial_10k | 37.63 ms | 37.32 ms | -0.8% | 0.8% | 26.57% (declared 15%) |
| redact.secrets_5k | 21.02 ms | 21.14 ms | +0.6% | 1.0% | 47.57% (declared 15%) |
| job.report_noop_100k | 48.81 ms | 49.07 ms | +0.5% | 1.9% | 15% |
| dag.list_runs_warm | 12.91 ms | 12.84 ms | -0.5% | 1.6% | 25% |
| cronexpr.parse_simple | 44.93 ms | 45.15 ms | +0.5% | 1.3% | 22.26% (declared 15%) |
| state.append_1k | 724.81 ms | 721.67 ms | -0.4% | 2.3% | 15% |
| webapi.auth_scope_20k | 93.66 ms | 93.29 ms | -0.4% | 0.5% | 15% |
| cluster.fleet_view_15x400 | 90.85 ms | 90.50 ms | -0.4% | 0.5% | 25% |
| dag.advance_quiescent_1k | 73.63 ms | 73.35 ms | -0.4% | 0.7% | 25% |
| startup.python_baseline | 17.32 ms | 17.36 ms | +0.2% | 0.4% | info |
| webapi.jobs_payload_500 | 59.04 ms | 58.92 ms | -0.2% | 0.9% | 16.94% (declared 15%) |
| dag.advance_quiescent_chain | 72.65 ms | 72.51 ms | -0.2% | 1.0% | 25% |
| mem.rss_daemon_import | 36.12 MB | 36.06 MB | -0.2% | 0.2% | 25% |
| resources.monitor_stop_100 | 288.04 ms | 288.44 ms | +0.1% | 1.9% | 25% |
| fingerprint.job_set_id_10k | 297.42 ms | 297.05 ms | -0.1% | 0.5% | 15% |
| tui.log_search_20k | 16.34 ms | 16.33 ms | -0.1% | 0.9% | 61.18% (declared 15%) |
| statsd.emit_2k | 14.74 ms | 14.74 ms | +0.0% | 0.9% | 67.84% (declared 25%) |
| webui.append_line_5k | 15.0 us | 15.0 us | +0.0% | 4.4% | 25% |
| webapi.jobs_bytes_500 | 181.42 KB | 181.42 KB | +0.0% | 0.0% | 15% |
| webapi.jobs_gzip_500 | 5.19 KB | 5.19 KB | +0.0% | 0.0% | 15% |
| mem.crontab_10k | 2.80 MB | 2.80 MB | +0.0% | 0.0% | 17.85% (declared 15%) |
What's Changed
- Bump the github-actions group with 6 updates by @dependabot[bot] in #14
Full Changelog: 1.2.49...1.2.50