Signed inv/rcp codecs keyed by identity, payments table with unverified
incoming receipts, optional JSON-RPC sidecar (loopback/.onion HTTP only),
and TUI /pay /tip. OnionWire still holds no spend keys.
prf frames are ed25519-signed, friend-visible only (unknown pubkey is ignored).
/profile edits self; F5 and /who show the selected friend's last profile.
Run 309 reported success but uploaded 0 bytes for both aarch64 assets
(a 0.85s 'upload' of an 18MB file). The Pack step had just listed
18258736 bytes and sha256sum -c'd OK, so the failure is in the handoff,
not the build.
- publish-release.sh now fails loudly on a 0-byte asset instead of
publishing a release that silently breaks every download
- the workflow logs pwd, GITHUB_WORKSPACE, ls -l dist/ and the byte count
of each dist file immediately before publishing
Ruled out: the api_curl retry wrapper. Reproduced from inside a
node:20-bullseye container (curl 7.74, same as CI) — wrapper and plain
curl both uploaded 994 bytes correctly through Cloudflare.
The dispatched v0.1.1 build succeeded a third time (2m06s, valid ARM ELF)
and then died at the first API call inside the publish step with curl exit
92 (HTTP/2 stream error) — job containers reach Forgejo through Cloudflare,
where that is intermittent.
- all API calls go through api_curl: --http1.1 --retry 5
--retry-all-errors --retry-delay 3 --connect-timeout 20 --max-time 300
- HTTP/1.1 is the documented workaround for this instance's HTTP/2 resets
Job containers cannot reach http://forgejo:3000 (isolated GITEA-ACTIONS
network, name unresolvable, container IP unroutable — measured), so the
public hostname plus retries is the available fix.
Verified locally: create + idempotent re-run against a throwaway tag, both
clean; test release and tag deleted.
The dispatched build of v0.1.1 kept failing at publish with
'scripts/publish-release.sh: No such file or directory' — the workflow is
read from the dispatch ref (main) but the workspace was the v0.1.1 tag,
whose tree predates scripts/ and .forgejo/.
- second checkout of the workflow's own ref into .ci-tools; publish runs
.ci-tools/scripts/publish-release.sh (and .ci-tools/scripts/release-body.md)
- exclude ./.ci-tools from the build context tar
- target_commitish is now opt-in in publish-release.sh and only set for a
push event, so a re-publish can never move an existing tag
Verified locally end-to-end against a throwaway tag: create, idempotent
re-run (stale assets deleted + replaced), public download, sha256sum -c,
--version. Test release and tag deleted afterwards.
Two separate breakages from the first green-ish CI run:
1. tests/hs.rs asserted on a constant, which clippy rejects under
-D warnings (clippy::assertions_on_constants) because the compiler
folds the assert away. Compare through a runtime binding instead.
2. The release workflow built the aarch64 binary fine (13m02s, verified
ARM ELF) but the publish step died with:
/var/run/act/workflow/3: line 6: scripts/publish-release.sh: No such file or directory
run: steps execute with act's cwd, not the repo root, so relative
paths miss. Pin every run step with cd "${GITHUB_WORKSPACE}" (the
pattern the osint-dashboard workflow already relies on).
Verified locally before pushing: cargo test 41 passed, cargo clippy
--all-targets -- -D warnings clean.
rust:1.91-bookworm ships without clippy, so the clippy step died with
'cargo-clippy is not installed for the toolchain' after all 39 tests
passed. Also pushes the watcher fix (1=success 2=failure in Forgejo job
statuses, not action_run's numbering).
1=success 2=failure 3=cancelled 4=skipped 5=waiting 6=running 7=blocked,
terminal is 1..4. The first cut treated 2 as success and reported a failed
job as green.
The rust:1.87-bookworm job image failed every builder step with
'tor-*@0.46.0 requires rustc 1.91 ... either upgrade rustc or select
compatible dependency versions'. Cargo.toml declared rust-version 1.87,
which was simply wrong: cargo 1.87 could not even resolve the lockfile.
- rust-version 1.87 -> 1.91 (README requirement text too)
- RUST_IMAGE rust:1.87-bookworm -> rust:1.91-bookworm in ci and release
The GitHub workflows could never run on this instance: jobs asked for
ubuntu-24.04 runners (the Pi runner only registers the 'docker' label, so
every job sat in waiting), and release.yml published to github.com, which
is not a remote of this repo.
- .forgejo/workflows/ci.yml — cargo test + clippy on the 'docker' label,
Rust work in a rust:1.87-bookworm sibling container (aarch64 native)
- .forgejo/workflows/release.yml — on v*.*.* tags, build aarch64, strip,
sha256, publish to the Forgejo release; workflow_dispatch takes a tag
to re-publish
- scripts/publish-release.sh — idempotent create-or-update release +
asset upload via the Forgejo API (replaces same-named assets)
- scripts/build-release-local.sh — x86_64 path (no x86_64 runner exists)
- scripts/release-body.md — release notes template (@TAG@ substituted)
- README: install URLs -> Forgejo, accurate maintainer release procedure
- remove .github/workflows/*
- Hand-written wordmark banner (<=80 cols, auto-collapses to a compact
mark below banner width) plus onion glyph and themed screen headings
- Color-palette consts, stateful pane titles, highlighted selection row
(accent + bg), context-sensitive footer that always keeps '? help'
- Pane focus model (roster/chat/composer) with Tab/Shift-Tab, 1/2/3,
j/k + arrows, g/G, and a '?' help overlay; Esc closes any overlay
- New tests/tui_chrome.rs: banner widths, help overlay bindings, real
footer helper at 80 and 120 cols, 80x24 draw smoke test
- README keybinding table updated to match
Locked helper strings (fingerprint_mismatch_banner, rotate_screen_text,
wipe_screen_text, parse_slash) unchanged; UI-only (src/tui.rs).
Add a README install path for CI-built Linux binaries (curl, checksum,
PATH) plus source builds. CI runs tests/clippy on main; tags v*.*.*
publish stripped x86_64 and aarch64 artifacts. --version/--help so a
download can be checked without booting Tor.
/wipe overwrites the message log and VACUUMs; identity and friends stay.
/wipe-all deletes the data dir after confirm so the next open is a new person.
Neither runs without a typed confirm screen.