A changelog, kept from now rather than assembled at the end
Every version bump gets an entry in the same commit. Not afterwards: the reason a change was made is known while it is being made and gone a week later, and a changelog assembled from commit subjects at release time is a list of things nobody can act on. Backfilled 0.8.2 through 0.9.8, because those shipped as a running deployment rather than as releases and 1.0.0's notes have to be assembled from something. The rule that earns the file its place is the last one in CLAUDE.md: a fix to something that *looked* like it worked gets a line, always. Those are the entries somebody stops working around a bug because of, and they are invisible from outside -- nobody reports a control that silently does nothing, they just quietly stop using it. Half of what is in here is that shape: a group delete that left its grants, a share panel that only saved if you also saved the resource, an update script that stopped after "== fetching ==". A release is a signed annotated tag whose message is that version's entry, and that is not decoration -- /admin/updates reads release notes out of the tag object, so the tag message is literally what an administrator sees on the update page. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+169
@@ -0,0 +1,169 @@
|
||||
# Changelog
|
||||
|
||||
What changed, per version, for somebody using or running LLeMbas — not a
|
||||
restatement of the commit log. If a change fixed something that *looked* like it
|
||||
worked, that is worth a line: those are the ones nobody would otherwise know to
|
||||
stop working around.
|
||||
|
||||
Newest first. Versions are `__version__` in `src/lembas/__init__.py`, which is
|
||||
the only place a version is written.
|
||||
|
||||
The first tagged release is **1.0.0**. Everything below it shipped as a running
|
||||
deployment rather than as a release, and is recorded here so the release notes
|
||||
for 1.0.0 have something to be assembled from.
|
||||
|
||||
---
|
||||
|
||||
## Unreleased
|
||||
|
||||
Nothing since 0.9.8.
|
||||
|
||||
## 0.9.8
|
||||
|
||||
**Updates follow a channel, not a commit.** `stable` tracks the newest `vX.Y.Z`
|
||||
tag; `edge` tracks the branch tip. A branch tip is not a release — following one
|
||||
means deploying whatever was pushed five minutes ago — so stable is the default
|
||||
for anybody who is not the person writing it.
|
||||
|
||||
- The Updates page shows a **version** rather than a commit sha: `1.0.0` at a
|
||||
tag, `1.0.0-7-gd4f56d` seven commits past one, and a bare sha only before the
|
||||
first release exists.
|
||||
- Release notes come out of the **annotated tag itself**, so no forge API is
|
||||
involved anywhere. That matters: the Gitea API this was checked against
|
||||
returns a 500 from a server-side panic on exactly the releases endpoint.
|
||||
- A tag with a suffix (`v1.1.0-rc1`) is deliberately not a release — git's
|
||||
version sort ranks it *above* `v1.1.0`, so accepting one would step a stable
|
||||
host onto a candidate.
|
||||
- Fixed: `deploy/update.sh` stopped silently after `== fetching ==` on any host
|
||||
with no release tags — which was every host. Fetched, not reset, not
|
||||
restarted, and no error printed.
|
||||
- Fixed: `install.sh` now refuses an `ssh://` repository URL up front instead of
|
||||
letting the clone fail as a service user with no key.
|
||||
|
||||
## 0.9.7
|
||||
|
||||
**Packaging, and updating without a shell.**
|
||||
|
||||
- `/admin/updates`: what is running, what is available, and what changed between.
|
||||
A button applies it — answered by an **opt-in** systemd helper, because the
|
||||
service runs unprivileged and a web application that can restart its own
|
||||
service is one whose worst day is much worse. Without the helper the page says
|
||||
so and prints the command.
|
||||
- `Dockerfile` and `docker-compose.yml`. No secret key, no data and no `.git`
|
||||
baked in; loopback only; a TLS proxy expected in front, because a service
|
||||
worker and a microphone both require HTTPS or localhost.
|
||||
- `deploy/lxc-install.sh` creates an unprivileged Proxmox container and runs the
|
||||
existing installer inside it.
|
||||
- `/healthz`, which opens the database rather than only proving the socket is
|
||||
listening.
|
||||
|
||||
## 0.9.6
|
||||
|
||||
**Permissions, quotas and sharing.**
|
||||
|
||||
- **"What can this account actually do?"** answered on screen, naming *where*
|
||||
each permission came from — admin, the baseline, or a group.
|
||||
- Users and groups are list-plus-detail, and membership is edited from **one**
|
||||
side. It was on both, and a save from either overwrote what the other showed.
|
||||
- Reading and writing split for notes, memory and skills.
|
||||
- **Quotas on a group** — monthly tokens, concurrent replies, agent wall clock,
|
||||
images a day, helpers a reply. Resolved by maximum across a person's groups,
|
||||
with zero meaning *no limit* and winning outright.
|
||||
- Fixed: **deleting a group or an account left every share naming it behind.**
|
||||
`forget_principal` had existed since shares did and was called by nobody.
|
||||
- Fixed: `library.share` defaulted to off, so sharing shipped documented as done
|
||||
and unreachable — the panel only renders for somebody who holds it.
|
||||
- The share panel is its own action with a search box. It used to be checkboxes
|
||||
inside the resource's save form, listing every account on the instance, and a
|
||||
tick only took effect if you also saved the resource.
|
||||
- Reports are shareable, and every listing has a **Shared with me** filter.
|
||||
|
||||
## 0.9.5
|
||||
|
||||
**Extraction settings, embeddings, and hybrid search.**
|
||||
|
||||
- `/admin/extraction`: upload size, image edge, JPEG quality, PDF pages,
|
||||
extracted characters, orphan age, extra text extensions.
|
||||
- An **embedding model** can be chosen from models flagged for it. Library search
|
||||
then fuses keyword and semantic ranking, so *"how do I get paid"* finds a
|
||||
document that says *"invoicing"*.
|
||||
- **Choosing none is not a degraded mode**: no rows written, no requests made,
|
||||
and byte-for-byte the keyword search that was always there.
|
||||
- Vectors carry their model and width, and a mismatch is skipped rather than
|
||||
scored — comparing two embedding spaces produces a confident wrong answer.
|
||||
- Indexing happens in the background as records are written, with a rebuild
|
||||
button for everything that already existed.
|
||||
|
||||
## 0.9.4
|
||||
|
||||
**An instance can be somebody else's.**
|
||||
|
||||
- Name, tagline, logo, favicon and launcher icons derived from the logo.
|
||||
- The Middle-earth wording is editable data. Leaving a box alone does not freeze
|
||||
it, so a later release can still improve the default.
|
||||
- **Custom themes** as a set of colours rather than a stylesheet, inheriting
|
||||
whichever built-in they start from.
|
||||
- Global CSS overrides, served as `/branding.css`.
|
||||
|
||||
## 0.9.3
|
||||
|
||||
**Subagents.** A reply can hand a self-contained piece of work to a helper that
|
||||
runs on its own and reports back — several at once, so research fans out instead
|
||||
of queueing.
|
||||
|
||||
- A helper cannot ask questions, cannot send helpers of its own, writes nothing
|
||||
unless the call asked and the chat's mode allowed it, and on a machine runs
|
||||
only a fixed list of read-only commands — in **every** mode, including Auto.
|
||||
- Fixed, and it was live in scheduled runs too: an unattended chat that hit an
|
||||
approval built a card nobody could see and sat on it for fifteen minutes.
|
||||
|
||||
## 0.9.2
|
||||
|
||||
**Image generation defaults an administrator can actually set** — steps, cfg,
|
||||
size, sampler, scheduler, denoise, negative prompt, checkpoint, batch. There were
|
||||
none: one hard-coded set from the SD1.5 era, and prose in a box as the only way
|
||||
to change it.
|
||||
|
||||
- The samplers and schedulers ComfyUI had been reporting all along are now the
|
||||
pickers; nothing had ever read them.
|
||||
- The tool's own schema restates the instance's defaults, instead of telling the
|
||||
model "Default 512" beside an instance that draws at 1024.
|
||||
|
||||
## 0.9.1
|
||||
|
||||
**Everything that arrives is announced, not only chat replies.** A scheduled run
|
||||
that filed a report used to light a dot in a corner and say nothing.
|
||||
|
||||
- A count in the tab title while you are looking elsewhere.
|
||||
- **Web push**, so a schedule firing at seven in the morning reaches a browser
|
||||
that is shut. Opt-in per device. It is the one thing here that contacts an
|
||||
outside service, and `services/push.py` says so plainly.
|
||||
|
||||
## 0.9.0
|
||||
|
||||
**A model can schedule things.** There was no tool for it — asked to "remind me
|
||||
every Monday", a model wrote a note and reported that it had scheduled
|
||||
something, and every screen agreed with it.
|
||||
|
||||
- `schedule_create`, `schedule_list`, `schedule_update`, `schedule_cancel`, over
|
||||
the same rule normaliser the manual form uses.
|
||||
- The reply says the resulting timing back in words, which is the only moment
|
||||
anybody can check that Monday was understood as Monday.
|
||||
|
||||
## 0.8.3
|
||||
|
||||
**An SSH connection may not point at this machine unless an administrator says
|
||||
so.** A profile aimed at `127.0.0.1` walked straight past "nothing runs on the
|
||||
LLeMbas host" — through a real login, onto the machine holding the database and
|
||||
the encryption key. Three positions: off, one named port, or anywhere.
|
||||
|
||||
## 0.8.2
|
||||
|
||||
- Fixed: **opening the canvas before a chat existed swapped the whole site into
|
||||
the panel.** `hx-get=""` is not "fetch nothing" — htmx looks for the attribute,
|
||||
not the value, so the empty one was a real request for the current document.
|
||||
- Fixed: the Canvas and Terminal buttons appeared where they could not work.
|
||||
- The bottom edge of the shell is no longer drawn, so the sidebar footer and the
|
||||
composer stop meeting a line at two different heights.
|
||||
- Admin pages scroll in one container; `/admin/prompts` no longer drops you at
|
||||
the bottom of a shorter panel.
|
||||
Reference in New Issue
Block a user