detached e4b5a97

fix(startup): record first-presentation provenance

commit
e4b5a976154ba4286272cc67f72babeae8452b03
author
brice · · 2026-07-14 08:47 UTC
committer
brice · · 2026-07-14 09:35 UTC
parent
04b52b5
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +18 -3
M internal/logging/first_presentation_collector_test.go +7 -0
@@ -52,6 +52,13 @@ func TestFirstPresentationCollectorSanitizesMachineLocalValues(t *testing.T) {
5252 for _, forbidden := range []string{"/home/", temp, "alice", "machine_path", `"time"`} {
5353 require.NotContainsf(t, artifacts.String(), forbidden, "committed artifact leaked %q", forbidden)
5454 }
55+ for _, required := range []string{
56+ `"measured_source_revision"`,
57+ `"tag": "v0.8.4"`,
58+ `"revision": "f217ece342dea3ef2a3f98671fcd16a39ad0037d"`,
59+ } {
60+ require.Contains(t, artifacts.String(), required)
61+ }
5562 }
5663
5764 func TestFirstPresentationCollectorRejectsInconsistentTiming(t *testing.T) {
@@ -52,6 +52,13 @@ func TestFirstPresentationCollectorSanitizesMachineLocalValues(t *testing.T) {
52 for _, forbidden := range []string{"/home/", temp, "alice", "machine_path", `"time"`} {52 for _, forbidden := range []string{"/home/", temp, "alice", "machine_path", `"time"`} {
53 require.NotContainsf(t, artifacts.String(), forbidden, "committed artifact leaked %q", forbidden)53 require.NotContainsf(t, artifacts.String(), forbidden, "committed artifact leaked %q", forbidden)
54 }54 }
55+ for _, required := range []string{
56+ `"measured_source_revision"`,
57+ `"tag": "v0.8.4"`,
58+ `"revision": "f217ece342dea3ef2a3f98671fcd16a39ad0037d"`,
59+ } {
60+ require.Contains(t, artifacts.String(), required)
61+ }
55 }62 }
56 63
57 func TestFirstPresentationCollectorRejectsInconsistentTiming(t *testing.T) {64 func TestFirstPresentationCollectorRejectsInconsistentTiming(t *testing.T) {
M scripts/collect_first_presentation.sh +11 -3
@@ -9,10 +9,17 @@ readonly timeout_seconds="${DUMBER_FIRST_PRESENTATION_TIMEOUT_SECONDS:-45}"
99 readonly runtime="${DUMBER_CEF_DIR:-$HOME/.local/share/cef-147-runtime}"
1010 readonly binary="${DUMBER_FIRST_PRESENTATION_BIN:-$PWD/dist/dumber}"
1111 readonly output="${DUMBER_FIRST_PRESENTATION_OUTPUT:-$PWD/phase1/first-presentation}"
12+readonly upstream_module="github.com/bnema/purego-cef2gtk"
13+readonly upstream_tag="v0.8.4"
14+readonly upstream_revision="f217ece342dea3ef2a3f98671fcd16a39ad0037d"
1215
1316 [[ -x "$binary" ]] || { echo "first-presentation: executable not found: $binary" >&2; exit 2; }
1417 [[ -d "$runtime" ]] || { echo "first-presentation: CEF runtime not found: $runtime" >&2; exit 2; }
1518 [[ -n "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ]] || { echo "first-presentation: a current Wayland/X11 display is required" >&2; exit 2; }
19+[[ "$(go list -m -f '{{.Version}}' "$upstream_module")" == "$upstream_tag" ]] || {
20+ echo "first-presentation: expected $upstream_module@$upstream_tag" >&2
21+ exit 2
22+}
1623
1724 rm -rf "$output"
1825 mkdir -p "$output"
@@ -20,9 +27,9 @@ mkdir -p "$output"
2027 # outside the committed artifact directory and always remove them.
2128 work_root="$(mktemp -d "${TMPDIR:-/tmp}/dumber-first-presentation.XXXXXX")"
2229 trap 'rm -rf "$work_root"' EXIT
23-python3 - "$output/metadata.json" "$binary" "$timeout_seconds" <<'PY'
30+python3 - "$output/metadata.json" "$binary" "$timeout_seconds" "$upstream_module" "$upstream_tag" "$upstream_revision" <<'PY'
2431 import hashlib, json, os, subprocess, sys
25-path, binary, timeout = sys.argv[1:]
32+path, binary, timeout, upstream_module, upstream_tag, upstream_revision = sys.argv[1:]
2633 with open(binary, "rb") as candidate:
2734 binary_sha256 = hashlib.file_digest(candidate, "sha256").hexdigest()
2835 json.dump({
@@ -30,7 +37,8 @@ json.dump({
3037 "runtime": {"label": "cef", "version": os.environ.get("DUMBER_CEF_RUNTIME_VERSION", "147")},
3138 "binary": {"label": "dumber", "sha256": binary_sha256},
3239 "timeout_seconds": int(timeout),
33- "git_revision": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),
40+ "measured_source_revision": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),
41+ "upstream": {"module": upstream_module, "tag": upstream_tag, "revision": upstream_revision},
3442 "fixed_environment": {"DUMBER_RENDER_STACK": "vulkan-dmabuf", "PUREGO_CEF2GTK_BACKEND": "gdk-dmabuf", "GSK_RENDERER": "vulkan"}
3543 }, open(path, "w"), indent=2, sort_keys=True)
3644 PY
@@ -9,10 +9,17 @@ readonly timeout_seconds="${DUMBER_FIRST_PRESENTATION_TIMEOUT_SECONDS:-45}"
9 readonly runtime="${DUMBER_CEF_DIR:-$HOME/.local/share/cef-147-runtime}"9 readonly runtime="${DUMBER_CEF_DIR:-$HOME/.local/share/cef-147-runtime}"
10 readonly binary="${DUMBER_FIRST_PRESENTATION_BIN:-$PWD/dist/dumber}"10 readonly binary="${DUMBER_FIRST_PRESENTATION_BIN:-$PWD/dist/dumber}"
11 readonly output="${DUMBER_FIRST_PRESENTATION_OUTPUT:-$PWD/phase1/first-presentation}"11 readonly output="${DUMBER_FIRST_PRESENTATION_OUTPUT:-$PWD/phase1/first-presentation}"
12+readonly upstream_module="github.com/bnema/purego-cef2gtk"
13+readonly upstream_tag="v0.8.4"
14+readonly upstream_revision="f217ece342dea3ef2a3f98671fcd16a39ad0037d"
12 15
13 [[ -x "$binary" ]] || { echo "first-presentation: executable not found: $binary" >&2; exit 2; }16 [[ -x "$binary" ]] || { echo "first-presentation: executable not found: $binary" >&2; exit 2; }
14 [[ -d "$runtime" ]] || { echo "first-presentation: CEF runtime not found: $runtime" >&2; exit 2; }17 [[ -d "$runtime" ]] || { echo "first-presentation: CEF runtime not found: $runtime" >&2; exit 2; }
15 [[ -n "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ]] || { echo "first-presentation: a current Wayland/X11 display is required" >&2; exit 2; }18 [[ -n "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ]] || { echo "first-presentation: a current Wayland/X11 display is required" >&2; exit 2; }
19+[[ "$(go list -m -f '{{.Version}}' "$upstream_module")" == "$upstream_tag" ]] || {
20+ echo "first-presentation: expected $upstream_module@$upstream_tag" >&2
21+ exit 2
22+}
16 23
17 rm -rf "$output"24 rm -rf "$output"
18 mkdir -p "$output"25 mkdir -p "$output"
@@ -20,9 +27,9 @@ mkdir -p "$output"
20 # outside the committed artifact directory and always remove them.27 # outside the committed artifact directory and always remove them.
21 work_root="$(mktemp -d "${TMPDIR:-/tmp}/dumber-first-presentation.XXXXXX")"28 work_root="$(mktemp -d "${TMPDIR:-/tmp}/dumber-first-presentation.XXXXXX")"
22 trap 'rm -rf "$work_root"' EXIT29 trap 'rm -rf "$work_root"' EXIT
23-python3 - "$output/metadata.json" "$binary" "$timeout_seconds" <<'PY'30+python3 - "$output/metadata.json" "$binary" "$timeout_seconds" "$upstream_module" "$upstream_tag" "$upstream_revision" <<'PY'
24 import hashlib, json, os, subprocess, sys31 import hashlib, json, os, subprocess, sys
25-path, binary, timeout = sys.argv[1:]32+path, binary, timeout, upstream_module, upstream_tag, upstream_revision = sys.argv[1:]
26 with open(binary, "rb") as candidate:33 with open(binary, "rb") as candidate:
27 binary_sha256 = hashlib.file_digest(candidate, "sha256").hexdigest()34 binary_sha256 = hashlib.file_digest(candidate, "sha256").hexdigest()
28 json.dump({35 json.dump({
@@ -30,7 +37,8 @@ json.dump({
30 "runtime": {"label": "cef", "version": os.environ.get("DUMBER_CEF_RUNTIME_VERSION", "147")},37 "runtime": {"label": "cef", "version": os.environ.get("DUMBER_CEF_RUNTIME_VERSION", "147")},
31 "binary": {"label": "dumber", "sha256": binary_sha256},38 "binary": {"label": "dumber", "sha256": binary_sha256},
32 "timeout_seconds": int(timeout),39 "timeout_seconds": int(timeout),
33- "git_revision": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),40+ "measured_source_revision": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),
41+ "upstream": {"module": upstream_module, "tag": upstream_tag, "revision": upstream_revision},
34 "fixed_environment": {"DUMBER_RENDER_STACK": "vulkan-dmabuf", "PUREGO_CEF2GTK_BACKEND": "gdk-dmabuf", "GSK_RENDERER": "vulkan"}42 "fixed_environment": {"DUMBER_RENDER_STACK": "vulkan-dmabuf", "PUREGO_CEF2GTK_BACKEND": "gdk-dmabuf", "GSK_RENDERER": "vulkan"}
35 }, open(path, "w"), indent=2, sort_keys=True)43 }, open(path, "w"), indent=2, sort_keys=True)
36 PY44 PY

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close