Prepare the 1.0.0 GA release surface

Add the repo-side pieces for milestone 5: MIT licensing, real maintainer and forge metadata, a public support doc, 1.0.0 release notes, release-prep tooling, and CI uploads for the full candidate artifact set.

Keep source-tree version surfaces honest by reading the local project version in the CLI and About dialog, and cover the new release-prep plus version-fallback behavior with focused tests.

Document where raw validation evidence belongs, add the GA validation rollup, and archive the latest readiness review. Milestone 5 remains open until the forge release page is published and the milestone 2 and 3 matrices are filled with linked manual evidence.

Validation: PYTHONPATH=src python3 -m unittest discover -s tests -p 'test_*.py'; PYTHONPATH=src python3 -m unittest tests.test_release_prep tests.test_portable_bundle tests.test_aman_cli tests.test_config_ui; python3 -m py_compile src/*.py tests/*.py; PYTHONPATH=src python3 -m aman version
This commit is contained in:
Thales Maciel 2026-03-12 19:36:52 -03:00
parent acfc376845
commit 31a1e069b3
No known key found for this signature in database
GPG key ID: 33112E6833C34679
28 changed files with 591 additions and 33 deletions

View file

@ -17,12 +17,8 @@ jobs:
python -m pip install --upgrade pip
python -m pip install uv build
uv sync --extra x11
- name: Release quality checks
run: make release-check
- name: Build Debian package
run: make package-deb
- name: Build Arch package inputs
run: make package-arch
- name: Prepare release candidate artifacts
run: make release-prep
- name: Upload packaging artifacts
uses: actions/upload-artifact@v4
with:
@ -30,5 +26,8 @@ jobs:
path: |
dist/*.whl
dist/*.tar.gz
dist/*.sha256
dist/SHA256SUMS
dist/*.deb
dist/arch/PKGBUILD
dist/arch/*.tar.gz

View file

@ -6,14 +6,19 @@ The format is based on Keep a Changelog and this project follows Semantic Versio
## [Unreleased]
## [1.0.0] - 2026-03-12
### Added
- Packaging scripts and templates for Debian (`.deb`) and Arch (`PKGBUILD` + source tarball).
- Make targets for build/package/release-check workflows.
- Persona and distribution policy documentation.
- Portable X11 bundle install, upgrade, uninstall, and purge lifecycle.
- Distinct `doctor` and `self-check` diagnostics plus a runtime recovery guide.
- End-user-first first-run docs, screenshots, demo media, release notes, and a public support document.
- `make release-prep` plus `dist/SHA256SUMS` for the GA release artifact set.
- X11 GA validation matrices and a final GA validation report surface.
### Changed
- README now documents package-first installation for non-technical users.
- Release checklist now includes packaging artifacts.
- Project metadata now uses the real maintainer, release URLs, and MIT license.
- Packaging templates now point at the public Aman forge location instead of placeholders.
- CI now prepares the full release-candidate artifact set instead of only Debian and Arch packaging outputs.
## [0.1.0] - 2026-02-26

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Thales Maciel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -6,7 +6,7 @@ BUILD_DIR := $(CURDIR)/build
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
RUN_CONFIG := $(if $(RUN_ARGS),$(abspath $(firstword $(RUN_ARGS))),$(CONFIG))
.PHONY: run doctor self-check runtime-check eval-models build-heuristic-dataset sync-default-model check-default-model sync test check build package package-deb package-arch package-portable release-check install-local install-service install clean-dist clean-build clean
.PHONY: run doctor self-check runtime-check eval-models build-heuristic-dataset sync-default-model check-default-model sync test check build package package-deb package-arch package-portable release-check release-prep install-local install-service install clean-dist clean-build clean
EVAL_DATASET ?= $(CURDIR)/benchmarks/cleanup_dataset.jsonl
EVAL_MATRIX ?= $(CURDIR)/benchmarks/model_matrix.small_first.json
EVAL_OUTPUT ?= $(CURDIR)/benchmarks/results/latest.json
@ -77,6 +77,11 @@ release-check:
$(MAKE) test
$(MAKE) build
release-prep:
$(MAKE) release-check
$(MAKE) package
./scripts/prepare_release.sh
install-local:
$(PYTHON) -m pip install --user ".[x11]"

View file

@ -5,6 +5,11 @@ Aman is a local X11 dictation daemon for Linux desktops. The supported path is:
install the portable bundle, save the first-run settings window once, then use
a hotkey to dictate into the focused app.
Published bundles, checksums, and release notes live on the
[`git.thaloco.com` releases page](https://git.thaloco.com/thaloco/aman/releases).
Support requests and bug reports go to
[`SUPPORT.md`](SUPPORT.md) or `thales@thalesmaciel.com`.
## Supported Path
| Surface | Contract |
@ -62,7 +67,7 @@ sudo zypper install -y portaudio gtk3 libayatana-appindicator3-1 python3-gobject
Then install Aman and run the first dictation:
1. Verify and extract the portable bundle.
1. Download, verify, and extract the portable bundle from the releases page.
2. Run `./install.sh`.
3. When `Aman Settings (Required)` opens, choose your microphone and keep
`Clipboard paste (recommended)` unless you have a reason to change it.
@ -138,6 +143,8 @@ The canonical end-user guide lives in
- Fresh install, upgrade, uninstall, and purge behavior are documented there.
- The same guide covers distro-package conflicts and portable-installer
recovery steps.
- Release-specific notes for `1.0.0` live in
[`docs/releases/1.0.0.md`](docs/releases/1.0.0.md).
## Daily Use and Support
@ -162,6 +169,8 @@ The canonical end-user guide lives in
- Install, upgrade, uninstall: [docs/portable-install.md](docs/portable-install.md)
- Runtime recovery and diagnostics: [docs/runtime-recovery.md](docs/runtime-recovery.md)
- Release notes: [docs/releases/1.0.0.md](docs/releases/1.0.0.md)
- Support and issue reporting: [SUPPORT.md](SUPPORT.md)
- Config reference and advanced behavior: [docs/config-reference.md](docs/config-reference.md)
- Developer, packaging, and benchmark workflows: [docs/developer-workflows.md](docs/developer-workflows.md)
- Persona and distribution policy: [docs/persona-and-distribution.md](docs/persona-and-distribution.md)

35
SUPPORT.md Normal file
View file

@ -0,0 +1,35 @@
# Support
Aman supports X11 desktop sessions on mainstream Linux distros with the
documented runtime dependencies and `systemd --user`.
For support, bug reports, or packaging issues, email:
- `thales@thalesmaciel.com`
## Include this information
To make support requests actionable, include:
- distro and version
- whether the session is X11
- how Aman was installed: portable bundle, `.deb`, Arch package inputs, or
developer install
- the Aman version you installed
- the output of `aman doctor --config ~/.config/aman/config.json`
- the output of `aman self-check --config ~/.config/aman/config.json`
- the first relevant lines from `journalctl --user -u aman`
- whether the problem still reproduces with
`aman run --config ~/.config/aman/config.json --verbose`
## Supported escalation path
Use the supported recovery order before emailing:
1. `aman doctor --config ~/.config/aman/config.json`
2. `aman self-check --config ~/.config/aman/config.json`
3. `journalctl --user -u aman`
4. `aman run --config ~/.config/aman/config.json --verbose`
The diagnostic IDs and common remediation steps are documented in
[`docs/runtime-recovery.md`](docs/runtime-recovery.md).

View file

@ -13,14 +13,21 @@ make package-deb
make package-arch
make runtime-check
make release-check
make release-prep
```
- `make package-portable` builds `dist/aman-x11-linux-<version>.tar.gz` plus
its `.sha256` file.
- `make release-prep` runs `make release-check`, builds the packaged artifacts,
and writes `dist/SHA256SUMS` for the release page upload set.
- `make package-deb` installs Python dependencies while creating the package.
- For offline Debian packaging, set `AMAN_WHEELHOUSE_DIR` to a directory
containing the required wheels.
For `1.0.0`, the manual publication target is the forge release page at
`https://git.thaloco.com/thaloco/aman/releases`, using
[`docs/releases/1.0.0.md`](./releases/1.0.0.md) as the release-notes source.
## Developer setup
`uv` workflow:

View file

@ -36,7 +36,7 @@ Design implications:
The current release channels are:
1. Current canonical end-user channel: portable X11 bundle (`aman-x11-linux-<version>.tar.gz`).
1. Current canonical end-user channel: portable X11 bundle (`aman-x11-linux-<version>.tar.gz`) published on `https://git.thaloco.com/thaloco/aman/releases`.
2. Secondary packaged channel: Debian package (`.deb`) for Ubuntu/Debian users.
3. Secondary maintainer channel: Arch package inputs (`PKGBUILD` + source tarball).
4. Developer: wheel and sdist from `python -m build`.
@ -75,7 +75,7 @@ variant.
## Release and Support Policy
- App versioning follows SemVer (`0.y.z` until API/UX stabilizes).
- App versioning follows SemVer starting with `1.0.0` for the X11 GA release.
- Config schema versioning is independent (`config_version` in config).
- Docs must always separate:
- Current release channels
@ -86,5 +86,7 @@ variant.
- Daily-use service mode versus manual foreground mode
- Canonical recovery sequence
- Representative validation families
- Public support and issue reporting currently use email only:
`thales@thalesmaciel.com`
- GA means the support contract, validation evidence, and release surface are
consistent. It does not require a native package for every distro.

View file

@ -5,6 +5,9 @@ This is the canonical end-user install path for Aman on X11.
For the shortest first-run path, screenshots, and the expected tray/dictation
result, start with the quickstart in [`README.md`](../README.md).
Download published bundles, checksums, and release notes from
`https://git.thaloco.com/thaloco/aman/releases`.
## Supported environment
- X11 desktop session
@ -42,7 +45,7 @@ sudo zypper install -y portaudio gtk3 libayatana-appindicator3-1 python3-gobject
## Fresh install
1. Download `aman-x11-linux-<version>.tar.gz` and `aman-x11-linux-<version>.tar.gz.sha256`.
1. Download `aman-x11-linux-<version>.tar.gz` and `aman-x11-linux-<version>.tar.gz.sha256` from the releases page.
2. Verify the checksum.
3. Extract the bundle.
4. Run `install.sh`.
@ -150,3 +153,6 @@ If installation succeeds but runtime behavior is wrong, use the supported recove
The failure IDs and example outputs for this flow are documented in
[`docs/runtime-recovery.md`](./runtime-recovery.md).
Public support and issue reporting instructions live in
[`SUPPORT.md`](../SUPPORT.md).

View file

@ -5,26 +5,27 @@ GA signoff bar. The GA signoff sections are required for `v1.0.0` and later.
1. Update `CHANGELOG.md` with final release notes.
2. Bump `project.version` in `pyproject.toml`.
3. Run quality and build gates:
- `make release-check`
- `make runtime-check`
- `make check-default-model`
4. Ensure model promotion artifacts are current:
3. Ensure model promotion artifacts are current:
- `benchmarks/results/latest.json` has the latest `winner_recommendation.name`
- `benchmarks/model_artifacts.json` contains that winner with URL + SHA256
- `make sync-default-model` (if constants drifted)
5. Build packaging artifacts:
- `make package`
6. Verify artifacts:
4. Prepare the release candidate:
- `make release-prep`
5. Verify artifacts:
- `dist/*.whl`
- `dist/aman-x11-linux-<version>.tar.gz`
- `dist/aman-x11-linux-<version>.tar.gz.sha256`
- `dist/SHA256SUMS`
- `dist/*.deb`
- `dist/arch/PKGBUILD`
6. Verify checksums:
- `sha256sum -c dist/SHA256SUMS`
7. Tag release:
- `git tag vX.Y.Z`
- `git push origin vX.Y.Z`
8. Publish release and upload package artifacts from `dist/`.
8. Publish `vX.Y.Z` on `https://git.thaloco.com/thaloco/aman/releases` and upload package artifacts from `dist/`.
- Use [`docs/releases/1.0.0.md`](./releases/1.0.0.md) as the release-notes source for the GA release.
- Include `dist/SHA256SUMS` with the uploaded artifacts.
9. Portable bundle release signoff:
- `README.md` points end users to the portable bundle first.
- [`docs/portable-install.md`](./portable-install.md) matches the shipped install, upgrade, uninstall, and purge behavior.
@ -49,3 +50,4 @@ GA signoff bar. The GA signoff sections are required for `v1.0.0` and later.
- The portable installer, upgrade path, and uninstall path are validated.
- End-user docs and release notes match the shipped artifact set.
- Public metadata, checksums, and support/reporting surfaces are complete.
- [`docs/x11-ga/ga-validation-report.md`](./x11-ga/ga-validation-report.md) links the release page, matrices, and raw evidence files.

69
docs/releases/1.0.0.md Normal file
View file

@ -0,0 +1,69 @@
# Aman 1.0.0
This is the first GA-targeted X11 release for Aman.
- Canonical release page:
`https://git.thaloco.com/thaloco/aman/releases/tag/v1.0.0`
- Canonical release index:
`https://git.thaloco.com/thaloco/aman/releases`
- Support and issue reporting:
`thales@thalesmaciel.com`
## Supported environment
- X11 desktop sessions only
- `systemd --user` for supported daily use
- System CPython `3.10`, `3.11`, or `3.12` for the portable installer
- Runtime dependencies installed from the distro package manager
- Representative validation families: Debian/Ubuntu, Arch, Fedora, openSUSE
## Artifacts
The release page should publish:
- `aman-x11-linux-1.0.0.tar.gz`
- `aman-x11-linux-1.0.0.tar.gz.sha256`
- `SHA256SUMS`
- wheel artifact from `dist/*.whl`
- Debian package from `dist/*.deb`
- Arch package inputs from `dist/arch/PKGBUILD` and `dist/arch/*.tar.gz`
## Install, update, and uninstall
- Install: download the portable bundle and checksum from the release page,
verify the checksum, extract the bundle, then run `./install.sh`
- Update: extract the newer bundle and run its `./install.sh`
- Uninstall: run `~/.local/share/aman/current/uninstall.sh`
- Purge uninstall: run `~/.local/share/aman/current/uninstall.sh --purge`
The full end-user lifecycle is documented in
[`docs/portable-install.md`](../portable-install.md).
## Recovery path
If the supported path fails, use:
1. `aman doctor --config ~/.config/aman/config.json`
2. `aman self-check --config ~/.config/aman/config.json`
3. `journalctl --user -u aman`
4. `aman run --config ~/.config/aman/config.json --verbose`
Reference diagnostics and failure IDs live in
[`docs/runtime-recovery.md`](../runtime-recovery.md).
## Support
Email `thales@thalesmaciel.com` with:
- distro and version
- X11 confirmation
- install channel and Aman version
- `aman doctor` output
- `aman self-check` output
- relevant `journalctl --user -u aman` lines
## Non-goals
- Wayland support
- Flatpak or snap as the canonical GA path
- Native-package parity across every Linux distro

View file

@ -58,3 +58,4 @@ The final step to GA is not more feature work. It is proving that Aman has a rea
- Completed validation report for the representative distro families.
- Updated release checklist with signed-off GA criteria.
- Public support/reporting instructions that match the shipped product.
- Raw validation evidence stored in `user-readiness/<linux-timestamp>.md` and linked from the validation matrices.

View file

@ -106,7 +106,12 @@ Any future docs, tray copy, and release notes should point users to this same se
[`first-run-review-notes.md`](./first-run-review-notes.md) plus
[`user-readiness/1773352170.md`](../../user-readiness/1773352170.md).
- [ ] [Milestone 5: GA Candidate Validation and Release](./05-ga-candidate-validation-and-release.md)
Close the remaining trust, legal, release, and validation work for a public 1.0 launch.
Implementation landed on 2026-03-12: repo metadata now uses the real
maintainer and forge URLs, `LICENSE`, `SUPPORT.md`, `docs/releases/1.0.0.md`,
`make release-prep`, and [`ga-validation-report.md`](./ga-validation-report.md)
now exist. Leave this milestone open until the release page is published and
the milestone 2 and 3 validation matrices are filled with linked raw
evidence.
## Cross-milestone acceptance scenarios

View file

@ -0,0 +1,54 @@
# GA Validation Report
This document is the final rollup for the X11 GA release. It does not replace
the underlying evidence sources. It links them and records the final signoff
state.
## Where to put validation evidence
- Put raw manual validation notes in `user-readiness/<linux-timestamp>.md`.
- Use one timestamped file per validation session, distro pass, or reviewer
handoff.
- In the raw evidence file, record:
- distro and version
- reviewer
- date
- release artifact version
- commands run
- pass/fail results
- failure details and recovery outcome
- Reference those timestamped files from the `Notes` columns in:
- [`portable-validation-matrix.md`](./portable-validation-matrix.md)
- [`runtime-validation-report.md`](./runtime-validation-report.md)
## Release metadata
- Release version: `1.0.0`
- Release page:
`https://git.thaloco.com/thaloco/aman/releases/tag/v1.0.0`
- Support channel: `thales@thalesmaciel.com`
- License: MIT
## Evidence sources
- Portable lifecycle matrix:
[`portable-validation-matrix.md`](./portable-validation-matrix.md)
- Runtime reliability matrix:
[`runtime-validation-report.md`](./runtime-validation-report.md)
- First-run review:
[`first-run-review-notes.md`](./first-run-review-notes.md)
- Raw evidence archive:
[`user-readiness/README.md`](../../user-readiness/README.md)
- Release notes:
[`docs/releases/1.0.0.md`](../releases/1.0.0.md)
## Final signoff status
| Area | Status | Evidence |
| --- | --- | --- |
| Milestone 2 portable lifecycle | Pending | Fill `portable-validation-matrix.md` and link raw timestamped evidence |
| Milestone 3 runtime reliability | Pending | Fill `runtime-validation-report.md` and link raw timestamped evidence |
| Milestone 4 first-run UX/docs | Complete | `first-run-review-notes.md` and `user-readiness/1773352170.md` |
| Release metadata and support surface | Repo-complete | `LICENSE`, `SUPPORT.md`, `pyproject.toml`, packaging templates |
| Release artifacts and checksums | Repo-complete | `make release-prep`, `dist/SHA256SUMS`, `docs/releases/1.0.0.md` |
| Published release page | Pending | Publish `v1.0.0` on the forge release page and attach the prepared artifacts |

View file

@ -20,6 +20,9 @@ Completed on 2026-03-12:
These rows must be filled with real results before milestone 2 can be closed as
fully complete for GA evidence.
Store raw evidence for each distro pass in `user-readiness/<linux-timestamp>.md`
and reference that file in the `Notes` column.
| Distro family | Fresh install | First service start | Upgrade | Uninstall | Reinstall | Reboot or service restart | Missing dependency recovery | Conflict with prior package install | Reviewer | Status | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Debian/Ubuntu | Pending | Pending | Pending | Pending | Pending | Pending | Pending | Pending | Pending | Pending | |

View file

@ -34,6 +34,10 @@ Completed on 2026-03-12:
These rows must be filled with release-specific evidence before milestone 3 can
be closed as complete for GA signoff.
Store raw evidence for each runtime validation pass in
`user-readiness/<linux-timestamp>.md` and reference that file in the `Notes`
column.
| Scenario | Debian/Ubuntu | Arch | Fedora | openSUSE | Reviewer | Status | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Service restart after a successful install | Pending | Pending | Pending | Pending | Pending | Pending | Verify `systemctl --user restart aman` returns to the tray/ready state |

View file

@ -1,10 +1,10 @@
# Maintainer: Aman Maintainers <maintainers@example.com>
# Maintainer: Thales Maciel <thales@thalesmaciel.com>
pkgname=aman
pkgver=__VERSION__
pkgrel=1
pkgdesc="Local amanuensis daemon for X11 desktops"
arch=('x86_64')
url="https://github.com/example/aman"
url="https://git.thaloco.com/thaloco/aman"
license=('MIT')
depends=('python' 'python-pip' 'python-setuptools' 'portaudio' 'gtk3' 'libayatana-appindicator' 'python-gobject' 'python-xlib')
makedepends=('python-build' 'python-installer' 'python-wheel')

View file

@ -3,7 +3,7 @@ Version: __VERSION__
Section: utils
Priority: optional
Architecture: __ARCH__
Maintainer: Aman Maintainers <maintainers@example.com>
Maintainer: Thales Maciel <thales@thalesmaciel.com>
Depends: python3, python3-venv, python3-gi, python3-xlib, libportaudio2, gir1.2-gtk-3.0, libayatana-appindicator3-1
Description: Aman local amanuensis daemon for X11 desktops
Aman records microphone input, transcribes speech, optionally rewrites output,

View file

@ -4,10 +4,26 @@ build-backend = "setuptools.build_meta"
[project]
name = "aman"
version = "0.1.0"
version = "1.0.0"
description = "X11 STT daemon with faster-whisper and optional AI cleanup"
readme = "README.md"
requires-python = ">=3.10"
license = { file = "LICENSE" }
authors = [
{ name = "Thales Maciel", email = "thales@thalesmaciel.com" },
]
maintainers = [
{ name = "Thales Maciel", email = "thales@thalesmaciel.com" },
]
classifiers = [
"Environment :: X11 Applications",
"License :: OSI Approved :: MIT License",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
dependencies = [
"faster-whisper",
"llama-cpp-python",
@ -26,6 +42,12 @@ x11 = [
]
wayland = []
[project.urls]
Homepage = "https://git.thaloco.com/thaloco/aman"
Source = "https://git.thaloco.com/thaloco/aman"
Releases = "https://git.thaloco.com/thaloco/aman/releases"
Support = "https://git.thaloco.com/thaloco/aman"
[tool.setuptools]
package-dir = {"" = "src"}
packages = ["engine", "stages"]

63
scripts/prepare_release.sh Executable file
View file

@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
source "${SCRIPT_DIR}/package_common.sh"
require_command sha256sum
VERSION="$(project_version)"
PACKAGE_NAME="$(project_name)"
DIST_DIR="${DIST_DIR:-${ROOT_DIR}/dist}"
ARCH_DIST_DIR="${DIST_DIR}/arch"
PORTABLE_TARBALL="${DIST_DIR}/${PACKAGE_NAME}-x11-linux-${VERSION}.tar.gz"
PORTABLE_CHECKSUM="${PORTABLE_TARBALL}.sha256"
ARCH_TARBALL="${ARCH_DIST_DIR}/${PACKAGE_NAME}-${VERSION}.tar.gz"
ARCH_PKGBUILD="${ARCH_DIST_DIR}/PKGBUILD"
SHA256SUMS_PATH="${DIST_DIR}/SHA256SUMS"
require_file() {
local path="$1"
if [[ -f "${path}" ]]; then
return
fi
echo "missing required release artifact: ${path}" >&2
exit 1
}
require_file "${PORTABLE_TARBALL}"
require_file "${PORTABLE_CHECKSUM}"
require_file "${ARCH_TARBALL}"
require_file "${ARCH_PKGBUILD}"
shopt -s nullglob
wheels=("${DIST_DIR}/${PACKAGE_NAME//-/_}-${VERSION}-"*.whl)
debs=("${DIST_DIR}/${PACKAGE_NAME}_${VERSION}_"*.deb)
shopt -u nullglob
if [[ "${#wheels[@]}" -eq 0 ]]; then
echo "missing required release artifact: wheel for ${PACKAGE_NAME} ${VERSION}" >&2
exit 1
fi
if [[ "${#debs[@]}" -eq 0 ]]; then
echo "missing required release artifact: deb for ${PACKAGE_NAME} ${VERSION}" >&2
exit 1
fi
mapfile -t published_files < <(
cd "${DIST_DIR}" && find . -type f ! -name "SHA256SUMS" -print | LC_ALL=C sort
)
if [[ "${#published_files[@]}" -eq 0 ]]; then
echo "no published files found in ${DIST_DIR}" >&2
exit 1
fi
(
cd "${DIST_DIR}"
rm -f "SHA256SUMS"
sha256sum "${published_files[@]}" >"SHA256SUMS"
)
echo "generated ${SHA256SUMS_PATH}"

View file

@ -770,7 +770,21 @@ def _build_editor_stage(cfg: Config, *, verbose: bool) -> LlamaEditorStage:
)
def _local_project_version() -> str | None:
pyproject_path = Path(__file__).resolve().parents[1] / "pyproject.toml"
if not pyproject_path.exists():
return None
for line in pyproject_path.read_text(encoding="utf-8").splitlines():
stripped = line.strip()
if stripped.startswith('version = "'):
return stripped.split('"')[1]
return None
def _app_version() -> str:
local_version = _local_project_version()
if local_version:
return local_version
try:
return importlib.metadata.version("aman")
except importlib.metadata.PackageNotFoundError:

View file

@ -1,6 +1,7 @@
from __future__ import annotations
import copy
import importlib.metadata
import logging
import time
from dataclasses import dataclass
@ -642,9 +643,22 @@ def show_about_dialog() -> None:
def _present_about_dialog(parent) -> None:
about = Gtk.AboutDialog(transient_for=parent, modal=True)
about.set_program_name("Aman")
about.set_version("pre-release")
about.set_version(_app_version())
about.set_comments("Local amanuensis for X11 desktop dictation and rewriting.")
about.set_license("MIT")
about.set_wrap_license(True)
about.run()
about.destroy()
def _app_version() -> str:
pyproject_path = Path(__file__).resolve().parents[1] / "pyproject.toml"
if pyproject_path.exists():
for line in pyproject_path.read_text(encoding="utf-8").splitlines():
stripped = line.strip()
if stripped.startswith('version = "'):
return stripped.split('"')[1]
try:
return importlib.metadata.version("aman")
except importlib.metadata.PackageNotFoundError:
return "unknown"

View file

@ -242,6 +242,14 @@ class AmanCliTests(unittest.TestCase):
self.assertEqual(exit_code, 0)
self.assertEqual(out.getvalue().strip(), "1.2.3")
def test_app_version_prefers_local_pyproject_version(self):
pyproject_text = '[project]\nversion = "9.9.9"\n'
with patch.object(aman.Path, "exists", return_value=True), patch.object(
aman.Path, "read_text", return_value=pyproject_text
), patch("aman.importlib.metadata.version", return_value="1.0.0"):
self.assertEqual(aman._app_version(), "9.9.9")
def test_doctor_command_json_output_and_exit_code(self):
report = DiagnosticReport(
checks=[DiagnosticCheck(id="config.load", status="ok", message="ok", next_step="")]

View file

@ -11,9 +11,11 @@ from config import Config
from config_ui import (
RUNTIME_MODE_EXPERT,
RUNTIME_MODE_MANAGED,
_app_version,
apply_canonical_runtime_defaults,
infer_runtime_mode,
)
from unittest.mock import patch
class ConfigUiRuntimeModeTests(unittest.TestCase):
@ -38,6 +40,14 @@ class ConfigUiRuntimeModeTests(unittest.TestCase):
self.assertFalse(cfg.models.allow_custom_models)
self.assertEqual(cfg.models.whisper_model_path, "")
def test_app_version_prefers_local_pyproject_version(self):
pyproject_text = '[project]\nversion = "9.9.9"\n'
with patch("config_ui.Path.exists", return_value=True), patch(
"config_ui.Path.read_text", return_value=pyproject_text
), patch("config_ui.importlib.metadata.version", return_value="1.0.0"):
self.assertEqual(_app_version(), "9.9.9")
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,88 @@
import os
import subprocess
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
def _project_version() -> str:
for line in (ROOT / "pyproject.toml").read_text(encoding="utf-8").splitlines():
if line.startswith('version = "'):
return line.split('"')[1]
raise RuntimeError("project version not found")
def _write_file(path: Path, content: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(content, encoding="utf-8")
class ReleasePrepScriptTests(unittest.TestCase):
def test_prepare_release_writes_sha256sums_for_expected_artifacts(self):
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
dist_dir = tmp_path / "dist"
arch_dir = dist_dir / "arch"
version = _project_version()
_write_file(dist_dir / f"aman-{version}-py3-none-any.whl", "wheel\n")
_write_file(dist_dir / f"aman-x11-linux-{version}.tar.gz", "portable\n")
_write_file(dist_dir / f"aman-x11-linux-{version}.tar.gz.sha256", "checksum\n")
_write_file(dist_dir / f"aman_{version}_amd64.deb", "deb\n")
_write_file(arch_dir / "PKGBUILD", "pkgbuild\n")
_write_file(arch_dir / f"aman-{version}.tar.gz", "arch-src\n")
env = os.environ.copy()
env["DIST_DIR"] = str(dist_dir)
subprocess.run(
["bash", "./scripts/prepare_release.sh"],
cwd=ROOT,
env=env,
text=True,
capture_output=True,
check=True,
)
sha256sums = (dist_dir / "SHA256SUMS").read_text(encoding="utf-8")
self.assertIn(f"./aman-{version}-py3-none-any.whl", sha256sums)
self.assertIn(f"./aman-x11-linux-{version}.tar.gz", sha256sums)
self.assertIn(f"./aman-x11-linux-{version}.tar.gz.sha256", sha256sums)
self.assertIn(f"./aman_{version}_amd64.deb", sha256sums)
self.assertIn(f"./arch/PKGBUILD", sha256sums)
self.assertIn(f"./arch/aman-{version}.tar.gz", sha256sums)
def test_prepare_release_fails_when_expected_artifact_is_missing(self):
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
dist_dir = tmp_path / "dist"
arch_dir = dist_dir / "arch"
version = _project_version()
_write_file(dist_dir / f"aman-{version}-py3-none-any.whl", "wheel\n")
_write_file(dist_dir / f"aman-x11-linux-{version}.tar.gz", "portable\n")
_write_file(dist_dir / f"aman-x11-linux-{version}.tar.gz.sha256", "checksum\n")
_write_file(arch_dir / "PKGBUILD", "pkgbuild\n")
_write_file(arch_dir / f"aman-{version}.tar.gz", "arch-src\n")
env = os.environ.copy()
env["DIST_DIR"] = str(dist_dir)
result = subprocess.run(
["bash", "./scripts/prepare_release.sh"],
cwd=ROOT,
env=env,
text=True,
capture_output=True,
check=False,
)
self.assertNotEqual(result.returncode, 0)
self.assertIn("missing required release artifact", result.stderr)
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,105 @@
# User Readiness Review
- Date: 2026-03-12
- Reviewer: Codex
- Scope: documentation, packaged artifacts, and CLI help surface
- Live run status: documentation-and-artifact based plus `python3 -m aman --help`; I did not launch the GTK daemon in a live X11 session
## Verdict
A new X11 user can now tell what Aman is for, how to install it, what success
looks like, and what recovery path to follow when the first run goes wrong.
That is a real improvement over an internal-looking project surface.
It still does not feel fully distribution-ready. The first-contact and
onboarding story are strong, but the public release and validation story still
looks in-progress rather than complete.
## What A New User Would Experience
A new user lands on a README that immediately states the product, the supported
environment, the install path, the expected first dictation result, and the
recovery flow. The quickstart is concrete, with distro-specific dependency
commands, screenshots, demo media, and a plain-language description of what the
tray and injected text should do. The install and support docs stay aligned
with that same path, which keeps the project from feeling like it requires
author hand-holding.
Confidence drops once the user looks for proof that the release is actually
published and validated. The repo-visible evidence still shows pending GA
publication work and pending manual distro validation, so the project reads as
"nearly ready" instead of "safe to recommend."
## Top Blockers
1. The public release trust surface is still incomplete. The supported install
path depends on a published release page, but
`docs/x11-ga/ga-validation-report.md` still marks `Published release page`
as `Pending`.
2. The artifact story still reads as pre-release. `docs/releases/1.0.0.md`
says the release page "should publish" the artifacts, and local `dist/`
contents are still `0.1.0` wheel and tarball outputs rather than a visible
`1.0.0` portable bundle plus checksum set.
3. Supported-distro validation is still promise, not proof.
`docs/x11-ga/portable-validation-matrix.md` and
`docs/x11-ga/runtime-validation-report.md` show good automated coverage, but
every manual Debian/Ubuntu, Arch, Fedora, and openSUSE row is still
`Pending`.
4. The top-level CLI help still mixes end-user and maintainer workflows.
Commands like `bench`, `eval-models`, `build-heuristic-dataset`, and
`sync-default-model` make the help surface feel more internal than a focused
desktop product when a user checks `--help`.
## What Is Already Working
- A new user can tell what Aman is and who it is for from `README.md`.
- A new user can follow one obvious install path without being pushed into
developer tooling.
- A new user can see screenshots, demo media, expected tray states, and a
sample dictated phrase before installing.
- A new user gets a coherent support and recovery story through `doctor`,
`self-check`, `journalctl`, and `aman run --verbose`.
- The repo now has visible trust signals such as a real `LICENSE`,
maintainer/contact metadata, and a public support document.
## Quick Wins
- Publish the `1.0.0` release page with the portable bundle, checksum files,
and final release notes, then replace every `Pending` or "should publish"
wording with completed wording.
- Make the local artifact story match the docs by generating or checking in the
expected `1.0.0` release outputs referenced by the release documentation.
- Fill at least one full manual validation pass per supported distro family and
link each timestamped evidence file into the two GA matrices.
- Narrow the top-level CLI help to the supported user commands, or clearly
label maintainer-only commands so the main recovery path stays prominent.
## What Would Make It Distribution-Ready
Before broader distribution, it needs a real published `1.0.0` release page,
artifact and checksum evidence that matches the docs, linked manual validation
results across the supported distro families, and a slightly cleaner user-facing
CLI surface. Once those land, the project will look like a maintained product
rather than a well-documented release candidate.
## Evidence
### Commands Run
- `bash /home/thales/projects/personal/skills-exploration/.agents/skills/user-readiness-review/scripts/collect_readiness_context.sh`
- `PYTHONPATH=src python3 -m aman --help`
- `find docs/media -maxdepth 1 -type f | sort`
- `ls -la dist`
### Files Reviewed
- `README.md`
- `docs/portable-install.md`
- `SUPPORT.md`
- `pyproject.toml`
- `CHANGELOG.md`
- `docs/releases/1.0.0.md`
- `docs/persona-and-distribution.md`
- `docs/x11-ga/ga-validation-report.md`
- `docs/x11-ga/portable-validation-matrix.md`
- `docs/x11-ga/runtime-validation-report.md`

View file

@ -1,4 +1,4 @@
# User Readiness Reports
# User Readiness Reports And Validation Evidence
Each Markdown file in this directory is a user readiness report for the
project.
@ -6,3 +6,10 @@ project.
The filename title is a Linux timestamp. In practice, a report named
`1773333303.md` corresponds to a report generated at Unix timestamp
`1773333303`.
This directory also stores raw manual validation evidence for GA signoff.
Use one timestamped file per validation session and reference those files from:
- `docs/x11-ga/portable-validation-matrix.md`
- `docs/x11-ga/runtime-validation-report.md`
- `docs/x11-ga/ga-validation-report.md`

2
uv.lock generated
View file

@ -8,7 +8,7 @@ resolution-markers = [
[[package]]
name = "aman"
version = "0.1.0"
version = "1.0.0"
source = { editable = "." }
dependencies = [
{ name = "faster-whisper" },