## slothflowlabs/duckle — v0.6.1…v0.7.0

_130 commits._

### Features
- **feat(security): verify downloaded artifacts against a pinned checksum** (2c69935)
- **feat(settings): show where this workspace keeps credentials** (075dda0)
- **feat(deploy): show what a deploy will send before it sends it** (adf162d)
- **feat(setup): show the administrator token once, so claiming is the whole setup** (6793852)
- **feat(desktop): send a pipeline to a server from the app** (d82c51c)
- **feat(setup): choose where the server runs, and hand over the runner to start it** (e55998b)
- **feat(onboarding): walk every capability once, and let Settings ask again** (3a91195)
- **feat(desktop): author a plan in the app, not only in the console** (2d6e92e)
- **feat(scheduler): the desktop runs plans too, and a plan can be scheduled from the console** (758afad)
- **feat(console): a Plans tab, so an order of pipelines is something you can see** (44094ba)
- **feat(plans): a schedule can fire a plan, not only one pipeline** (992c3ab)
- **feat(plans): several pipelines, in an order somebody chose** (71bd82d)
- **feat(desktop): one question on a first run, and the app sets a server up** (a47bb7f)
- **feat(console): a People tab, so adding a colleague is not a deployment task** (95f9e36)
- **feat(console): manage people and machine keys over the API** (5b06004)
- **feat(console): set a server up in a browser instead of a terminal** (f6a40a8)
- **feat(serve): the console runs on axum, and authorisation is an extractor** (b511bac)
- **feat(desktop): configure a server, and send a pipeline to it** (da61234)
- **feat(console): machines get their own credentials, and accounts move to the database** (4d1f354)
- **feat(console): a credential store in SQLite, with API keys for machines** (5df98b2)
- **feat(serve): land a pipeline on a running server, with its schedule switched off** (df019e2)
- **feat(serve): answer a liveness probe, and stop schedules failing in silence** (0ad6bce)
- **feat(import): a folder of legacy jobs is a migration, not a file dialog** (7b6b5f1)
- **feat(codegraph): index every symbol, so finding code stops costing a file read** (847d3ab)
- **feat(catalog): the graph at a git revision, and what a change does to it** (a540938)
- **feat(catalog): console parity, and a lint that fails CI on a rule nobody will notice** (62260f8)
- **feat(catalog): the Data Catalog screen, and the Home tile stops saying "planned"** (1266e37)
- **feat(catalog): the desktop can read, annotate and inspect the workspace catalog** (6366cea)
- **feat(catalog): record what each run touched, so an asset can say how fresh it is** (452dd1e)
- **feat(catalog): a saved graph knows when the pipelines have moved on** (929b80a)
- **feat(catalog): columns, descriptions, tags and a glossary; a builder that takes documents** (ac68ff5)
- **feat(work): prove the lock excludes before trusting it, and ship the multi-host measurement** (a92ba0a)
- **feat(batches): see queued work, and retry what failed** (701dd62)
- **feat(batch): say whether queued items can safely run at once** (c3653cb)
- **feat(work): a worker that claims queued items and runs them** (7c74d47)
- **feat(foreach): dispatch work as a batch file instead of running it here** (decca68)
- **feat(foreach): an item key, so every row keeps its own watermark** (a61385f)
- **feat(connections): a REST connection holds the auth, the node keeps its request** (5fa6f60)
- **feat(console): read the audit log back** (953c078)
- **feat(alerts): tell someone when a run fails** (46deb7f)
- **feat(catalog): ownership, a console tab and an MCP tool over the workspace graph** (3e1eb37)
- **feat(catalog): the workspace graph between pipelines, not just inside one** (6835534)
- **feat(serve): sign-in, roles and an audit log for the console and editor** (ac0dc09)
- **feat(home): Home is three tiles, modules are one level in** (2c2279a)
- **feat(home): a launcher screen listing everything Duckle can do** (f9e5e61)
- **feat(strings): Text to Columns, splitting a field into named columns** (ebdd156)

