Private beta
Did
run last night?
If you can't answer that, Weev can — for the jobs you already have. One outbound-only agent sees what SQL Server Agent, Task Scheduler and cron already run, and turns every run into evidence. Nothing migrates until you want it to.
01 · The problem
One night of jobs, end to end
The same seven jobs as the graph above, running on cron instead. Four are in a crontab, two are in a runbook, one is in someone's head. Nothing checks that the job before it finished — so when fx_rates overruns by forty minutes, everything downstream runs anyway.
Ran 40 min long
Started before fx finished
Settled on stale rates
02 · The ladder
The Weev agent · UpcomingEscalate one job at a time
Install one outbound-only agent. Within the hour it has found what your schedulers already run. Then each job climbs at its own pace — and steps back down just as mechanically.
01 · Read-only
Observe
The agent discovers the jobs your schedulers already run and streams every run into Weev as a tamper-evident record. Nothing changes on the box.
02 · Wrap
Adopt
The incumbent stays the execution engine; Weev owns the clock, not the run. Same job, same code — the schedule and the record move.
03 · Fire
Own
Weev fires the job through the agent on its declared schedule and dependencies. The incumbent's entry retires.
04 · Full lifecycle
Native
The job is declared in Weev and executed by the agent with the complete lifecycle — held, leased, heartbeated and accounted for like any SDK job.
The rung is chosen per job, recorded per run, and every step has a mechanical rollback. The incumbent keeps firing until Weev owns the run — the cutover you already know, one rung at a time.
03 · The deepening layer
Declare it when
you're ready
Observation needs no code change. When a job graduates — or was born HTTP-reachable — the dependency moves out of a comment and into config that ships on your branch: in the SDK today, or in one weev.yaml when Link Mode lands.
Before · crontab + runbook
0 2 * * * run_settlement.sh
# after ledger_close
# (usually done ~1:40?)
# retry: runbook §4
# ping #payments if it failsFour facts about this job, none of them enforced by anything.
After · SDK Mode
Today
weev.job({
name: "settle",
batch: "nightlySettlement",
predecessors: ["reconBatch", "feeAccrual"] },
async (ctx) => legacy.settle(ctx));After · Link Mode
Upcoming
batches:
nightly-settlement:
jobs:
settle:
http: { path: /jobs/settle }
after: [recon-batch, fee-accrual]Same declaration, two doors. In the SDK your script is the last line, unchanged; in Link Mode an endpoint you already have becomes the job, zero code. Either way it is reviewable, versioned and validated.
A job cannot end up waiting on itself through four hops of indirection.
Every declared dependency resolves to a job that exists and is scheduled to run.
The graph is the schedule. There is no second copy in a runbook to fall out of sync.
// checked on push, not at 02:00
04 · The record
Every run, accounted for
The run, its trigger, its upstreams and its logs in one place — not a Slack alert with a script name in it.
02:00:01 triggered by: graph · deps satisfied (2/2)
02:00:01 heartbeat · payments-01
02:00:47 settling 41,208 rows
02:00:47 holding regulatory_export until complete05 · The console
Every job, every environment,
one screen
What is running, what is blocked, what failed and what is due next — scoped to a project and an environment. This is where the question at the top of this page gets answered.
Connection timeout to rate provider after 30s
Connection timeout to rate provider after 30s
Start with the job you
check every morning.
No new runtime, no port. Cron keeps firing until Weev owns the run — then you delete the line.