chore(release): 1.0.0b1 — the v1 target, staged as a beta

All seven v1 capabilities are landed (ROADMAP's v1 target is met), so this is
the first release of the 1.x train. Staged as a beta rather than cut final on
the operator's call: per the canonical policy `-beta.N` means feature-complete,
external testing, no new features, focus is on bugs — which is exactly this
state, with a cross-frontier bug-hunt panel outstanding on U7's diff.

The repo learned this sequencing the hard way once: v0.2.0 was tagged and
announced while a contract panel was in flight, the panel found three defects in
the code just released, and v0.2.1 shipped within the hour. A beta is the
designed answer to that, not a workaround for it.

ALSO FIXES A SECOND COPY OF THE VERSION, found while cutting this one.
`booth.__version__` was the literal `0.1.0` and had been wrong through six
releases. It is now read from pyproject.toml — deliberately NOT from
importlib.metadata, which describes a different artifact: this repo has no build
step and no install step (booth.service runs uvicorn with WorkingDirectory set
to the tree), and the venv was carrying a vestigial booth-0.3.0.dist-info with
no package directory behind it. Installed metadata therefore reported 0.3.0 for
a tree at 1.0.0b1 — confidently wrong and varying by environment, which is worse
than a literal that at least fails the same way everywhere.

booth/__init__.py is also, it turns out, effectively stdlib-only: scripts/booth
imports booth.links / booth.marks / booth.manifest under the system python3 with
no venv, and every one of those executes the package root first. Nothing
asserted it. test_stdlib_only now covers __init__, and the no-venv import path
is verified under python3.11 reporting 1.0.0b1.

642 tests green.
This commit is contained in:
vh
2026-09-22 21:40:09 -07:00
parent bf351a26d1
commit 3126deca00
4 changed files with 79 additions and 7 deletions
+6 -3
View File
@@ -1,9 +1,12 @@
# The Booth — roadmap
Design: [`docs/design/information-architecture.md`](docs/design/information-architecture.md).
Current version: `0.6.1` (**U1 through U7 landed — every v1 capability is in**;
extracted from eshpfi 2026-09-21). **The 1.0 cut is now a decision, not a
dependency**, and it is the operator's: a major bump needs his approval.
Current version: `1.0.0b1` (**U1 through U7 landed — every v1 capability is
in**; extracted from eshpfi 2026-09-21). **The v1 target is MET and staged as a
beta** (operator, 2026-09-22): feature-complete, external testing, no new
features — the remaining work is bugs. `1.0.0` final is cut when the beta
survives; per the canonical policy an rc would be cut from the same commit,
but a beta may still take fixes.
## v1 target
+41 -2
View File
@@ -1,3 +1,42 @@
"""The Booth — ephemeral media drop board. See booth.app for the server."""
"""The Booth — ephemeral media drop board. See booth.app for the server.
__version__ = "0.1.0"
⚠ THIS FILE IS EFFECTIVELY STDLIB-ONLY and nothing used to say so. `scripts/booth`
imports `booth.links` / `booth.marks` / `booth.manifest` under the SYSTEM python3
with no venv, and importing any of them executes this module first — so a single
third-party import here breaks `booth ask` on every fleet host exactly as one in
those three would. `test_stdlib_only` now covers `__init__` for that reason.
"""
import tomllib
from pathlib import Path
_PYPROJECT = Path(__file__).resolve().parent.parent / "pyproject.toml"
def _declared_version() -> str:
"""The version of the code actually running, read from `pyproject.toml`.
⚠ NOT `importlib.metadata`, and the reason is this repo's own shape: there
is no build step and no install step — `booth.service` runs uvicorn with
WorkingDirectory set to the repo, so the running code IS this tree.
Installed metadata describes a DIFFERENT artifact and was found saying
`0.3.0` (a vestigial dist-info, three releases stale, with no package
directory behind it) while the tree was at `1.0.0b1`. A confidently wrong
number that varies by environment is worse than the hardcoded `0.1.0` this
replaced, which at least failed the same way everywhere.
Falls back to installed metadata for the case this repo does not have but a
consumer might: packaged as a wheel, where pyproject does not ship.
"""
try:
return tomllib.loads(_PYPROJECT.read_text())["project"]["version"]
except (OSError, KeyError, tomllib.TOMLDecodeError):
try:
from importlib.metadata import version
return version("booth")
except Exception:
return "0.0.0+unknown"
__version__ = _declared_version()
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "booth"
version = "0.6.1"
version = "1.0.0b1"
description = "The Booth — a dead-simple standing web server that scans a data dir of drop-folders and renders each as an ephemeral media 'booth' (image/webm/audio auto-gallery, or a folder's own index.html verbatim). Also accepts browser/curl uploads for pickup under a human-readable id. 24h TTL, then the folder is wiped. Fleet tool for CC sessions to surface A/B and smoke results to the operator."
requires-python = ">=3.11"
dependencies = [
+31 -1
View File
@@ -7,6 +7,8 @@ See docs/contracts/u2_marks.contract.md.
"""
import ast
import json
import re
import tomllib
import pathlib
import sys
@@ -276,7 +278,7 @@ def test_as_dict_round_trips_through_json(tmp_path):
# ---- the stdlib-only invariant (INV-5) --------------------------------------
@pytest.mark.parametrize("module", ["marks", "asks", "links", "manifest", "benches"])
@pytest.mark.parametrize("module", ["marks", "asks", "links", "manifest", "benches", "__init__"])
def test_stdlib_only(module):
"""INV-5. scripts/booth imports these under the system python3 with NO venv,
through a `python3 -c` heredoc that no AST extractor can see — so nothing
@@ -1428,3 +1430,31 @@ def test_a_healthy_multi_answer_still_hydrates(tmp_path):
by = {m.id: m for m in marks_for(tmp_path)}
assert by["multi"].error is None, by["multi"].error
assert by["single"].error is None, by["single"].error
def test_the_package_version_carries_no_literal_of_its_own():
"""`booth.__version__` said `0.1.0` through six releases while pyproject
said `0.6.1` — a second copy of one fact, drifting silently, found only
while cutting 1.0.
THE ASSERTION IS THE ABSENCE OF A LITERAL, not agreement with pyproject:
`__version__` is now READ from pyproject, so comparing the two would be
circular and would prove only that the read works. The defeating change is
hardcoding a number back into this module, and that is what this catches.
"""
src = (pathlib.Path(__file__).parent.parent / "booth" / "__init__.py").read_text()
literals = re.findall(r'__version__\s*=\s*["\']([^"\']+)["\']', src)
assert not literals, f"booth/__init__.py hardcodes a version again: {literals}"
def test_the_package_version_is_the_one_the_tree_declares():
"""And it resolves, from the tree, to what pyproject says — NOT to whatever
a stale dist-info in some venv happens to record. Found saying `0.3.0` from
installed metadata while the tree was at `1.0.0b1`."""
import booth
declared = tomllib.loads(
(pathlib.Path(__file__).parent.parent / "pyproject.toml").read_text()
)["project"]["version"]
assert booth.__version__ == declared
assert booth.__version__ != "0.0.0+unknown", "the pyproject read fell through"