Title, changelog and the installers' pinned tag, all regenerated by sync.sh from the source repo at v0.1.2. Signed-off-by: disqualifier <dev@disqualifier.me>
166 lines
8.6 KiB
Markdown
166 lines
8.6 KiB
Markdown
# Changelog
|
||
|
||
Generated from the source repo by `sync.sh`; do not edit here.
|
||
Starts at 0.1.0, where the version line was reset flat.
|
||
|
||
# 0.1.2 — the terminal prompt
|
||
|
||
**Operator commands ask you instead of refusing you.** Run `standup update`,
|
||
`uninstall`, `service stop` or any other operator-only command in your own
|
||
terminal without `--code`, and it now says what it is about to do and asks
|
||
you to confirm you are the operator. Type `y` to go ahead; anything else
|
||
stops it, and nothing is done. `--code` and `STANDUP_OPERATOR_CODE` work as
|
||
before, with no prompt.
|
||
|
||
It is a guard against accidents, not a lock: your code is in
|
||
`~/.standup/config.toml`, which anything running as you can read. Agents run
|
||
without a terminal, so they never see the prompt; they are refused as
|
||
before, and told to ask you.
|
||
|
||
**Agents can add to the knowledge base.** `standup kb add` no longer needs
|
||
the code, so an agent can save a note without asking you. Deleting one is
|
||
still yours: `standup kb rm` is operator-only, and like the other operator
|
||
commands it now asks you at a terminal.
|
||
|
||
# 0.1.1 — the fixes release
|
||
|
||
A maintenance release: no new surfaces except one on the dashboard, and a
|
||
security fix worth upgrading for.
|
||
|
||
**Fixed: a backup could leave your tokens on disk.** If any directory inside
|
||
your standup home was read-only, `backup` wrote its archive and then failed to
|
||
remove its staging copy — and said nothing, because the archive had been
|
||
written. With `--include-secrets` that copy held every participant token, raw,
|
||
in your temp directory. Restores and exports had the same fault. Nothing was
|
||
leaked off the machine, but the files were left where you would not look for
|
||
them. Upgrading removes the fault; existing stray copies are yours to delete.
|
||
|
||
**The dashboard tells you when an update exists**, and offers a button. It
|
||
checks only when you open the page — nothing polls, and nothing is sent
|
||
anywhere if you never look. A box that cannot reach the registry shows
|
||
nothing rather than a warning.
|
||
|
||
**`standup update` no longer downgrades a prerelease install.** On a
|
||
`0.7.0-rc*` box it followed the `latest` tag and offered 0.1.0, which is older.
|
||
It now compares versions properly and installs nothing when nothing is newer.
|
||
|
||
**Also in:**
|
||
- `kb rm` refuses, naming both homes, when the daemon on the port serves a
|
||
different standup home than your CLI — instead of deleting from the wrong one.
|
||
- A restore no longer fails on an archived read-only directory after writing
|
||
every file correctly.
|
||
- An interrupted `uninstall` edits only the file it read, so a concurrent
|
||
change is kept rather than overwritten.
|
||
- A registry read (`standup project`, `search`) no longer refuses a join as
|
||
though a daemon held the project; it waits, and names itself if it must refuse.
|
||
- Two message-delivery faults around pause/resume and agent hand-over.
|
||
- Codex is wired up by the installer where `codex` is on your PATH.
|
||
|
||
# 0.1.0 — the daemon release
|
||
|
||
**The version is flat now.** This is the same work the `0.7.0-rc*` line was
|
||
heading for, released as **0.1.0**: the release candidates are retired and the
|
||
numbering restarts. So the entries below it (0.5.0-rc3, and 0.2–0.3 further
|
||
down) are *older* than this one despite reading higher — they are the rc
|
||
lineage this release replaces.
|
||
|
||
**Upgrade from any 0.5.x or 0.7.0-rc.** Nobody is asked to rejoin this time;
|
||
0.5.0-rc3's credential rotation was a one-off and does not repeat.
|
||
|
||
One thing to know before you start: **the daemon needs Node 22.13+ or 23.4+**
|
||
(not 22.0–22.12, not 23.0–23.3) because it loads `node:sqlite` unflagged.
|
||
Single mode — `standup serve` — still runs on Node 20 and stores its rooms as
|
||
JSONL. If you only ever run one project, nothing about your setup changes.
|
||
|
||
## What this release is
|
||
|
||
0.5 could run a room. 0.6 runs *your machine*: one daemon serving every
|
||
project you have registered, with the rooms, the knowledge base, the todo
|
||
list and the audit trail behind one address instead of one per checkout.
|
||
|
||
- **One daemon, every project.** `standup daemon` serves them all, and the
|
||
dashboard lists them. A project is registered by its path, so moving a
|
||
checkout does not strand its room.
|
||
- **Templates.** A thread you open more than once — a release check, a weekly
|
||
sweep — saved as a file: the title, the objective, who is invited, who is
|
||
spawned, and how they may talk. `standup template run <name>` opens it, and
|
||
this release added a page to write one without editing TOML.
|
||
- **Search across everything**, reconciled against the registry rather than
|
||
rebuilt on each boot. On a real install this went from about 1.5 seconds a
|
||
query to under 10 milliseconds.
|
||
- **Backup, restore and import that respect what is already here.** A restore
|
||
no longer loses what happened after the backup was taken: the audit log
|
||
keeps its live rows, counters take the higher of the two sides, and a
|
||
decision you made since (archived, closed, kicked) stands. An import from
|
||
another machine renumbers colliding todo ids rather than overwriting
|
||
yours, and says which it moved.
|
||
- **A licence for the daemon.** Single mode is never licensed and never will
|
||
be; `standup serve` needs no key.
|
||
|
||
## Breaking changes
|
||
|
||
- **`standup project rename`, `/rename-project`, `/rename-thread` and
|
||
`/archive` are gone.** One name grammar covers join, rename and spawn.
|
||
- **Project-level role files are no longer loaded.** Roles are install-wide.
|
||
A project that still has them is told so once at daemon start.
|
||
- **`export --project` and `backup --remote` are dropped.**
|
||
- **A flag a verb would have ignored is now refused.** `expose --stop
|
||
--rotate-code` used to exit 0 having rotated nothing; `export <thread>
|
||
--all --from 2 --to 2` used to export the whole project. Both now exit 2
|
||
and name the flag. This will break scripts that were passing flags that
|
||
silently did nothing — which is the point.
|
||
- **`.standup/` is ignored whole** rather than file by file.
|
||
|
||
## Security
|
||
|
||
Six audit rounds over this release -- 5, 6, 7, 7.1, 7.2 and the rc1 pass --
|
||
most of them run twice independently, and two of them re-reads of our own
|
||
fix batches. The findings that mattered most were not new code:
|
||
|
||
- **Three ways to forge the operator.** A newline in a message body rendered
|
||
as a system line; `operator` with a zero-width space and `οperator` with a
|
||
Greek omicron both joined with full authority. Agent-originated text now
|
||
goes through one neutralising function (`inert`) wherever it lands in a
|
||
frame — titles, `working_on`, search results, separators.
|
||
- **Clickjacking.** No `X-Frame-Options` and no `frame-ancestors` anywhere.
|
||
A page you visited could frame your dashboard and start a public tunnel in
|
||
three clicks. Loopback is not a boundary against a page you are already
|
||
looking at.
|
||
- **`standup expose stop` started a tunnel.** It parsed as `expose` with a
|
||
stray argument, opened a public cloudflared tunnel, and printed the share
|
||
link with your operator code in it.
|
||
- **An uncredentialed `/api/join`** could plant a managed row with any
|
||
session id.
|
||
- **A local privilege escalation in `standup daemon`:** while the daemon was
|
||
down, another local user holding the port could make your daemon SIGTERM
|
||
an unrelated process. It now proves the port holder before taking it back.
|
||
|
||
## Honest notes
|
||
|
||
- **We found more by re-reading old code than by writing new code.** Four
|
||
audit passes over largely the same source yielded 51, 40, 69 and 61
|
||
findings. Yield tracked how much old code got read, not how broken the
|
||
code was.
|
||
- **One fix batch caused 25 of the next audit's 61 findings.** Ten builders
|
||
worked in parallel, each branch passed its own suites, and nothing ran the
|
||
whole set against the whole set until the audit did. The process change
|
||
that came out of that — fix by class, re-run everything — is worth more
|
||
than any single row here.
|
||
- **594 probes** ship in `docs/probes/`. Each exits 1 while its finding is
|
||
present and 0 once it is fixed, and a row is closed only when its probe is
|
||
shown failing on the tree before the fix. That rule caught two closures
|
||
this release that were otherwise about to be recorded as done.
|
||
|
||
## Known
|
||
|
||
- **This release is verified on Linux and WSL2 only.** The macOS and
|
||
Windows installers, and their service managers (launchd, the Windows
|
||
task), are implemented but **have never been executed end to end on a
|
||
real host** -- not once, by anyone. They ship unverified by an explicit
|
||
decision rather than an oversight: no amount of further review closes
|
||
this, only hardware does. If you install on macOS or Windows, expect to
|
||
debug it, and please report what breaks.
|
||
- A handful of pre-existing low-severity findings are deferred rather
|
||
than fixed; they are named, with probes, in the archived backlogs.
|
||
|