Repository navigation
1.2.59
- WinGet installs and upgrades use signed setup executables that display
the full cronstable logo in User Account Control (UAC) prompts. Windows
executables and installed application entries use the same logo. The setup
installers support upgrades from existing MSI installations. Standalone
MSI packages are also available. - MCP tool results carry their data as JSON in a second text block after
the one-line summary, so clients that pass onlycontentto the model,
such as Claude Desktop, can answer from it.cron_get_status,
cron_list_jobs, and the three schedule-authoring tools declare an
outputSchema. - The MCP server serves protocol revision
2026-07-28beside2025-11-25
and its predecessors on the same endpoint. A request that carries its
version in_metais served statelessly, withserver/discover,
resultType, cache hints, and checks that theMCP-Protocol-Version,
Mcp-Method, andMcp-Nameheaders match the body. Thecronstable mcp
bridge sets those headers for such frames and passes the daemon's JSON-RPC
errors through; its own transport errors use code-31000.
cronstable mcp --checkreports which era the daemon speaks. - A
viewtoken opens a read-only MCP session./mcprequiresview, each
tool requires the scope of its REST route, andtools/listand the
prompts show only what the presented token can call. Anonymous access
(web.anonymousScopes) does not reach/mcp. - MCP pauses, resumes, and gate decisions record the presented token's label
asby. Abyargument tocron_decide_gatemust be a string of at most
100 characters, and the server appends it to the label. cron_run_job,cron_trigger_dag,cron_backfill_dag,
cron_recover_dag, andcron_decide_gatereportdestructiveHint: true
andopenWorldHint: true, so clients that confirm risky calls confirm
these.- MCP resource templates decode percent-encoded values, so
cronstable://jobs/nightly%20backupreads the jobnightly backup. - An MCP prompt is served only when every tool it calls is visible to the
caller:backfill_planneedsreadOnly: false, andblast_radiusleaves
out its workflow and state steps when those toolsets are off.
prompts/getrejects a missing, empty, or non-string argument with
-32602. - The MCP server completes prompt arguments and resource template variables
from job names, workflow names, and recent run keys, and identifies itself
with a description, a website, and the dashboard's icon. - The MCP server rejects tool arguments a tool does not accept, request IDs
that are not strings or integers, and JSON-RPC responses posted by a
client, and its responses echo the negotiatedMCP-Protocol-Version.
cron_pause_jobrefuses a BooleandurationSeconds, and the recovery
tools apply the REST checks tomode,plan_token, and
allow_config_change. - Every
401from the web API carries
WWW-Authenticate: Bearer realm="cronstable". - A reload that restarts the web API keeps each
http://listener's socket
open and passes new connections to the replacement server. Another local
account therefore cannot bind the port during the restart and collect the
bearer token that the dashboard,cronstable tui, andcronstable mcp
send. The running server stops only after its replacement is built, so a
replacement that fails to build leaves it serving.https://and
unix://listeners close and bind again. - Saving or clearing the dashboard token rewrites both calendar feed links
and empties the token field and the pairing sheet, so a shared tab keeps
no copy of the previous token. - A DAG run's
configurationRevisioncovers the names of task environment
variables and leaves out their values, so aviewreader cannot test
guesses for a secret against it. Recovering a run after an environment
value changes does not requireallowConfigChange. Runs whose recorded
revision includes environment values report a configuration change when
recovered.
Performance compared with 1.2.58
Regressions accepted for this release. The following changes exceeded their regression thresholds:
- mcp.handle_200 increased by 16.3% (91.54 ms to 106.42 ms; declared limit 15%; noise: ±0.9%)
Both versions were benchmarked in alternating rounds on the same machine. Results use the lowest runtime and median memory usage across rounds. Negative changes mean less time or memory; positive changes mean more.
Benchmark comparisons (99 metrics)
Noise (±) estimates run-to-run variation across both versions. A result fails the regression check only if the increase exceeds its percentage limit, its minimum absolute change, and 2 times the noise estimate. n/a means too few rounds to estimate noise; the other limits still apply.
The Regression limit column accounts for the minimum absolute change, expressed as a percentage of the baseline. Not enforced marks informational metrics.
Startup times include Python startup overhead. Their percentage changes exclude that overhead when it can be measured separately and leaves a positive runtime in both versions.
| Benchmark | 1.2.58 | 1.2.59 | Change | Noise (±) | Regression limit |
|---|---|---|---|---|---|
| loop.stall_metrics_2000 | 14.16 ms | 17.60 ms | +24.3% | 2.5% | Not enforced |
| webui.log_count_5k | 60.0 us | 70.0 us | +16.7% | 0.0% | 3333% (declared 25%) |
| mcp.handle_200 | 91.54 ms | 106.42 ms | +16.3% (regression) | 0.9% | 15% |
| startup.import_cronexpr | 21.81 ms | 22.08 ms | +5.0% | 0.2% | 25% |
| schedule.lint_250_zoned | 4.43 ms | 4.54 ms | +2.5% | 1.8% | 225.7% (declared 15%) |
| dag.finish_fanin_1k | 2.32 ms | 2.37 ms | +1.8% | 1.6% | 215.2% (declared 25%) |
| webui.week_walk_500 | 2.80 ms | 2.75 ms | -1.8% | 1.3% | 71.43% (declared 25%) |
| loop.idle_wake_rate | 10.33 ms | 10.49 ms | +1.6% | 2.0% | 48.4% (declared 25%) |
| state.artifact_list_churn | 750.1 us | 738.5 us | -1.5% | 4.5% | 666.6% (declared 25%) |
| schedule.next_fires_2k | 17.10 ms | 17.32 ms | +1.3% | 1.0% | 58.47% (declared 15%) |
| mem.gc_pause_100k | 63.19 ms | 63.98 ms | +1.3% | 1.0% | 25% |
| startup.python_baseline | 13.38 ms | 13.22 ms | -1.2% | 0.0% | Not enforced |
| state.depends_on_past_gate | 1.50 ms | 1.49 ms | -1.0% | 1.3% | 133% (declared 25%) |
| dag.list_dags_warm | 576.6 us | 571.2 us | -0.9% | 3.1% | 346.8% (declared 25%) |
| webui.render_fleet_15x400 | 19.09 ms | 18.92 ms | -0.9% | 1.2% | 25% |
| cronexpr.occurrences_1k | 9.88 ms | 9.80 ms | -0.9% | 0.9% | 101.2% (declared 15%) |
| startup.version | 41.22 ms | 41.30 ms | +0.9% | 0.8% | 25% |
| config.reload_gc_100k | 1.631 s | 1.618 s | -0.8% | 0.8% | 25% |
| ical.render_500x7d | 35.55 ms | 35.83 ms | +0.8% | 1.1% | 28.13% (declared 15%) |
| redact.clean_20k | 15.54 ms | 15.66 ms | +0.8% | 0.9% | 64.36% (declared 15%) |
| state.append_1k | 44.12 ms | 43.78 ms | -0.8% | 1.9% | 113.3% (declared 15%) |
| schedule.reseed_local_20k | 61.86 ms | 62.30 ms | +0.7% | 1.0% | 16.16% (declared 15%) |
| dag.build_layered_10k | 37.41 ms | 37.17 ms | -0.6% | 0.4% | 26.73% (declared 15%) |
| schedule.reseed_100k | 139.05 ms | 139.93 ms | +0.6% | 1.3% | 15% |
| statsd.emit_2k | 7.32 ms | 7.36 ms | +0.6% | 2.2% | 136.7% (declared 25%) |
| webui.render_term_5k | 82.60 ms | 83.10 ms | +0.6% | 1.1% | 25% |
| state.boot_rehydrate_populated | 21.08 ms | 20.95 ms | -0.6% | 0.6% | 47.44% (declared 15%) |
| schedule.cold_build_100k | 339.46 ms | 341.43 ms | +0.6% | 1.4% | 15% |
| state.gc_sweep_2k_streams | 16.11 ms | 16.20 ms | +0.6% | 1.0% | 93.13% (declared 25%) |
| job.report_noop_100k | 35.45 ms | 35.25 ms | -0.5% | 1.0% | 15% |
| state.list_records_2k | 12.60 ms | 12.53 ms | -0.5% | 0.4% | 79.34% (declared 15%) |
| cluster.fleet_view_15x400 | 64.81 ms | 65.15 ms | +0.5% | 0.9% | 25% |
| webapi.auth_scope_20k | 60.59 ms | 60.30 ms | -0.5% | 1.1% | 16.5% (declared 15%) |
| dag.mapped_drain_256 | 13.29 ms | 13.22 ms | -0.5% | 0.9% | 75.27% (declared 25%) |
| state.list_records_warm | 74.27 ms | 73.92 ms | -0.5% | 0.4% | 15% |
| cronexpr.next_complex | 10.96 ms | 10.91 ms | -0.5% | 0.5% | 91.27% (declared 15%) |
| webapi.sse_burst_20k | 39.28 ms | 39.10 ms | -0.5% | 0.8% | 15% |
| schedule.suggest_slot_5k | 2.85 ms | 2.84 ms | -0.5% | 1.6% | 351% (declared 15%) |
| schedule.pressure_20k_48h | 10.89 ms | 10.85 ms | -0.4% | 1.3% | 91.79% (declared 15%) |
| state.artifact_get_newest | 9.37 ms | 9.33 ms | -0.4% | 2.9% | 53.36% (declared 25%) |
| state.derive_max_cold | 11.22 ms | 11.18 ms | -0.4% | 1.5% | 89.09% (declared 15%) |
| cronexpr.next_simple | 27.59 ms | 27.71 ms | +0.4% | 1.0% | 36.24% (declared 15%) |
| dag.build_chain_10k | 21.11 ms | 21.19 ms | +0.4% | 0.8% | 47.36% (declared 15%) |
| cronexpr.next_dst_2k | 28.61 ms | 28.71 ms | +0.4% | 0.6% | 34.96% (declared 15%) |
| tui.log_restyle_5k | 22.25 ms | 22.33 ms | +0.4% | 0.9% | 44.94% (declared 15%) |
| startup.import_config | 74.01 ms | 74.07 ms | +0.4% | 0.5% | 25% |
| json.roundtrip_orjson_3k | 148.41 ms | 148.96 ms | +0.4% | 1.5% | 15% |
| cluster.job_owner_2k | 44.09 ms | 44.24 ms | +0.3% | 0.5% | 22.68% (declared 15%) |
| state.lease_renew_200 | 18.71 ms | 18.65 ms | -0.3% | 1.2% | 267.2% (declared 25%) |
| state.fanout_gather_100 | 3.85 ms | 3.86 ms | +0.3% | 4.0% | 259.6% (declared 25%) |
| fingerprint.job_set_id_10k | 219.51 ms | 220.18 ms | +0.3% | 1.2% | 15% |
| tui.drawer_paint_5k | 92.45 ms | 92.69 ms | +0.3% | 0.8% | 15% |
| dag.advance_quiescent_1k | 54.49 ms | 54.35 ms | -0.3% | 0.5% | 25% |
| config.parse_crontab_1k | 8.56 ms | 8.54 ms | -0.3% | 0.4% | 116.8% (declared 15%) |
| schedule.due_pass_100k | 13.00 ms | 12.97 ms | -0.3% | 1.7% | 76.92% (declared 25%) |
| cronexpr.test_match_200k | 18.35 ms | 18.30 ms | -0.2% | 0.4% | 54.51% (declared 15%) |
| schedule.duplicates_20k | 12.31 ms | 12.34 ms | +0.2% | 1.1% | 81.26% (declared 15%) |
| config.interp_2k | 53.48 ms | 53.60 ms | +0.2% | 0.3% | 18.7% (declared 15%) |
| prometheus.render_500 | 12.72 ms | 12.69 ms | -0.2% | 0.3% | 78.61% (declared 15%) |
| state.derive_max_warm | 105.27 ms | 105.50 ms | +0.2% | 0.5% | 15% |
| webui.render_rows_500 | 13.60 ms | 13.63 ms | +0.2% | 0.8% | 25% |
| cluster.parse_summaries_6k | 60.33 ms | 60.20 ms | -0.2% | 0.6% | 16.58% (declared 15%) |
| cronexpr.parse_simple | 31.69 ms | 31.62 ms | -0.2% | 0.9% | 31.56% (declared 15%) |
| dag.adopt_scan_500 | 43.49 ms | 43.41 ms | -0.2% | 0.9% | 45.99% (declared 25%) |
| cronexpr.parse_complex | 15.51 ms | 15.53 ms | +0.2% | 0.7% | 64.49% (declared 15%) |
| job.stream_capture_120k | 29.89 ms | 29.94 ms | +0.2% | 0.6% | 33.45% (declared 15%) |
| mem.rss_daemon_import | 37.35 MB | 37.41 MB | +0.2% | 0.0% | 25% |
| webapi.jobs_payload_500 | 39.96 ms | 40.02 ms | +0.2% | 0.5% | 25.03% (declared 15%) |
| config.parse_yaml_300 | 133.29 ms | 133.49 ms | +0.2% | 0.8% | 15% |
| startup.import_daemon | 137.58 ms | 137.23 ms | -0.1% | 0.3% | 25% |
| redact.secrets_5k | 15.14 ms | 15.12 ms | -0.1% | 0.5% | 66.05% (declared 15%) |
| tui.log_search_20k | 11.40 ms | 11.42 ms | +0.1% | 0.5% | 87.68% (declared 15%) |
| config.reload_warm_50 | 31.31 ms | 31.36 ms | +0.1% | 0.9% | 31.93% (declared 25%) |
| state.list_documents_600 | 31.96 ms | 31.91 ms | -0.1% | 0.2% | 37.55% (declared 15%) |
| state.mutate_document_1k | 97.32 ms | 97.19 ms | -0.1% | 1.2% | 51.38% (declared 25%) |
| dag.plan_claim_10k | 10.62 ms | 10.61 ms | -0.1% | 1.6% | 94.16% (declared 15%) |
| state.kv_roundtrip_200 | 21.62 ms | 21.59 ms | -0.1% | 2.6% | 46.26% (declared 15%) |
| config.parse_yaml_3k | 1.338 s | 1.337 s | -0.1% | 1.4% | 15% |
| resources.monitor_stop_100 | 122.98 ms | 123.11 ms | +0.1% | 0.7% | 25% |
| loop.stall_completions_500 | 5.62 ms | 5.62 ms | -0.1% | 1.3% | 88.91% (declared 25%) |
| startup.validate_config_100 | 158.69 ms | 158.66 ms | +0.1% | 0.7% | 25% |
| loop.stall_jobs_500 | 14.84 ms | 14.83 ms | -0.1% | 0.9% | Not enforced |
| config.reload_warm_include_50 | 67.72 ms | 67.66 ms | -0.1% | 0.4% | 25% |
| redact.adversarial_10k | 25.53 ms | 25.55 ms | +0.1% | 0.4% | 39.17% (declared 15%) |
| mem.jobconfig_2k | 1.63 MB | 1.63 MB | +0.1% | 0.1% | 30.72% (declared 15%) |
| startup.job_set_id_100 | 163.57 ms | 163.51 ms | +0.1% | 0.3% | 25% |
| push.seal_500 | 77.42 ms | 77.47 ms | +0.1% | 0.4% | 15% |
| dag.advance_quiescent_chain | 53.65 ms | 53.68 ms | +0.1% | 0.4% | 25% |
| json.roundtrip_3k | 435.09 ms | 434.86 ms | -0.1% | 0.4% | 15% |
| dag.list_runs_warm | 6.75 ms | 6.75 ms | +0.0% | 0.6% | 29.64% (declared 25%) |
| tui.dag_graph_paint_2k | 194.10 ms | 194.15 ms | +0.0% | 0.2% | 15% |
| mem.rss_version | 14.45 MB | 14.45 MB | +0.0% | 0.1% | 25% |
| config.jobconfig_3k | 43.23 ms | 43.24 ms | +0.0% | 1.1% | 23.13% (declared 15%) |
| webui.radar_walk_500 | 290.0 us | 290.0 us | -0.0% | 0.0% | 689.7% (declared 25%) |
| webui.append_line_5k | 10.0 us | 10.0 us | +0.0% | 6.3% | 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%) |
| mem.retired_output_1k | 0.17 MB | 0.17 MB | +0.0% | 0.0% | 296.4% (declared 15%) |
Full Changelog: 1.2.58...1.2.59