byreis v0.4 release notes¶
v0.4 is the reviewer-loop release. It closes the two halves of the admin
review flow that v0.3 only half-showed: a real, browsable submission-PR queue in
the TUI and a first-class reject verb (CLI and in-TUI). Alongside the loop, the
successful-merge audit record now lands durably in the registry's signed file
instead of only on the merging admin's local machine.
The asymmetric-access guarantee is unchanged. Contributors still encrypt and submit write-only; they cannot decrypt, and no v0.4 surface gives a non-key-holder a route to a plaintext value. Access level remains derived from cryptographic reality, never from a flag, an environment variable, or a config file.
What's new¶
A browsable submission-PR queue in byreis review¶
byreis review, run on an interactive terminal as an admin, now opens a list of
pending submission PRs (the byreis/add-*, byreis/replace-*, and
byreis/bulk-* branches) with PR number, key/action, author, and age. Select a row
and press Enter to open the existing no-plaintext detail/approve flow — no manual PR
reference, no dropping to the CLI or the web UI.
The list view never decrypts. It calls only the bounded read port; the only path that decrypts is the explicit approve-detail flow you opt into per item, which is the same already-audited v0.3 decryption path. The list itself never constructs key material and never binds a plaintext value.
The queue is bounded: at most 5 pages / 200 results, with a visible truncation signal, a loading indicator on a slow fetch, and context-cancellation honored.
byreis admin request reject¶
A single verb closes a request or submission PR with a structured reason, from
within byreis rather than out-of-band gh pr close:
The PR is closed, the reason is posted as a PR comment (so the contributor gets
structured feedback), and a reject event is recorded in the audit log. --json
emits {pr, status, reason, url}. The verb is ADMIN/SUPER only; a contributor
invocation is denied at the permission matrix before any network contact.
reject is PR-close-only. It never loads a private key, never decrypts, never
advances a counter, and never writes to admins.yaml, projects/*, policy.yaml,
or the counter store. It validates the PR type before acting: pointed at a PR whose
type does not match (its source repo and branch prefix must agree), it refuses and
closes nothing. An already-merged PR is refused with a typed error (a merged
submission is never silently closed); an already-closed PR is an idempotent no-op
with no duplicate comment.
The reason is sanitized for terminal safety (control bytes and Unicode bidirectional/format overrides — the Trojan-source class — are stripped) before it reaches the PR comment or the audit log, and it is length-capped. The free-text reason is never stored in the audit event — only its byte length is recorded — so audit search and diff cannot leak it.
In-TUI reject¶
The submission detail screen in byreis review gains a reject action. It is a thin
caller: it collects a reason, shows a confirm step, and calls the same reject
use-case as the CLI verb. It never constructs key material and never reads a
plaintext value; aborting the confirm makes no call and returns to the detail view.
Durable merge audit in the signed registry file¶
A successful byreis merge now appends a signed merge event to the registry's
audit/<project>.jsonl, fetchable read-only, so post-incident review no longer
depends on a specific admin's local machine. The merge audit record rides the same
signed registry commit as the counter advance: it is written if and only if the
counter CommitBump lands. There is never an orphan audit entry on a non-advanced
counter, and never an orphan unsigned line. The audit counter is strictly monotonic
and subordinate to the counter advance; concurrent merges are serialized by a
compare-and-swap push so exactly one wins. The audit file auto-initializes on the
first merge.
The merge-audit posture is fail-closed: a signed registry commit cannot be retried offline, and an unattended audit gap is worse than a failed command. If the registry write cannot complete (offline at merge), the command fails with a clear retry hint and a result describing what landed, rather than dropping the record.
Scope of merge-audit tamper-evidence (read this)¶
The merge-audit channel is protected by the HEAD commit signature verified against the pinned trust anchor, plus the monotonic counter and the compare-and-swap (CAS) push. Together these detect an unsigned or forged registry HEAD and provide anti-rollback.
It is not per-line tamper-detection. byreis does not today re-verify the
per-line integrity of audit/<project>.jsonl on read: the per-entry hash is
write-side provenance only, with no read path recomputing it. A key-less repository
writer who edits, reorders, or deletes JSONL lines underneath a validly-signed HEAD
is therefore not detected by byreis. This is a pre-existing, system-wide
property of the audit channel (it has applied to the rotation audit since v0.2),
not something specific to merge-audit. Per-line read-side integrity binding across
the whole audit system (rotation and merge) is a tracked follow-up for a release
after v0.4.
Behavior and configuration change: the two-variable project contract¶
v0.4 splits the project identity into two variables with distinct meanings:
BYREIS_PROJECTis now the slash-free logical project id (for examplemyapp). It is used for registry paths — admin set, policy, counters, and theaudit/<project>.jsonlfile.BYREIS_PROJECT_REPOis theowner/reposlug of the project secrets repository (for examplemyorg/myapp). The GitHub git provider derives the repo location from it.
byreis doctor warns if BYREIS_PROJECT contains a slash, because that almost
always means an owner/repo value was left in the wrong variable.
Migration note¶
If you previously set BYREIS_PROJECT=owner/repo (the v0.3.x single-variable form),
split it: put the owner/repo slug in BYREIS_PROJECT_REPO and put the
slash-free logical id in BYREIS_PROJECT. Pass --project to override per
invocation. A BYREIS_PROJECT that still contains a slash is flagged by
byreis doctor.
Positioning and honesty disclosures¶
These statements bound what byreis does, deliberately:
- The review TUI opens the submission-PR queue by default; press
ato toggle to access-request triage. The submission queue is the new default screen; the v0.3 access-request-triage path is preserved, not removed — it is one keystroke away. rejectis PR-close-only and never touches key material. It closes a PR and posts a comment; it never loads a key, decrypts, advances a counter, or writes any trust state.- Merge-audit is HEAD-signature, monotonic-counter, and CAS protected — not per-line tamper-detection. A key-less repo writer editing JSONL lines under a validly-signed HEAD is not detected today; per-line read-side integrity is a tracked follow-up.
- byreis is GitHub-only. There is no GitLab provider and no other forge backend.
- There is no
export --sopsand no SOPS-symmetric interoperation. The format is native-ageModel B; a key-less contributor can encrypt to admins but cannot decrypt, and there is no shared data key to export.
Upgrading¶
Drop-in replacement for v0.3.1 with one configuration change: split the project
identity into BYREIS_PROJECT (slash-free logical id) and BYREIS_PROJECT_REPO
(owner/repo slug) per the migration note above. No secrets-format change. Existing
encrypted files, registries, and signed commits are unaffected.