d201521353
The channel is declared twice: in lembas.env, which this process reads and the page prints, and baked into the systemd unit, which is what the helper actually deploys. install.sh writes both together so they agree by construction -- and the moment somebody edits one by hand they diverge, with the page naming one channel down every card and the button deploying the other. Nothing anywhere would have said so. It cannot be collapsed to one place. Reading it from lembas.env at deploy time would mean the service account decides what gets deployed, since it owns that file -- and "the request carries no channel" is the property the whole design rests on. So the two stay, and the marker file the page already reads to know the helper exists now carries the channel it was installed with. A disagreement is an alert. Display only, deliberately: the service account can write that marker, so a compromised process could lie about what the helper will do -- but not change it, because the helper's own channel lives in /etc where that account cannot reach. Lying about the channel is a much smaller thing than choosing it. An empty marker -- every host installed before this -- reads as unknown rather than as a mismatch. Claiming one would put a red alert on every existing host. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
178 lines
8.5 KiB
Markdown
178 lines
8.5 KiB
Markdown
# 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
|
|
|
|
- The Updates page notices when the update helper on a host was installed for a
|
|
**different channel** than the page follows. It is declared in two places —
|
|
`lembas.env` and the systemd unit — and only the installer writes both, so
|
|
editing one by hand would have left the button deploying something other than
|
|
what the page named, with nothing anywhere saying so.
|
|
- Fixed: release notes from a **signed** tag rendered the signature block.
|
|
`_notes_for` stripped the PGP header only, and which header appears depends on
|
|
`gpg.format` — this repository signs with SSH.
|
|
- A `CHANGELOG.md`, kept from now on rather than assembled at release time.
|
|
|
|
## 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.
|