authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-02-06 00:10:16-08:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-02-06 21:28:58-08:00
log9b97490fddead9b441586998e85f08da0bac238f
tree56f4da9ea514440c85f6a81045c9b5b982cf20f5
parent569edfc3aff1680ad8c61865a798657543717ef1
signature Signed by SSH key SHA256:xbd+BjjhyBfwk7GVoURf9Yx0gzDerHbvYv7SddNWmAs

feat: catch up the clover activity log


1 files changed, 203 insertions(+), 0 deletions(-)

src/pages/log.mdx+203
......@@ -12,9 +12,212 @@ export const meta = { title: 'clover\'s log' };
1212[this site]: https://paperclover.net/
1313[todo tracker]: https://git.paperclover.net/clo/todo-tracker
1414[ts lie detector]: https://git.paperclover.net/clo/ts-lie-detector
15[evil inc]: https://evil.inc/
16[history of japan reanimated]: /history-of-japan-reanimated
17[react mutation]: /history-of-japan-reanimated
1518
1619# clover's log
1720
21these are like mini blog posts, but more in generally just what the heck i'm up to.
22
23## 2026-02-06
24
25spent yesterday and today cathing up with this page and preparing to get
26writing heavy on the blog. i also fixed a bug on the video player where it
27wouldnt work on latest chrome on non-av1 accelerated hardware.
28
29there were two bugs:
30
31- chrome without av1 and version >=142 would try and play the hls stream
32 natively. they made `video.canPlayType("application/x-mpegURL")` return
33 "maybe", which is total propaganda because chrome does not actually support
34 this type of stream. they support some insane subset that isn't real world
35 use cases.
36- hls polyfill was never being used because of a bundling mistake, so those
37 users would get the unoptimized original file.
38
39since i was testing windows 7, decided to also fix some IE9 bugs. the page
40works besides the video player and the fonts, which is all things i believe i
41could easily fix, so i opened new issues for those tasks.
42
43## 2026-02-04
44
45tags: [this site]
46
47i did a ton of random stuff to [this site], including the RSS feed and random
48bug fixes on the domain. trying to reduce the issue count on my forgejo.
49
50## 2026-02-03
51
52tags: [history of japan reanimated]
53
54immediately after the youtube premiere, i worked on my webpage of it. the live
55credits was a really fun touch that really completes things. i'm very happy
56with the final result.
57
58i also had to do a ton of work fixing the video player to properly show
59thumbnails on the video player. the biggest one was adding even more hell to
60the dash-av1 player. a issue that `dash.js` has is providing the first frame of
61media before the user presses "play." this doesn't happen with the hls or
62native players. so my workaround... delay attachment of the view.
63
64```
65player.initialize(null, dashFile, false);
66player.updateSettings({
67 streaming: { cacheInitSegments: true },
68});
69player.preload();
70
71video.addEventListener("play", function play() {
72 video.removeEventListener("play", play);
73
74 enableSafariAirplay(); // <-- another important hack
75 player.attachView(video);
76 onCloverVideoInit?.(id, video);
77});
78video.controls = true;
79```
80
81but on chrome you get cooked because a video without a source is not playable.
82so a second hack used to attach a fake source.
83
84```
85const duration = new Promise<number>((resolve) => {
86 player.on(dashjs.MediaPlayer.events.MANIFEST_LOADED, (e) => {
87 const duration = e.data.mediaPresentationDuration;
88 resolve(duration); // seconds
89 });
90});
91mediaSource = new MediaSource();
92mediaSource.addEventListener("sourceopen", () => {
93 duration.then((duration) => {
94 mediaSource = mediaSource!; // typescript assertion
95 mediaSource.duration = duration;
96 const sb = mediaSource.addSourceBuffer('video/webm; codecs="vp8"');
97 const oneFrame = Uint8Array.from(
98 atob("GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEAAAAAAAITEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHWTbuMU6uEElTDZ1OsggEjTbuMU6uEHFO7a1OsggH97AEAAAAAAABZ" + "A".repeat(119) + "VSalmsCrXsYMPQkBNgIxMYXZmNjIuMy4xMDBXQYxMYXZmNjIuMy4xMDBEiYhAXgAAAAAAABZUrmvIrgEAAAAAAAA/14EBc8WIDV7YG1KxA/CcgQAitZyDdW5kiIEAhoVWX1ZQOIOBASPjg4QCYloA4JCwgQG6gQGagQJVsIRVuYEBElTDZ/tzc59jwIBnyJlFo4dFTkNPREVSRIeMTGF2ZjYyLjMuMTAwc3PWY8CLY8WIDV7YG1KxA/BnyKFFo4dFTkNPREVSRIeUTGF2YzYyLjExLjEwMCBsaWJ2cHhnyKFFo4hEVVJBVElPTkSHkzAwOjAwOjAwLjEyMDAwMDAwMAAfQ7Z11eeBAKOigQAAgBACAJ0BKgEAAQALxwiFhYiFhIg/ggAMDWAA/ua1AKOVgQAoALEBAC8R/AAYABhYL/QAJAAAo5WBAFAAsQEALxH8ABgAGFgv9AAkAAAcU7trkbuPs4EAt4r3gQHxggGj8IED"),
99 (x) => x.charCodeAt(0),
100 );
101 sb.appendBuffer(oneFrame);
102 });
103});
104objectUrl = URL.createObjectURL(mediaSource);
105
106mainSource = document.createElement("source");
107mainSource.src = objectUrl;
108video.appendChild(mainSource);
109```
110
111the payload within contains a single webm vp8 frame, one pixel by one pixel.
112this is enough to get chrome to shut up. now the experience is nearly perfect,
113with browser support all the way to the ancient firefox version on my old
114laptop, to modern Apple Silicon Macs.
115
116## 2026-01-31
117
118tags: [history of japan reanimated]
119
120main section of animation for the project was already done, but i wanted to
121make some needed adjustments to my scene. so i had been doing those for a few
122days, as well as animating an extra 25 seconds for the outro section. it was
123very fun doing that process, since i actually grabbed an old macbook i had in
124storage to take the textedit screenshot. more details on this entire process
125will be in the project page.
126
127## 2026-01-30
128
129tags: [react mutation]
130
131at work, one of my coworkers was complaining about my helper functions for
132TanStack Query's mutation system. the conclusion was that the mutation system
133we were building on was flawed and not enjoyable to use. so i spent a few days
134making an alternative library. it's on the JSR: [@clo/react-mutation](https://jsr.io/@clo/react-mutation).
135
136this project was really fun because of how much the API surface changed as i
137started staging the library into our actual code. the experience has shaped how
138i want to go about my upcoming blog post for the better.
139
140## 2026-01-25
141
142tags: [ts lie detector], [todo tracker]
143
144added a trivial binary to the lie detector, `tsld-node`, which is like `ts-node` or `tsx` but it runs with the lie detector.
145
146for todo tracker, it's been vibe coded to a point where the sitegen repo gets
147through all commits, but there are still some issues with missing TODOs. i haven't really had time to prioritize this, even with an ai agent writing most of it, since even then i have to review the progress of it, so it's just not worth my time until other projects pull through.
148
149## 2026-01-24
150
151tags: [git], [home infra]
152
153i moved forgejo off of sqlite and onto postgres. the only motiviation behind this was to easily backdate the repositories i had imported: [name paint bot] and a scripting language compiler i wrote. i was more comfortable doing this on a real database server than just editing the file.
154
155the migration took a bit for me to figure out, but last year someone named Sven [did the same thing](https://sven-seeberg.de/wp/?p=1213), and found this `pgloader` command with the critical `data only` clause.
156
157```
158echo "LOAD DATABASE
159FROM sqlite:///root/forgejo.db
160INTO postgresql://forgejo:$POSTGRES_PASSWORD_FORGEJO@postgres/forgejo
161WITH data only, reset sequences, prefetch rows = 10000
162SET work_mem TO '16MB', maintenance_work_mem TO '512MB';" > ./pgloader-command
163
164pgloader ./pgloader-command
165```
166
167## 2026-01-18
168
169tags: [git], [home infra]
170
171i finally setup system integrated ssh push, but with a twist.
172
173the first problem is having two ssh servers on the same machine, one for the
174host, and another for Forgejo. this means that one of them had to live on
175another port, so i chose to move the host. but it kind of just sucks to use
176this. the proper solution is to use a custom config to direct the `git` user to
177the right place.
178
179what made this harder is i actually had two git instances; the second one is
180for a temporary infrastructure i'm running for [evil inc] until the
181organization gets dedicated hardware (more about this in a future post). so
182even if i routed `git` specially, it still wouldnt know which git server to go
183to.
184
185**the solution**: write a custom "router" script that generates an
186`authorized_keys` file based on which git instances actually have a key, then
187the line within the `authorized_keys` forces a special wrapper which intercepts
188the targetted git repository, routing it to the git instance with it.
189
190the sshd config looks like
191
192```
193Match User git
194 AuthorizedKeysCommand /bin/python /mnt/storage1/apps/home-infra/config/forgejo/ssh/keys.py %u %t %k
195 AuthorizedKeysCommandUser git
196```
197
198it is convenient because `AuthorizedKeysCommand` is run on every connection. it produces a file with zero or one valid keys:
199
200```
201command="/mnt/storage1/apps/home-infra/config/forgejo/ssh/route.sh --clover 1 --evil 2",no-port-forwarding,...,restrict ssh-ed25519 AAAAC3NzaC...
202```
203
204and then the route script does this shit:
205
206```
207if [ -d "/mnt/storage1/apps/forgejo/git/repositories/${repo}" ]; then
208 [ -z "$clover_id" ] && echo "ssh key is not configured for repository on git.paperclover.net" >&2 && exit 1
209 exec sudo docker exec -i -u git forgejo /usr/bin/env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" /usr/local/bin/forgejo --config=/custom/conf/app.ini serv key-"$clover_id"
210elif [ -d "/mnt/storage1/apps/evil-infra/forgejo/git/repositories/${repo}" ]; then
211 [ -z "$evil_id" ] && echo "ssh key is not configured for repository on git.evil.inc" >&2 && exit 1
212 exec sudo docker exec -i -u git evil-forgejo /usr/bin/env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" /usr/local/bin/forgejo --config=/custom/conf/app.ini serv key-"$evil_id"
213else
214 echo "repo not found" >&2
215 exit 1
216fi
217```
218
219it works beautifully. [see the whole patch for more info](https://git.paperclover.net/clo/home-infra/commit/e402d6ef71dfc310caeeb4d3579bddd9d0710594)
220
18221## 2026-01-14
19222
20223tags: [next.js blog post], [this site]