### Fixes
- **fix(test): match the ciphertext marker, not its version** (941a319)
- **perf(engine): give the per-stage executor the sink-footer row count** (1dd2614)
- **perf(xml): read a remote stream in 256 KiB chunks, not 8 KiB** (2d75f67)
- **fix(engine): do not glob a sink's path when counting what it wrote** (2306303)
- **perf(engine): take a sink's row count from the file it wrote** (56783e3)
- **perf(engine): count each relation once per run** (2bd85e9)
- **fix(editor): store a reference to a saved connection, not a copy of it** (1477720)
- **fix(editor): keep the saved connection selected after picking it** (95a0e50)
- **fix(editor): show what a saved connection supplies instead of the default** (c92f63f)
- **fix(editor): a saved connection satisfies the fields it supplies** (43c4c22)
- **fix(secrets): bind each ciphertext to the field and connection it belongs to** (386cc4c)
- **fix(params): stop run parameters redefining builtins or injecting shell syntax** (62e66ee)
- **fix(bundle): derive the secrets.enc key with Argon2id and a per-bundle salt** (c1d4c27)
- **fix(desktop): stage sidecars in a private directory instead of shared temp** (2e45315)
- **fix(web): keep decrypted connection secrets out of localStorage** (0ba8bec)
- **fix(security): escape quotes in the console, and keep key material off the file API** (ac848ed)
- **fix(console): refuse an empty credential, and correct what the docs promise** (bc8f0f6)
- **fix(security): gate the streaming run route and correct the update source** (394f175)
- **fix(runner): derive the fallback DuckDB path instead of compiling one in** (e2dd1ac)
- **fix(ui): restore the select arrow and use the brand accent on checkboxes** (fab31a9)
- **fix(git): re-encrypt a legacy plaintext token, and never write it world-readable** (4c05faa)
- **fix(deploy): refuse a pipeline carrying a credential in plain text** (9528139)
- **fix(git): ignore every credential under .duckle before staging** (c6af366)
- **fix(setup): give the Custom path a command that actually works** (582956d)
- **fix(tour): stop guessing which screen owns the app, and be told instead** (632b307)
- **fix(onboarding): the tour goes first, then Home, instead of both at once** (73052f5)
- **fix(plans): a plan's runs were recorded where nothing looks for them** (07bae7c)
- **fix(plans): one plans.json meant two different things in the two products** (ccd694f)
- **fix(console): a plan whose pipelines failed no longer reports that it worked** (eb1a8ef)
- **fix(console): two processes sharing a workspace no longer erase each other's sessions** (4214636)
- **fix(console): sessions that outlive a restart, expire, and travel marked** (eaf2f64)
- **fix(mcp): an agent gets the same catalog a person does** (84659e4)
- **fix(tests): take the env lock before setting DUCKLE_WORKSPACE** (38b464b)
- **fix(runlock): tell "someone else has it" apart from "this cannot be locked"** (65df42d)
- **fix(foreach): a sub-pipeline runs under its own name, not everyone's** (0a04122)
- **fix(rest): a responsePath that is not a pointer still finds the rows** (c019fb1)
- **fix(schedules): a store that will not open is not a store with nothing in it** (53dc323)
- **fix(serve): re-arm an edited cron, bound the request, stop denying auth exists** (d8e45a3)
- **fix(alerts): lock the state, and give every pipeline its own lock file** (6395614)
- **fix(scheduler): report a save that failed, and keep a fire claim** (90a6ddd)
- **fix(catalog): name assets without the password, and see every pipeline** (82649db)
- **fix(scheduler): a scheduled run that never starts is still reported** (0ec6249)
- **fix(alerts): per-rule cooldown, atomic state, and no url in the log** (eea53dc)
- **fix(serve): parse a route once, so the gate and the dispatcher cannot disagree** (bbec7ad)
- **fix(serve): a schedule that stops working now says so** (f2e33ca)
- **fix(errors): a missing local file is not a network error** (a5d8614)
- **fix(scheduler): one schedule store for the desktop app and the console** (26a6a9c)
- **fix(scheduler): lock the pipeline, not the schedule record** (78e0d42)
- **fix(scheduler): stop two processes firing the same schedule at once** (2199662)
- **fix(serve): encrypt connection secrets in the web editor** (95a7115)
- **fix(round): apply the requested precision to Float32 columns** (1fecc45)

### Backend
- **release: v0.7.0** (5d96c95)

### Tests
- **test(console): hold the refusal shape the CI docs promise** (0318359)

### Docs
- **docs(site): give the deploy page the architecture and the walkthrough** (cdb606f)
- **docs: state the positioning as deploy to your servers or cloud** (fbaf327)
- **docs(site): correct the component count on both preview cards** (e87ea8e)
- **docs(site): link the deployment guide from the docs shell** (168f5a0)
- **docs(site): correct the component counts and list the deployment guide** (e93e96e)
- **docs: the client/server architecture, with the uncomfortable parts in it** (37c3e46)
- **docs: warn that a failed run still answers 200, before somebody trusts it** (19b5f4b)
- **docs: promoting from CI, and driving Duckle from another orchestrator** (52e0d46)
- **docs: a walkthrough of the whole server flow, for training people on it** (30215fb)
- **docs(readme): a plan is authored in the desktop app too, and travels between both** (af95b0c)
- **docs(readme): plans, and the two console views the list had lost** (7dbc776)
- **docs: make the capability tables agree with themselves, and stop the counts breaking links** (6e02548)
- **docs: one component count, everywhere** (4f37437)
- **docs: put the reader first, and correct what the file was claiming** (e8e6055)
- **docs: show the deployment path instead of describing it** (e7fa367)
- **docs: make the authentication diagram findable** (83ab6d5)
- **docs: explain who can do what, starting from where the reader is** (1db1d38)
- **docs: a deployment guide for AWS, Azure and Google Cloud** (3fe5ce5)
- **docs: stop apologising for an architecture that is not a limitation** (4450274)
- **docs: say where Duckle runs, because readers were deciding it could not** (d9ed338)
- **docs: document what shipped today, and stop claiming there is no auth** (2c574fc)
- **docs(site): lead with ETL, and stop calling it one pipeline** (ae87682)

### Chore
- **chore: point every reference at slothflowlabs** (c665e03)
- **chore(deps): update the lockfile to clear known advisories** (6e1899c)
- **chore: attribute the binary and the licences to SlothFlowLabs** (975e621)
- **refactor(serve): a route now answers with a value, not a socket** (038304d)
- **chore: keep the local working kit out of version control** (326270e)
- **chore: keep local tooling and generated indexes out of the repository** (397266f)
- **style(home): one accent, and stop covering the top bar** (2e35476)
- **style(home): centre the three tiles and light each in its own brand colour** (5afd98c)
- **refactor(home): three groups instead of four** (a2296b2)

_Recap by [Repo Wrapped](https://repowrapped.com/gh/slothflowlabs/duckle?utm_source=github-action)._